diff --git a/arcade/experimental/input/inputs.py b/arcade/experimental/input/inputs.py index 665efe608..a8709423a 100644 --- a/arcade/experimental/input/inputs.py +++ b/arcade/experimental/input/inputs.py @@ -1,5 +1,4 @@ -# type: ignore - +#type: ignore """ Enums used to map different input types to their common counterparts. @@ -90,9 +89,7 @@ class Keys(InputEnum): MOD_SCROLLLOCK = 256 # Platform-specific base hotkey modifier - MOD_ACCEL = MOD_CTRL - if platform == "darwin": - MOD_ACCEL = MOD_COMMAND + MOD_ACCEL = MOD_COMMAND if platform == "darwin" else MOD_CTRL # Keys BACKSPACE = 65288 @@ -319,3 +316,37 @@ class MouseButtons(InputEnum): MOUSE_4 = 1 << 3 MOUSE_5 = 1 << 4 + + +#.This is safe since: +# 1. Enum types with members are final +#.2. Types are hashable +# Hoever, we can probably make this much cleaner to set up since +# we have repeated if ladders elsewhere which can be replaced with +# smaller dicts. +CLASS_TO_INPUT_TYPE = { + Keys: InputType.KEYBOARD, + MouseButtons: InputType.MOUSE_BUTTON, + MouseAxes: InputType.MOUSE_AXIS, + ControllerButtons: InputType.CONTROLLER_BUTTON, + ControllerAxes: InputType.CONTROLLER_AXIS, +} + +INPUT_TYPE_TO_CLASS = { + InputType.KEYBOARD: Keys, + InputType.MOUSE_BUTTON: MouseButtons, + InputType.MOUSE_AXIS: MouseAxes, + InputType.CONTROLLER_BUTTON: ControllerButtons, + InputType.CONTROLLER_AXIS: ControllerAxes, +} + + +# WIP cleanup, will be documented and named better and actually annotated later +def parse_instance(_mapping): + _raw_input = _mapping['input'] + _input_type = InputType(_mapping["input_type"]) + + if not (_input_class := INPUT_TYPE_TO_CLASS.get(_input_type, None)): + raise AttributeError("Tried to parse an unknown input type") + return _input_class(_raw_input) + diff --git a/arcade/experimental/input/manager.py b/arcade/experimental/input/manager.py index 30f9c4795..e00110fb8 100644 --- a/arcade/experimental/input/manager.py +++ b/arcade/experimental/input/manager.py @@ -1,5 +1,4 @@ -# type: ignore - +# type: ignore from __future__ import annotations from enum import Enum @@ -24,10 +23,12 @@ serialize_axis, ) -RawInputManager = TypedDict( - "RawInputManager", - {"actions": List[RawAction], "axes": List[RawAxis], "controller_deadzone": float}, -) + + +class RawInputManager(TypedDict): + actions: List[RawAction] + axes: List[RawAxis] + controller_deadzone: float def _set_discard(set: Set, element: Any) -> Set: @@ -125,24 +126,13 @@ def parse(cls, raw: RawInputManager) -> InputManager: for raw_action in raw["actions"]: name = raw_action["name"] final.new_action(name) + for raw_mapping in raw_action["mappings"]: - raw_input = raw_mapping["input"] - input_type = inputs.InputType(raw_mapping["input_type"]) - if input_type == inputs.InputType.KEYBOARD: - input = inputs.Keys(raw_input) - elif input_type == inputs.InputType.MOUSE_BUTTON: - input = inputs.MouseButtons(raw_input) - elif input_type == inputs.InputType.MOUSE_AXIS: - input = inputs.MouseAxes(raw_input) - elif input_type == inputs.InputType.CONTROLLER_BUTTON: - input = inputs.ControllerButtons(raw_input) - elif input_type == inputs.InputType.CONTROLLER_AXIS: - input = inputs.ControllerAxes(raw_input) - else: - raise AttributeError("Tried to parse an unknown input type") + input_instance = inputs.parse_instance(raw_mapping) + final.add_action_input( name, - input, + input_instance, raw_mapping["mod_shift"], raw_mapping["mod_ctrl"], raw_mapping["mod_alt"], @@ -152,21 +142,9 @@ def parse(cls, raw: RawInputManager) -> InputManager: name = raw_axis["name"] final.new_axis(name) for raw_mapping in raw_axis["mappings"]: - raw_input = raw_mapping["input"] - input_type = inputs.InputType(raw_mapping["input_type"]) - if input_type == inputs.InputType.KEYBOARD: - input = inputs.Keys(raw_input) - elif input_type == inputs.InputType.MOUSE_BUTTON: - input = inputs.MouseButtons(raw_input) - elif input_type == inputs.InputType.MOUSE_AXIS: - input = inputs.MouseAxes(raw_input) - elif input_type == inputs.InputType.CONTROLLER_BUTTON: - input = inputs.ControllerButtons(raw_input) - elif input_type == inputs.InputType.CONTROLLER_AXIS: - input = inputs.ControllerAxes(raw_input) - else: - raise AttributeError("Tried to parse an unknown input type") - final.add_axis_input(name, input, raw_mapping["scale"]) + input_instance = inputs.parse_instance(raw_mapping) + + final.add_axis_input(name, input_instance, raw_mapping["scale"]) return final @@ -484,7 +462,7 @@ def on_mouse_release(self, x: int, y: int, button: int, modifiers: int) -> None: def on_key_release(self, key: int, modifiers) -> None: if not self._allow_keyboard: return - + # What, why are we doing any of this repeat tuple conversion in here? keys_to_actions = tuple(self.keys_to_actions.get(key, set())) for action_name in keys_to_actions: action = self.actions[action_name] diff --git a/arcade/experimental/input/mapping.py b/arcade/experimental/input/mapping.py index 2d448d2c0..28b2e47b7 100644 --- a/arcade/experimental/input/mapping.py +++ b/arcade/experimental/input/mapping.py @@ -8,22 +8,29 @@ from arcade.experimental.input import inputs -RawActionMapping = TypedDict( - "RawActionMapping", - { - "input_type": int, - "input": Union[str, int], - "mod_shift": bool, - "mod_ctrl": bool, - "mod_alt": bool, - }, -) -RawAxisMapping = TypedDict( - "RawAxisMapping", {"input_type": int, "input": Union[str, int], "scale": float} -) - -RawAction = TypedDict("RawAction", {"name": str, "mappings": List[RawActionMapping]}) -RawAxis = TypedDict("RawAxis", {"name": str, "mappings": List[RawAxisMapping]}) + +class RawActionMapping(TypedDict): + input_type: int + input: Union[str, int] + mod_shift: bool + mod_ctrl: bool + mod_alt: bool + + +class RawAxisMapping(TypedDict): + input_type: int + input: Union[str, int] + scale: float + + +class RawAction(TypedDict): + name: str + mappings: List[RawActionMapping] + + +class RawAxis(TypedDict): + name: str + mappings: List[RawAxisMapping] class Action: @@ -61,21 +68,12 @@ def remove_mapping(self, mapping: AxisMapping) -> None: class Mapping: def __init__(self, input: inputs.InputEnum): - if isinstance(input, inputs.Keys): - self._input_type = inputs.InputType.KEYBOARD - elif isinstance(input, inputs.MouseButtons): - self._input_type = inputs.InputType.MOUSE_BUTTON - elif isinstance(input, inputs.MouseAxes): - self._input_type = inputs.InputType.MOUSE_AXIS - elif isinstance(input, inputs.ControllerButtons): - self._input_type = inputs.InputType.CONTROLLER_BUTTON - elif isinstance(input, inputs.ControllerAxes): - self._input_type = inputs.InputType.CONTROLLER_AXIS - else: + try: + self._input_type = inputs.CLASS_TO_INPUT_TYPE[input] + except KeyError: raise TypeError( "Input specified for ActionMapping must inherit from InputEnum" ) - self._input = input @@ -127,23 +125,10 @@ def serialize_action(action: Action) -> RawAction: def parse_raw_axis(raw_axis: RawAxis) -> Axis: axis = Axis(raw_axis["name"]) for raw_mapping in raw_axis["mappings"]: - raw_input = raw_mapping["input"] - input_type = inputs.InputType(raw_mapping["input_type"]) - if input_type == inputs.InputType.KEYBOARD: - input = inputs.Keys(raw_input) - elif input_type == inputs.InputType.MOUSE_BUTTON: - input = inputs.MouseButtons(raw_input) - elif input_type == inputs.InputType.MOUSE_AXIS: - input = inputs.MouseAxes(raw_input) - elif input_type == inputs.InputType.CONTROLLER_BUTTON: - input = inputs.ControllerButtons(raw_input) - elif input_type == inputs.InputType.CONTROLLER_AXIS: - input = inputs.ControllerAxes(raw_input) - else: - raise AttributeError("Tried to parse an unknown input type") + instance = inputs.parse_instance(raw_mapping) axis.add_mapping( AxisMapping( - input, + instance, raw_mapping["scale"], ) )