[wpilib,cmd2] Fix up issues with generated gamepads (#8985)

There were a few issues with the generated classes.

Python had a __getattr__ forwarder that we defintely did not want.
C++ was using a struct with constexpr values, and not an enum class for
button types.
In all 3, the forwarders from gamepad didn't exist on the generated
types.

This fixes all 3.

---------

Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
This commit is contained in:
Thad House
2026-06-19 14:53:41 -07:00
committed by GitHub
parent 0b950ea6d9
commit 8d2f3212e7
33 changed files with 1571 additions and 600 deletions

View File

@@ -1,6 +1,6 @@
# THIS FILE WAS AUTO-GENERATED BY ./commandsv2/generate_hids.py. DO NOT MODIFY
from typing import Optional
from typing import Optional, Union
from wpilib import EventLoop, {{ ClassName }}Controller
@@ -8,13 +8,6 @@ from .commandgenerichid import CommandGenericHID
from .trigger import Trigger
def _enum_value(value) -> int:
try:
return int(value)
except TypeError:
return value.value
class Command{{ ClassName }}Controller:
"""
A version of :class:`wpilib.{{ ClassName }}Controller` with :class:`.Trigger` factories for command-based.
@@ -23,17 +16,19 @@ class Command{{ ClassName }}Controller:
_hid: CommandGenericHID
_controller: {{ ClassName }}Controller
def __init__(self, port: int):
def __init__(self, hid: Union[int, {{ ClassName }}Controller]):
"""
Construct an instance of a controller.
:param port: The port index on the Driver Station that the controller is plugged into.
:param hid: The port index on the Driver Station that the controller is plugged into,
or the {{ ClassName }}Controller object to use for this controller.
"""
self._hid = CommandGenericHID.getCommandGenericHID(port)
self._controller = {{ ClassName }}Controller(self._hid.getHID())
def __getattr__(self, name: str):
return getattr(self._hid, name)
if isinstance(hid, int):
self._hid = CommandGenericHID.getCommandGenericHID(hid)
self._controller = {{ ClassName }}Controller(self._hid.getHID())
else:
self._hid = CommandGenericHID(hid.getHID())
self._controller = hid
def getHID(self) -> CommandGenericHID:
"""
@@ -50,6 +45,19 @@ class Command{{ ClassName }}Controller:
:returns: the wrapped controller object
"""
return self._controller
def button(
self,
button: {{ ClassName }}Controller.Button,
loop: Optional[EventLoop] = None,
) -> Trigger:
"""
Constructs an event instance around this button's digital signal.
:param button: the :class:`wpilib.{{ ClassName }}Controller.Button` to read
:param loop: the event loop instance to attach the event to
"""
return self._hid.button(button.value, loop)
{% for button in buttons %}
def {{ button.Name }}(self, loop: Optional[EventLoop] = None) -> Trigger:
"""
@@ -61,9 +69,7 @@ class Command{{ ClassName }}Controller:
:returns: a Trigger instance representing the {{ button.DocName }} button's digital signal
attached to the given loop.
"""
return self._hid.button(
_enum_value({{ ClassName }}Controller.Button.{{ button.ConstantName }}), loop
)
return self.button({{ ClassName }}Controller.Button.{{ button.ConstantName }}, loop)
{% endfor -%}
{% for trigger in triggerAxes %}
def {{ trigger.Name }}(
@@ -83,12 +89,76 @@ class Command{{ ClassName }}Controller:
:returns: a Trigger instance that is true when the {{ trigger.DocName }} axis exceeds the
provided threshold, attached to the given event loop.
"""
return self._hid.axisGreaterThan(
_enum_value({{ ClassName }}Controller.Axis.{{ trigger.AxisConstantName }}),
return self.axisGreaterThan(
{{ ClassName }}Controller.Axis.{{ trigger.AxisConstantName }},
threshold,
loop,
)
{% endfor -%}
{% endfor %}
def axisLessThan(
self,
axis: {{ ClassName }}Controller.Axis,
threshold: float,
loop: Optional[EventLoop] = None,
) -> Trigger:
"""
Constructs a Trigger instance that is true when the axis value is less than
``threshold``, attached to the given loop.
:param axis: the :class:`wpilib.{{ ClassName }}Controller.Axis` to read
:param threshold: the value below which this Trigger should return true.
:param loop: the event loop instance to attach the Trigger to
:returns: a Trigger instance that is true when the axis value is less than
the provided threshold.
"""
return self._hid.axisLessThan(axis.value, threshold, loop)
def axisGreaterThan(
self,
axis: {{ ClassName }}Controller.Axis,
threshold: float,
loop: Optional[EventLoop] = None,
) -> Trigger:
"""
Constructs a Trigger instance that is true when the axis value is greater
than ``threshold``, attached to the given loop.
:param axis: the :class:`wpilib.{{ ClassName }}Controller.Axis` to read
:param threshold: the value above which this Trigger should return true.
:param loop: the event loop instance to attach the Trigger to.
:returns: a Trigger instance that is true when the axis value is greater
than the provided threshold.
"""
return self._hid.axisGreaterThan(axis.value, threshold, loop)
def axisMagnitudeGreaterThan(
self,
axis: {{ ClassName }}Controller.Axis,
threshold: float,
loop: Optional[EventLoop] = None,
) -> Trigger:
"""
Constructs a Trigger instance that is true when the axis magnitude is
greater than ``threshold``, attached to the given loop.
:param axis: the :class:`wpilib.{{ ClassName }}Controller.Axis` to read
:param threshold: the value above which this Trigger should return true.
:param loop: the event loop instance to attach the Trigger to.
:returns: a Trigger instance that is true when the axis magnitude is
greater than the provided threshold.
"""
return self._hid.axisMagnitudeGreaterThan(axis.value, threshold, loop)
def getAxis(self, axis: {{ ClassName }}Controller.Axis) -> float:
"""
Get the value of the axis.
:param axis: the :class:`wpilib.{{ ClassName }}Controller.Axis` to read
"""
return self._hid.getRawAxis(axis.value)
{% for axis in axes %}
def get{{ axis.MethodName }}(self) -> float:
"""