diff --git a/commands2/button/trigger.py b/commands2/button/trigger.py index c939b54..1612706 100644 --- a/commands2/button/trigger.py +++ b/commands2/button/trigger.py @@ -122,6 +122,27 @@ def _(): return self + def onChange(self, command: Command) -> Self: + """ + Starts the command when the condition changes. + + :param command: the command t start + :returns: this trigger, so calls can be chained + """ + + state = SimpleNamespace(pressed_last=self._condition()) + + @self._loop.bind + def _(): + pressed = self._condition() + + if state.pressed_last != pressed: + command.schedule() + + state.pressed_last = pressed + + return self + def whileTrue(self, command: Command) -> Self: """ Starts the given command when the condition changes to `True` and cancels it when the condition diff --git a/tests/test_trigger.py b/tests/test_trigger.py index 876ae9d..79ef9f4 100644 --- a/tests/test_trigger.py +++ b/tests/test_trigger.py @@ -42,6 +42,23 @@ def test_onFalse(scheduler: commands2.CommandScheduler): assert not command1.isScheduled() +def test_onChange(scheduler: commands2.CommandScheduler): + finished = OOBoolean(False) + command1 = commands2.WaitUntilCommand(finished) + + button = InternalButton() + button.setPressed(True) + button.onChange(command1) + scheduler.run() + assert not command1.isScheduled() + button.setPressed(False) + scheduler.run() + assert command1.isScheduled() + finished.set(True) + scheduler.run() + assert not command1.isScheduled() + + def test_whileTrueRepeatedly(scheduler: commands2.CommandScheduler): inits = OOInteger(0) counter = OOInteger(0)