X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=kll_lib%2Fcontainers.py;h=2436c7ea930356fd8c00310fa3a938d9e96b9a5e;hb=f3451f619c96788ec8998fc111af0b4c8189d8cf;hp=a6c205ad96a6997b549fbc0e67b89a2734e009a2;hpb=e8d498a0d6a9e6ca00920383e0eaeef4262f31f0;p=kiibohd-kll.git diff --git a/kll_lib/containers.py b/kll_lib/containers.py index a6c205a..2436c7e 100644 --- a/kll_lib/containers.py +++ b/kll_lib/containers.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # KLL Compiler Containers # -# Copyright (C) 2014 by Jacob Alexander +# Copyright (C) 2014-2015 by Jacob Alexander # # This file is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -18,6 +18,8 @@ ### Imports ### +import copy + ### Decorators ### @@ -29,7 +31,9 @@ ERROR = '\033[5;1;31mERROR\033[0m:' ### Parsing ### + ## Containers + class Capabilities: # Container for capabilities dictionary and convenience functions def __init__( self ): @@ -86,6 +90,10 @@ class Macros: # Macro Storage self.macros = [ dict() ] + # Base Layout Storage + self.baseLayout = None + self.layerLayoutMarkers = [] + # Correlated Macro Data self.resultsIndex = dict() self.triggersIndex = dict() @@ -93,6 +101,7 @@ class Macros: self.triggersIndexSorted = [] self.triggerList = [] self.maxScanCode = [] + self.firstScanCode = [] # USBCode Assignment Cache self.assignmentCache = [] @@ -100,10 +109,23 @@ class Macros: def __repr__( self ): return "{0}".format( self.macros ) + def completeBaseLayout( self ): + # Copy base layout for later use when creating partial layers and add marker + self.baseLayout = copy.deepcopy( self.macros[ 0 ] ) + self.layerLayoutMarkers.append( copy.deepcopy( self.baseLayout ) ) # Not used for default layer, just simplifies coding + + def removeUnmarked( self ): + # Remove all of the unmarked mappings from the partial layer + for trigger in self.layerLayoutMarkers[ self.layer ].keys(): + del self.macros[ self.layer ][ trigger ] + def addLayer( self ): # Increment layer count, and append another macros dictionary self.layer += 1 - self.macros.append( dict() ) + self.macros.append( copy.deepcopy( self.baseLayout ) ) + + # Add a layout marker for each layer + self.layerLayoutMarkers.append( copy.deepcopy( self.baseLayout ) ) # Use for ScanCode trigger macros def appendScanCode( self, trigger, result ): @@ -123,6 +145,11 @@ class Macros: def replaceScanCode( self, trigger, result ): self.macros[ self.layer ][ trigger ] = [ result ] + # Mark layer scan code, so it won't be removed later + # Also check to see if it hasn't already been removed before + if not self.baseLayout is None and trigger in self.layerLayoutMarkers[ self.layer ]: + del self.layerLayoutMarkers[ self.layer ][ trigger ] + # Return a list of ScanCode triggers with the given USB Code trigger def lookupUSBCodes( self, usbCode ): scanCodeList = [] @@ -132,6 +159,16 @@ class Macros: if usbCode in self.macros[ self.layer ][ macro ]: scanCodeList.append( macro ) + if len(scanCodeList) == 0: + if len(usbCode) > 1 or len(usbCode[0]) > 1: + for combo in usbCode: + comboCodes = list() + for key in combo: + scanCode = self.lookupUSBCodes(((key,),)) + comboCodes.append(scanCode[0][0][0]) + scanCodeList.append(tuple(code for code in comboCodes)) + scanCodeList = [tuple(scanCodeList)] + return scanCodeList # Cache USBCode Assignment @@ -229,9 +266,90 @@ class Macros: # Shrink triggerList to actual max size self.triggerList[ layer ] = self.triggerList[ layer ][ : self.maxScanCode[ layer ] + 1 ] + # Calculate first scan code for layer, useful for uC implementations trying to save RAM + firstScanCode = 0 + for triggerList in range( 0, len( self.triggerList[ layer ] ) ): + firstScanCode = triggerList + + # Break if triggerList has items + if len( self.triggerList[ layer ][ triggerList ] ) > 0: + break; + self.firstScanCode.append( firstScanCode ) + # Determine overall maxScanCode self.overallMaxScanCode = 0x00 for maxVal in self.maxScanCode: if maxVal > self.overallMaxScanCode: self.overallMaxScanCode = maxVal + +class Variables: + # Container for variables + # Stores three sets of variables, the overall combined set, per layer, and per file + def __init__( self ): + # Dictionaries of variables + self.baseLayout = dict() + self.fileVariables = dict() + self.layerVariables = [ dict() ] + self.overallVariables = dict() + self.defines = dict() + + self.currentFile = "" + self.currentLayer = 0 + self.baseLayoutEnabled = True + + def baseLayoutFinished( self ): + self.baseLayoutEnabled = False + + def setCurrentFile( self, name ): + # Store using filename and current layer + self.currentFile = name + self.fileVariables[ name ] = dict() + + # If still processing BaseLayout + if self.baseLayoutEnabled: + if '*LayerFiles' in self.baseLayout.keys(): + self.baseLayout['*LayerFiles'] += [ name ] + else: + self.baseLayout['*LayerFiles'] = [ name ] + # Set for the current layer + else: + if '*LayerFiles' in self.layerVariables[ self.currentLayer ].keys(): + self.layerVariables[ self.currentLayer ]['*LayerFiles'] += [ name ] + else: + self.layerVariables[ self.currentLayer ]['*LayerFiles'] = [ name ] + + def incrementLayer( self ): + # Store using layer index + self.currentLayer += 1 + self.layerVariables.append( dict() ) + + def assignVariable( self, key, value ): + # Overall set of variables + self.overallVariables[ key ] = value + + # The Name variable is a special accumulation case + if key == 'Name': + # BaseLayout still being processed + if self.baseLayoutEnabled: + if '*NameStack' in self.baseLayout.keys(): + self.baseLayout['*NameStack'] += [ value ] + else: + self.baseLayout['*NameStack'] = [ value ] + # Layers + else: + if '*NameStack' in self.layerVariables[ self.currentLayer ].keys(): + self.layerVariables[ self.currentLayer ]['*NameStack'] += [ value ] + else: + self.layerVariables[ self.currentLayer ]['*NameStack'] = [ value ] + + # If still processing BaseLayout + if self.baseLayoutEnabled: + self.baseLayout[ key ] = value + # Set for the current layer + else: + self.layerVariables[ self.currentLayer ][ key ] = value + + # File context variables + self.fileVariables[ self.currentFile ][ key ] = value +