From 7dcff82cf5261d9ef1f325bc9ee6ce42be5fcd76 Mon Sep 17 00:00:00 2001 From: chrys Date: Thu, 20 Jul 2017 00:41:12 +0200 Subject: [PATCH] intial rewrite of command detection; move command execution to event --- src/fenrir/core/commandManager.py | 13 --- src/fenrir/core/eventData.py | 1 + src/fenrir/core/eventManager.py | 17 ++-- src/fenrir/core/fenrirManager.py | 116 +++++++++++++++----------- src/fenrir/core/inputManager.py | 22 ++--- src/fenrir/screenDriver/vcsaDriver.py | 4 +- 6 files changed, 93 insertions(+), 80 deletions(-) diff --git a/src/fenrir/core/commandManager.py b/src/fenrir/core/commandManager.py index 683bea94..fc238d51 100644 --- a/src/fenrir/core/commandManager.py +++ b/src/fenrir/core/commandManager.py @@ -199,7 +199,6 @@ class commandManager(): self.env['commands'][section][command].run() except Exception as e: self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR) - self.clearCommandQueued() self.env['commandInfo']['lastCommandExecutionTime'] = time.time() def getCommandDescription(self, command, section = 'commands'): @@ -208,19 +207,7 @@ class commandManager(): return self.env['commands'][section][command].getDescription() except Exception as e: self.env['runtime']['debug'].writeDebugOut('commandManager.getCommandDescription:' + str(e),debug.debugLevel.ERROR) - self.clearCommandQueued() self.env['commandInfo']['lastCommandExecutionTime'] = time.time() - - def isCommandQueued(self): - return self.env['commandInfo']['currCommand'] != '' - - def clearCommandQueued(self): - self.env['commandInfo']['currCommand'] = '' - - def queueCommand(self, command): - if command == '': - return - self.env['commandInfo']['currCommand'] = command def commandExists(self, command, section = 'commands'): return( command in self.env['commands'][section]) diff --git a/src/fenrir/core/eventData.py b/src/fenrir/core/eventData.py index c9592c98..be5db45a 100755 --- a/src/fenrir/core/eventData.py +++ b/src/fenrir/core/eventData.py @@ -17,6 +17,7 @@ class fenrirEventType(Enum): BrailleFlush = 6 ScreenChanged = 7 HeartBeat = 8 # for time based scheduling + ExecuteCommand = 9 def __int__(self): return self.value def __str__(self): diff --git a/src/fenrir/core/eventManager.py b/src/fenrir/core/eventManager.py index d6c06475..945c6a16 100644 --- a/src/fenrir/core/eventManager.py +++ b/src/fenrir/core/eventManager.py @@ -47,15 +47,17 @@ class eventManager(): self.env['runtime']['debug'].writeDebugOut('eventManager:eventDispatcher:start: event:' + str(event['Type']) + ' QueueSize:' + str( self._eventQueue.qsize()),debug.debugLevel.INFO) if not event: return + if not event['Type']: + return if event['Type'] == fenrirEventType.Ignore: return elif event['Type'] == fenrirEventType.StopMainLoop: - self.handleStopMainLoop() + self.handleStopMainLoop(event) return elif event['Type'] == fenrirEventType.ScreenUpdate: - self.env['runtime']['fenrirManager'].handleScreenUpdate() + self.env['runtime']['fenrirManager'].handleScreenUpdate(event) elif event['Type'] == fenrirEventType.KeyboardInput: - self.env['runtime']['fenrirManager'].handleInput() + self.env['runtime']['fenrirManager'].handleInput(event) elif event['Type'] == fenrirEventType.BrailleInput: pass elif event['Type'] == fenrirEventType.PlugInputDevice: @@ -63,18 +65,19 @@ class eventManager(): elif event['Type'] == fenrirEventType.BrailleFlush: pass elif event['Type'] == fenrirEventType.ScreenChanged: - self.env['runtime']['fenrirManager'].handleScreenChange() + self.env['runtime']['fenrirManager'].handleScreenChange(event) elif event['Type'] == fenrirEventType.HeartBeat: - self.env['runtime']['fenrirManager'].handleHeartBeat() + self.env['runtime']['fenrirManager'].handleHeartBeat(event) + elif event['Type'] == fenrirEventType.ExecuteCommand: + self.env['runtime']['fenrirManager'].handleExecuteCommand(event) def isMainEventLoopRunning(self): return self._mainLoopRunning.value == 1 def startMainEventLoop(self): self._mainLoopRunning.value = 1 while( self.isMainEventLoopRunning()): - st = time.time() self.proceedEventLoop() - def handleStopMainLoop(self): + def handleStopMainLoop(self, event): self._mainLoopRunning.value = 0 time.sleep(0.1) def stopMainEventLoop(self, Force = False): diff --git a/src/fenrir/core/fenrirManager.py b/src/fenrir/core/fenrirManager.py index 0010d8b9..8d99ff50 100644 --- a/src/fenrir/core/fenrirManager.py +++ b/src/fenrir/core/fenrirManager.py @@ -13,6 +13,7 @@ if not os.path.dirname(os.path.realpath(fenrirVersion.__file__)) in sys.path: from core import i18n from core import settingsManager from core import debug +from core.eventData import fenrirEventType import argparse class fenrirManager(): @@ -31,8 +32,9 @@ class fenrirManager(): signal.signal(signal.SIGINT, self.captureSignal) signal.signal(signal.SIGTERM, self.captureSignal) self.initialized = True - self.wasCommand = False - + self.modifierInput = False + self.singleKeyCommand = False + self.command = '' def handleArgs(self): args = None parser = argparse.ArgumentParser(description="Fenrir Help") @@ -49,31 +51,44 @@ class fenrirManager(): return self.environment['runtime']['eventManager'].startMainEventLoop() self.shutdown() - def handleInput(self): - startTime = time.time() + def handleInput(self, event): + #startTime = time.time() eventReceived = self.environment['runtime']['inputManager'].getInputEvent() if eventReceived: - self.prepareCommand() - #if not self.environment['runtime']['screenManager'].isSuspendingScreen(): - # if self.environment['runtime']['helpManager'].handleTutorialMode(): - # self.wasCommand = True - if not (self.wasCommand or self.environment['runtime']['helpManager'].isTutorialMode()) or self.environment['runtime']['screenManager'].isSuspendingScreen(): - self.environment['runtime']['inputManager'].writeEventBuffer() - if self.environment['runtime']['inputManager'].noKeyPressed(): - if self.wasCommand: - self.wasCommand = False - self.environment['runtime']['inputManager'].clearEventBuffer() - self.environment['runtime']['commandManager'].clearCommandQueued() + + if self.environment['runtime']['screenManager'].isSuspendingScreen(): + self.environment['runtime']['inputManager'].writeEventBuffer() + else: if self.environment['runtime']['helpManager'].isTutorialMode(): - self.environment['runtime']['inputManager'].clearEventBuffer() - if self.environment['input']['keyForeward'] > 0: - self.environment['input']['keyForeward'] -=1 + self.environment['runtime']['inputManager'].clearEventBuffer() + + self.detectCommand() + + if self.modifierInput: + self.environment['runtime']['inputManager'].clearEventBuffer() + if self.singleKeyCommand: + if self.environment['runtime']['inputManager'].noKeyPressed(): + self.environment['runtime']['inputManager'].clearEventBuffer() + else: + self.environment['runtime']['inputManager'].writeEventBuffer() + if self.environment['runtime']['inputManager'].noKeyPressed(): + self.modifierInput = False + self.singleKeyCommand = False + if self.environment['input']['keyForeward'] > 0: + self.environment['input']['keyForeward'] -=1 self.environment['runtime']['screenManager'].update('onInput') self.environment['runtime']['commandManager'].executeDefaultTrigger('onInput') - self.handleCommands() - print('handleInput:',time.time() - startTime) - - def handleScreenChange(self): + #print('handleInput:',time.time() - startTime) + def handleExecuteCommand(self, event): + if event['Data'] == '': + return + command = event['Data'] + if self.environment['runtime']['helpManager'].isTutorialMode(): + if self.environment['runtime']['commandManager'].commandExists( command, 'help'): + self.environment['runtime']['commandManager'].executeCommand( command, 'help') + return + self.environment['runtime']['commandManager'].executeCommand( command, 'commands') + def handleScreenChange(self, event): self.environment['runtime']['screenManager'].update('onScreenChange') ''' if self.environment['runtime']['applicationManager'].isApplicationChange(): @@ -84,8 +99,8 @@ class fenrirManager(): ''' self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged') - def handleScreenUpdate(self): - startTime = time.time() + def handleScreenUpdate(self, event): + #startTime = time.time() self.environment['runtime']['screenManager'].update('onUpdate') ''' @@ -100,39 +115,46 @@ class fenrirManager(): self.environment['runtime']['cursorManager'].isCursorHorizontalMove(): self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange') self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate') - print('handleScreenUpdate:',time.time() - startTime) + #print('handleScreenUpdate:',time.time() - startTime) - def handlePlugInputDevice(self): + def handlePlugInputDevice(self, event): self.environment['runtime']['commandManager'].executeDefaultTrigger('PlugInputDevice') - def handleHeartBeat(self): + def handleHeartBeat(self, event): self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat') #self.environment['runtime']['outputManager'].brailleText(flush=False) - def prepareCommand(self): - if self.environment['runtime']['screenManager'].isSuspendingScreen(): - self.wasCommand = False - return - if self.environment['runtime']['inputManager'].noKeyPressed(): - return + def detectCommand(self): if self.environment['input']['keyForeward'] > 0: return - shortcut = self.environment['runtime']['inputManager'].getCurrShortcut() - command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut) - #if len(self.environment['input']['prevDeepestInput']) >= len(self.environment['input']['currInput']): - self.wasCommand = command != '' or self.environment['runtime']['inputManager'].isFenrirKeyPressed() or self.environment['runtime']['inputManager'].isScriptKeyPressed() - if command == '': - return - self.environment['runtime']['commandManager'].queueCommand(command) + if self.environment['runtime']['inputManager'].isKeyPress(): + self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier() + else: + if not self.environment['runtime']['inputManager'].noKeyPressed(): + if self.singleKeyCommand: + self.singleKeyCommand = len(self.environment['input']['prevDeepestInput']) == 1 + # key is already released. we need the old one + if not( self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()): + shortcut = self.environment['runtime']['inputManager'].getCurrShortcut() + self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut) + if not self.modifierInput: + if self.environment['runtime']['inputManager'].isKeyPress(): + if self.command != '': + self.singleKeyCommand = True - def handleCommands(self): - if not self.environment['runtime']['commandManager'].isCommandQueued(): + if not (self.singleKeyCommand or self.modifierInput): return - if len(self.environment['input']['prevDeepestInput']) > len(self.environment['input']['currInput']): - return - if self.environment['runtime']['helpManager'].isTutorialMode(): - self.environment['runtime']['commandManager'].executeCommand( self.environment['commandInfo']['currCommand'], 'help') - self.environment['runtime']['commandManager'].executeCommand( self.environment['commandInfo']['currCommand'], 'commands') + + # fire event + if self.command != '': + if self.modifierInput: + self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) + self.command = '' + else: + if self.singleKeyCommand: + if self.environment['runtime']['inputManager'].noKeyPressed(): + self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) + self.command = '' def shutdownRequest(self): self.environment['runtime']['eventManager'].stopMainEventLoop() diff --git a/src/fenrir/core/inputManager.py b/src/fenrir/core/inputManager.py index fd5d3e2b..33a6bc59 100644 --- a/src/fenrir/core/inputManager.py +++ b/src/fenrir/core/inputManager.py @@ -141,13 +141,6 @@ class inputManager(): eventName = 'KEY_SCRIPT' return eventName - def isConsumeInput(self): - return self.env['runtime']['commandManager'].isCommandQueued() and \ - not self.env['input']['keyForeward'] - #and - # not (self.env['input']['keyForeward'] or \ - # self.env['runtime']['settingsManager'].getSettingAsBool(, 'keyboard', 'grabDevices')) - def clearEventBuffer(self): self.env['runtime']['inputDriver'].clearEventBuffer() @@ -155,7 +148,6 @@ class inputManager(): try: if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): self.env['runtime']['inputDriver'].writeEventBuffer() - time.sleep(0.008) self.clearEventBuffer() if len(self.env['input']['currInput']) == 1: if self.env['input']['currInput'][0] in ['KEY_UP','KEY_DOWN']: @@ -172,7 +164,8 @@ class inputManager(): def noKeyPressed(self): return self.env['input']['currInput'] == [] - + def isKeyPress(self): + return (self.env['input']['prevInput'] == []) and (self.env['input']['currInput'] != []) def getPrevDeepestInput(self): shortcut = [] shortcut.append(self.env['input']['shortcutRepeat']) @@ -185,10 +178,13 @@ class inputManager(): shortcut.append(self.env['input']['prevInput']) return str(shortcut) - def getCurrShortcut(self): + def getCurrShortcut(self, inputSequence = None): shortcut = [] shortcut.append(self.env['input']['shortcutRepeat']) - shortcut.append(self.env['input']['currInput']) + if inputSequence: + shortcut.append(inputSequence) + else: + shortcut.append(self.env['input']['currInput']) if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']): if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)): shortcut = [] @@ -198,6 +194,10 @@ class inputManager(): self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO) return str(shortcut) + def currKeyIsModifier(self): + if len(self.env['input']['prevDeepestInput']) != 1: + return False + return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT') def isFenrirKey(self, eventName): return eventName in self.env['input']['fenrirKey'] def isScriptKey(self, eventName): diff --git a/src/fenrir/screenDriver/vcsaDriver.py b/src/fenrir/screenDriver/vcsaDriver.py index c6473d1b..003c68e4 100644 --- a/src/fenrir/screenDriver/vcsaDriver.py +++ b/src/fenrir/screenDriver/vcsaDriver.py @@ -260,7 +260,7 @@ class driver(): self.env['screen']['newCursor']['x'] = int( self.env['screen']['newContentBytes'][2]) self.env['screen']['newCursor']['y'] = int( self.env['screen']['newContentBytes'][3]) # analyze content - s = time.time() + if screenEncoding.upper() == 'AUTO': self.updateCharMap(str(self.env['screen']['newTTY'])) self.env['screen']['newContentText'], \ @@ -271,7 +271,7 @@ class driver(): self.env['screen']['newContentText'] = screen_utils.removeNonprintable(self.env['screen']['newContentText']) self.env['screen']['newContentAttrib'] = self.env['screen']['newContentBytes'][5:][::2] self.env['screen']['newContentText'] = screen_utils.insertNewlines(self.env['screen']['newContentText'], self.env['screen']['columns']) - print(time.time() -s, self.env['screen']['newTTY'] ) + if self.env['screen']['newTTY'] != self.env['screen']['oldTTY']: self.env['screen']['oldContentBytes'] = b'' self.env['screen']['oldContentAttrib'] = b''