More methods!
parent
607894648c
commit
9331f13786
|
@ -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,12 +393,10 @@ 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':
|
||||||
|
@ -422,41 +406,44 @@ class Double(Bind):
|
||||||
'`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.
|
||||||
|
|
Loading…
Reference in New Issue