Adding support for Interconnect Nodes
- Required changing the ScanCode node datastructure - Interconnect Id's must be stored until the end as it's not possible to calculate the max per node ScanCode until after all the assignments are complete - Should make future additions more straight-forward (that require per ScanCode information to be stored)
This commit is contained in:
parent
6456b05951
commit
114d666bd8
@ -225,7 +225,11 @@ class Backend( BackendBase ):
|
||||
|
||||
# For each combo, add the key type, key state and scan code
|
||||
for combo in range( 0, len( macros.triggersIndexSorted[ trigger ][0][ sequence ] ) ):
|
||||
triggerItem = macros.triggersIndexSorted[ trigger ][ 0 ][ sequence ][ combo ]
|
||||
triggerItemId = macros.triggersIndexSorted[ trigger ][0][ sequence ][ combo ]
|
||||
|
||||
# Lookup triggerItem in ScanCodeStore
|
||||
triggerItemObj = macros.scanCodeStore[ triggerItemId ]
|
||||
triggerItem = triggerItemObj.offset( macros.interconnectOffset )
|
||||
|
||||
# TODO Add support for Analog keys
|
||||
# TODO Add support for LED states
|
||||
@ -254,6 +258,17 @@ class Backend( BackendBase ):
|
||||
self.fill_dict['MaxScanCode'] = "#define MaxScanCode 0x{0:X}".format( macros.overallMaxScanCode )
|
||||
|
||||
|
||||
## Interconnect ScanCode Offset List ##
|
||||
self.fill_dict['ScanCodeInterconnectOffsetList'] = "const uint8_t InterconnectOffsetList[] = {\n"
|
||||
for offset in range( 0, len( macros.interconnectOffset ) ):
|
||||
self.fill_dict['ScanCodeInterconnectOffsetList'] += "\t0x{0:02X},\n".format( macros.interconnectOffset[ offset ] )
|
||||
self.fill_dict['ScanCodeInterconnectOffsetList'] += "};"
|
||||
|
||||
|
||||
## Max Interconnect Nodes ##
|
||||
self.fill_dict['InterconnectNodeMax'] = "#define InterconnectNodeMax 0x{0:X}\n".format( len( macros.interconnectOffset ) )
|
||||
|
||||
|
||||
## Default Layer and Default Layer Scan Map ##
|
||||
self.fill_dict['DefaultLayerTriggerList'] = ""
|
||||
self.fill_dict['DefaultLayerScanMap'] = "const nat_ptr_t *default_scanMap[] = {\n"
|
||||
@ -267,8 +282,8 @@ class Backend( BackendBase ):
|
||||
self.fill_dict['DefaultLayerScanMap'] += "default_tl_0x{0:02X}, ".format( triggerList )
|
||||
|
||||
# Add each item of the trigger list
|
||||
for trigger in macros.triggerList[ 0 ][ triggerList ]:
|
||||
self.fill_dict['DefaultLayerTriggerList'] += ", {0}".format( trigger )
|
||||
for triggerItem in macros.triggerList[0][ triggerList ]:
|
||||
self.fill_dict['DefaultLayerTriggerList'] += ", {0}".format( triggerItem )
|
||||
|
||||
self.fill_dict['DefaultLayerTriggerList'] += " };\n"
|
||||
self.fill_dict['DefaultLayerTriggerList'] = self.fill_dict['DefaultLayerTriggerList'][:-1] # Remove last newline
|
||||
|
29
kll.py
29
kll.py
@ -478,6 +478,15 @@ def hidCodeToCapability( items ):
|
||||
return items
|
||||
|
||||
|
||||
# Convert tuple of tuples to list of lists
|
||||
def listit( t ):
|
||||
return list( map( listit, t ) ) if isinstance( t, ( list, tuple ) ) else t
|
||||
|
||||
# Convert list of lists to tuple of tuples
|
||||
def tupleit( t ):
|
||||
return tuple( map( tupleit, t ) ) if isinstance( t, ( tuple, list ) ) else t
|
||||
|
||||
|
||||
## Evaluation Rules
|
||||
|
||||
def eval_scanCode( triggers, operator, results ):
|
||||
@ -486,8 +495,26 @@ def eval_scanCode( triggers, operator, results ):
|
||||
triggers = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in triggers )
|
||||
results = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in results )
|
||||
|
||||
# Lookup interconnect id (Current file scope)
|
||||
# Default to 0 if not specified
|
||||
if 'ConnectId' not in variables_dict.overallVariables.keys():
|
||||
id_num = 0
|
||||
else:
|
||||
id_num = int( variables_dict.overallVariables['ConnectId'] )
|
||||
|
||||
# Iterate over all combinations of triggers and results
|
||||
for trigger in triggers:
|
||||
for sequence in triggers:
|
||||
# Convert tuple of tuples to list of lists so each element can be modified
|
||||
trigger = listit( sequence )
|
||||
|
||||
# Create ScanCode entries for trigger
|
||||
for seq_index, combo in enumerate( sequence ):
|
||||
for com_index, scancode in enumerate( combo ):
|
||||
trigger[ seq_index ][ com_index ] = macros_map.scanCodeStore.append( ScanCode( scancode, id_num ) )
|
||||
|
||||
# Convert back to a tuple of tuples
|
||||
trigger = tupleit( trigger )
|
||||
|
||||
for result in results:
|
||||
# Append Case
|
||||
if operator == ":+":
|
||||
|
@ -34,6 +34,67 @@ ERROR = '\033[5;1;31mERROR\033[0m:'
|
||||
|
||||
## Containers
|
||||
|
||||
class ScanCode:
|
||||
# Container for ScanCodes
|
||||
#
|
||||
# scancode - Non-interconnect adjusted scan code
|
||||
# interconnect_id - Unique id for the interconnect node
|
||||
def __init__( self, scancode, interconnect_id ):
|
||||
self.scancode = scancode
|
||||
self.interconnect_id = interconnect_id
|
||||
|
||||
def __eq__( self, other ):
|
||||
return self.dict() == other.dict()
|
||||
|
||||
def __repr__( self ):
|
||||
return repr( self.dict() )
|
||||
|
||||
def dict( self ):
|
||||
return {
|
||||
'ScanCode' : self.scancode,
|
||||
'Id' : self.interconnect_id,
|
||||
}
|
||||
|
||||
# Calculate the actual scancode using the offset list
|
||||
def offset( self, offsetList ):
|
||||
if self.interconnect_id > 0:
|
||||
return self.scancode + offsetList[ self.interconnect_id - 1 ]
|
||||
else:
|
||||
return self.scancode
|
||||
|
||||
|
||||
class ScanCodeStore:
|
||||
# Unique lookup for ScanCodes
|
||||
def __init__( self ):
|
||||
self.scancodes = []
|
||||
|
||||
def __getitem__( self, name ):
|
||||
# First check if this is a ScanCode object
|
||||
if isinstance( name, ScanCode ):
|
||||
# Do a reverse lookup
|
||||
for idx, scancode in enumerate( self.scancodes ):
|
||||
if scancode == name:
|
||||
return idx
|
||||
|
||||
# Could not find scancode
|
||||
return None
|
||||
|
||||
# Return scancode using unique id
|
||||
return self.scancodes[ name ]
|
||||
|
||||
# Attempt add ScanCode to list, return unique id
|
||||
def append( self, new_scancode ):
|
||||
# Iterate through list to make sure this is a unique ScanCode
|
||||
for idx, scancode in enumerate( self.scancodes ):
|
||||
if new_scancode == scancode:
|
||||
return idx
|
||||
|
||||
# Unique entry, add to the list
|
||||
self.scancodes.append( new_scancode )
|
||||
|
||||
return len( self.scancodes ) - 1
|
||||
|
||||
|
||||
class Capabilities:
|
||||
# Container for capabilities dictionary and convenience functions
|
||||
def __init__( self ):
|
||||
@ -87,6 +148,9 @@ class Macros:
|
||||
# Default layer (0)
|
||||
self.layer = 0
|
||||
|
||||
# Unique ScanCode Hash Id Lookup
|
||||
self.scanCodeStore = ScanCodeStore()
|
||||
|
||||
# Macro Storage
|
||||
self.macros = [ dict() ]
|
||||
|
||||
@ -102,6 +166,7 @@ class Macros:
|
||||
self.triggerList = []
|
||||
self.maxScanCode = []
|
||||
self.firstScanCode = []
|
||||
self.interconnectOffset = []
|
||||
|
||||
# USBCode Assignment Cache
|
||||
self.assignmentCache = []
|
||||
@ -199,6 +264,7 @@ class Macros:
|
||||
def generate( self ):
|
||||
self.generateIndices()
|
||||
self.sortIndexLists()
|
||||
self.generateOffsetTable()
|
||||
self.generateTriggerLists()
|
||||
|
||||
# Generates Index of Results and Triggers
|
||||
@ -229,6 +295,34 @@ class Macros:
|
||||
for trigger in self.triggersIndex.keys():
|
||||
self.triggersIndexSorted[ self.triggersIndex[ trigger ] ] = trigger
|
||||
|
||||
# Generates list of offsets for each of the interconnect ids
|
||||
def generateOffsetTable( self ):
|
||||
idMaxScanCode = [ 0 ]
|
||||
|
||||
# Iterate over each layer to get list of max scancodes associated with each interconnect id
|
||||
for layer in range( 0, len( self.macros ) ):
|
||||
# Iterate through each trigger/sequence in the layer
|
||||
for sequence in self.macros[ layer ].keys():
|
||||
# Iterate over the trigger to locate the ScanCodes
|
||||
for combo in sequence:
|
||||
# Iterate over each scancode id in the combo
|
||||
for scancode_id in combo:
|
||||
# Lookup ScanCode
|
||||
scancode_obj = self.scanCodeStore[ scancode_id ]
|
||||
|
||||
# Extend list if not large enough
|
||||
if scancode_obj.interconnect_id >= len( idMaxScanCode ):
|
||||
idMaxScanCode.extend( [ 0 ] * ( scancode_obj.interconnect_id - len( idMaxScanCode ) + 1 ) )
|
||||
|
||||
# Determine if the max seen id for this interconnect id
|
||||
if scancode_obj.scancode > idMaxScanCode[ scancode_obj.interconnect_id ]:
|
||||
idMaxScanCode[ scancode_obj.interconnect_id ] = scancode_obj.scancode
|
||||
|
||||
# Generate interconnect offsets
|
||||
self.interconnectOffset = [ idMaxScanCode[0] + 1 ]
|
||||
for index in range( 1, len( idMaxScanCode ) ):
|
||||
self.interconnectOffset.append( self.interconnectOffset[ index - 1 ] + idMaxScanCode[ index ] )
|
||||
|
||||
# Generates Trigger Lists per layer using index lists
|
||||
def generateTriggerLists( self ):
|
||||
for layer in range( 0, len( self.macros ) ):
|
||||
@ -248,7 +342,8 @@ class Macros:
|
||||
|
||||
# Iterate over the trigger to locate the ScanCodes
|
||||
for sequence in trigger:
|
||||
for combo in sequence:
|
||||
for combo_id in sequence:
|
||||
combo = self.scanCodeStore[ combo_id ].offset( self.interconnectOffset )
|
||||
# Append triggerIndex for each found scanCode of the Trigger List
|
||||
# Do not re-add if triggerIndex is already in the Trigger List
|
||||
if not triggerIndex in self.triggerList[ layer ][ combo ]:
|
||||
|
@ -25,5 +25,9 @@
|
||||
|
||||
|
||||
// ----- Defines -----
|
||||
|
||||
// -- Interconnect Node Maximum --
|
||||
<|InterconnectNodeMax|>
|
||||
|
||||
<|Defines|>
|
||||
|
||||
|
@ -91,6 +91,13 @@
|
||||
<|PartialLayerTriggerLists|>
|
||||
|
||||
|
||||
// -- ScanCode Offset Map
|
||||
// Maps interconnect ids to scancode offsets
|
||||
//
|
||||
// Only used for keyboards with an interconnect
|
||||
<|ScanCodeInterconnectOffsetList|>
|
||||
|
||||
|
||||
// -- ScanCode Indexed Maps
|
||||
// Maps to a trigger list of macro pointers
|
||||
// _
|
||||
|
Reference in New Issue
Block a user