More methods!

main
Nicholas Hope 2022-10-05 21:32:07 -04:00
parent 607894648c
commit 9331f13786
1 changed files with 125 additions and 138 deletions

View File

@ -28,7 +28,7 @@ class Bind(object):
bindTypes = [] bindTypes = []
instances = {} instances = {}
def __init__(self, key='', fields={}, *, parent=None): def __init__(self, key='', fields={}, /,*, parent=None):
if parent is None: if parent is None:
self.alias = False self.alias = False
self.key = str(key) self.key = str(key)
@ -72,15 +72,11 @@ class Bind(object):
self.instances[type(self)] = [self] self.instances[type(self)] = [self]
def verify(self): def verify(self):
try: self.alias = self.optional('alias', default=False)
self.alias = self.fields.pop('alias')
if not isinstance(self.alias, bool): if not isinstance(self.alias, bool):
self.errors.append( self.err(
f'alias should be "yes" or "no", not "{self.alias}"' f'`alias` should be "yes" or "no", not "{self.alias}"'
) )
self.alias = False
except popErrors:
self.alias = False
try: try:
typeName, self.key = self.key.split(' ', 1) typeName, self.key = self.key.split(' ', 1)
@ -107,6 +103,21 @@ class Bind(object):
if (not self.alias) and (self.key not in validKeyList): if (not self.alias) and (self.key not in validKeyList):
self.errors.append(f'invalid key name: "{self.key}"') self.errors.append(f'invalid key name: "{self.key}"')
def optional(self, name, /,*, default=None):
try:
return self.fields.pop(name)
except popErrors:
return default
def cmdListFrom(self, name, /,*, default=None):
result = self.fields.pop(name)
if isinstance(result, str):
return result.split(';')
elif isinstance(result, list):
return result
else:
return default
def toTargetType(self): def toTargetType(self):
if self.TargetType is None: if self.TargetType is None:
# do nothing # do nothing
@ -128,21 +139,20 @@ class Bind(object):
class Impulse(Bind): class Impulse(Bind):
def verify(self): def verify(self):
self.command = None self.command: list = None
if not isinstance(self.fields, dict): if not isinstance(self.fields, dict):
self.fields = {'command': self.fields} self.fields = {'command': self.fields}
try: try:
self.command = self.fields.pop('command') self.command = self.cmdListFrom(
if isinstance(self.command, str): 'command',
self.command = self.command.split(';') default=self.fields
elif not isinstance(self.command, list): )
self.err('`command` field must be argument of string or list') if self.command is None:
self.command = None self.err('`command` field must be string or list')
except KeyError: except popErrors:
self.err('requires `command` field') self.err('requires `command` field')
def toTF2(self) -> str: def toTF2(self) -> str:
if self.alias: if self.alias:
bindOrAlias = 'alias' bindOrAlias = 'alias'
@ -167,11 +177,8 @@ class Impulse(Bind):
'secondary': 'slot2', 'secondary': 'slot2',
'melee': 'slot3' 'melee': 'slot3'
} }
try: # if is shortcut, change
cmd = simpleSCs[cmd] cmd = simpleSCs.get(cmd, cmd)
except KeyError:
# not a shortcut
pass
if cmd == 'voice': if cmd == 'voice':
cmd = 'voicemenu' cmd = 'voicemenu'
@ -183,8 +190,8 @@ class Impulse(Bind):
elif cmd == 'loadout' and restOfCmd.isalpha(): elif cmd == 'loadout' and restOfCmd.isalpha():
cmd = 'load_itempreset' cmd = 'load_itempreset'
try: try:
restOfCmd = restOfCmd.lower() loadoutNum = ['a','b','c','d'].index(restOfCmd.lower())
restOfCmd = str(['a','b','c','d'].index(restOfCmd)) restOfCmd = str(loadoutNum)
except ValueError: except ValueError:
# not a load_itempreset shortcut # not a load_itempreset shortcut
pass pass
@ -221,40 +228,32 @@ class Impulse(Bind):
'exit': '1 1', 'exit': '1 1',
'sentry': '2 0' 'sentry': '2 0'
} }
for shortBuild, num in buildingNums.items(): return buildingNums.get(building, building)
if building == shortBuild:
return num
class Hold(Bind): class Hold(Bind):
def verify(self): def verify(self):
self.press = None self.press: list = None
self.release = None self.release: list = None
if not isinstance(self.fields, dict): if not isinstance(self.fields, dict):
self.fields = {'press': self.fields} self.fields = {'press': self.fields}
# verify press # verify press
try: try:
self.press = self.fields.pop('press') self.press = self.cmdListFrom('press')
if isinstance(self.press, str):
self.press = self.press.split(';')
elif not isinstance(self.press, list):
self.err('`press` field must be string or list')
self.press = None
except KeyError:
self.err('requires `press` field')
if self.press is None: if self.press is None:
return self.err('`press` field must be string or list')
except popErrors:
self.err('requires `press` field')
# verify release # verify release
try: try:
self.release = self.fields.pop('release') self.release = self.cmdListFrom('release')
if isinstance(self.release, str): if self.release is None:
self.release = self.release.split(';')
elif not isinstance(self.release, list):
self.err('`release` field must be string or list') self.err('`release` field must be string or list')
self.release = None
except popErrors: except popErrors:
if self.press is None:
return
self.warn('has no `release`, creating one') self.warn('has no `release`, creating one')
# no release specified, do -action for each item in press # no release specified, do -action for each item in press
self.release = [] self.release = []
@ -271,11 +270,11 @@ class Hold(Bind):
# Making impulse instances from self.press and .release # Making impulse instances from self.press and .release
# allows them to share the shortcuts # allows them to share the shortcuts
pressObj = Impulse(f'+{holdStr}', self.press) pressObj = Impulse('+' + holdStr, self.press)
pressObj.alias = True pressObj.alias = True
pressStr = pressObj.toTF2() pressStr = pressObj.toTF2()
releaseObj = Impulse(f'-{holdStr}', self.release) releaseObj = Impulse('-' + holdStr, self.release)
releaseObj.alias = True releaseObj.alias = True
releaseStr = releaseObj.toTF2() releaseStr = releaseObj.toTF2()
@ -296,34 +295,29 @@ class Hold(Bind):
class Toggle(Bind): class Toggle(Bind):
def verify(self): def verify(self):
self.on = None self.on : list = None
self.off = None self.off: list = None
if not isinstance(self.fields, dict): if not isinstance(self.fields, dict):
self.fields = {'on': self.fields} self.fields = {'on': self.fields}
# verify on # verify on
try: try:
self.on = self.fields.pop('on') self.on = self.cmdListFrom('on')
if isinstance(self.on, str):
self.on = self.on.split(';')
elif not isinstance(self.on, list):
self.err('`on` field must be string or list')
self.on = None
except KeyError:
self.err('requires `on` field')
if self.on is None: if self.on is None:
return self.err(f'`on` field must be string or list')
except popErrors:
self.err('requires `on` field')
# verify off # verify off
try: try:
self.off = self.fields.pop('off') self.off = self.cmdListFrom('off')
if isinstance(self.off, str): if self.off is None:
self.off = self.off.split(';') self.err(f'`off` field must be string or list')
elif not isinstance(self.off, list):
self.err('`off` field must be string or list')
except popErrors: except popErrors:
# no off specified, do -action for each item in on # no off specified, do -action for each item in on
self.off = [] self.off = []
if self.on is None:
return
for cmd in self.on: for cmd in self.on:
if cmd[0] == '+': if cmd[0] == '+':
self.off.append('-' + cmd[1:]) self.off.append('-' + cmd[1:])
@ -361,21 +355,16 @@ class Double(Bind):
bindNames = [] bindNames = []
def verify(self): def verify(self):
self.primary = None
self.primStr = f'{self.key}_primary' self.primStr = f'{self.key}_primary'
self.secondary = None
self.secondStr = f'{self.key}_secondary' self.secondStr = f'{self.key}_secondary'
self.condition = None
self.isToggle = False self.isToggle = False
# name of a bind type
self.type = None
# either 'released' (default) or 'both'
self.cancelBoth = False self.cancelBoth = False
self.primary: Bind = None
self.secondary: Bind = None
self.condition: str = None
self.type: str = None
# toggler # toggler
try: try:
self.condition = self.fields.pop('condition') self.condition = self.fields.pop('condition')
@ -384,15 +373,12 @@ class Double(Bind):
except popErrors: except popErrors:
self.err('requires `condition` field') self.err('requires `condition` field')
try: self.isToggle = self.optional('toggle', default=False)
self.isToggle = self.fields.pop('toggle')
if not isinstance(self.isToggle, bool): if not isinstance(self.isToggle, bool):
self.err( self.err(
'`toggle` field should be "yes" or "no", ' '`toggle` field should be "yes" or "no",'
+ f'not "{self.isToggle}"' + f' not "{self.isToggle}"'
) )
except popErrors:
self.isToggle = False
# type # type
try: try:
@ -407,56 +393,57 @@ class Double(Bind):
return return
# cancel mode, must happend after type has been inferred # cancel mode, must happend after type has been inferred
try: cancel = self.optional('cancel', default='released')
cancel = self.fields.pop('cancel')
if not isinstance(cancel, str): if not isinstance(cancel, str):
self.err(f'`cancel` field must be "released" or "both"') self.err(f'`cancel` field must be "released" or "both"')
else: else:
if cancel == 'both': if cancel == 'both':
if self.type == 'hold': if self.type == 'hold':
self.cancelBoth = True self.cancelBoth = True
else: else:
self.err( self.err(
'`cancel` field only affects "hold", ' '`cancel` field only affects "hold",'
+ f'not "{self.type}"' + f' not "{self.type}"'
) )
elif cancel == 'released':
elif cancel != 'released': self.cancelBoth = False
else:
self.err( self.err(
'`cancel` field must be "released" ' '`cancel` field must be "released"'
+ f'or "both", not "{cancel}"' + f' or "both", not "{cancel}"'
) )
except popErrors:
cancel = 'released'
# primary action
try: try:
mainSection = self.fields.pop('primary') self.primary = self.getSection('primary', self.primStr)
mainBind = Bind(f'{self.type} {self.primStr}', mainSection)
mainBind = mainBind.toTargetType()
self.errors.extend(mainBind.errors)
self.warnings.extend(mainBind.warnings)
self.errors.remove(f'invalid key name: "{self.primStr}"')
self.primary = mainBind
except popErrors: except popErrors:
self.err('requires `primary` field') self.primary = None
# secondary action
try: try:
altSection = self.fields.pop('secondary') self.secondary = self.getSection('secondary', self.secondStr)
altBind = Bind(f'{self.type} {self.secondStr}', altSection)
altBind = altBind.toTargetType()
self.errors.extend(altBind.errors)
self.warnings.extend(altBind.warnings)
self.errors.remove(f'invalid key name: "{self.secondStr}"')
self.secondary = altBind
except popErrors: except popErrors:
self.err('requires `secondary` field') self.secondary = None
if self.primary is self.secondary is None:
self.err('has neither primary nor secondary')
def getSection(self, popName, key, /) -> Bind:
section = self.fields.pop(popName)
bind = Bind(f'{self.type} {key}', section)
bind = bind.toTargetType()
bind.errors.remove(f'invalid key name: "{key}"')
self.prettifyList(bind.errors, key)
self.errors.extend(bind.errors)
self.prettifyList(bind.warnings, key)
self.warnings.extend(bind.warnings)
return bind
def prettifyList(self, strList, origStr):
repStr = ' '.join(origStr.split('_', 1))
for i, cmd in enumerate(strList):
strList[i] = cmd.replace(origStr, repStr)
def toTF2(self) -> str: def toTF2(self) -> str:
# Get code for primary and secondary actions. # Get code for primary and secondary actions.