Files
allwpilib/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h

581 lines
19 KiB
C
Raw Normal View History

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <functional>
#include <initializer_list>
#include <memory>
#include <span>
#include <utility>
#include <frc/event/BooleanEvent.h>
#include <frc/event/EventLoop.h>
#include <frc/filter/Debouncer.h>
#include <units/time.h>
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
#include <wpi/deprecated.h>
#include "frc2/command/Command.h"
#include "frc2/command/CommandScheduler.h"
namespace frc2 {
class Command;
/**
* This class provides an easy way to link commands to conditions.
*
* <p>It is very easy to link a button to a command. For instance, you could
* link the trigger button of a joystick to a "score" command.
*
* <p>Triggers can easily be composed for advanced functionality using the
* {@link #operator!}, {@link #operator||}, {@link #operator&&} operators.
*
* <p>This class is provided by the NewCommands VendorDep
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
class Trigger {
public:
/**
* Creates a new trigger based on the given condition.
*
* <p>Polled by the default scheduler button loop.
*
* @param condition the condition represented by this trigger
*/
explicit Trigger(std::function<bool()> condition)
: Trigger{CommandScheduler::GetInstance().GetDefaultButtonLoop(),
std::move(condition)} {}
/**
* Creates a new trigger based on the given condition.
*
* @param loop The loop instance that polls this trigger.
* @param condition the condition represented by this trigger
*/
Trigger(frc::EventLoop* loop, std::function<bool()> condition)
: m_loop{loop}, m_condition{std::move(condition)} {}
/**
* Create a new trigger that is always `false`.
*/
Trigger() : Trigger([] { return false; }) {}
Trigger(const Trigger& other);
/**
* Starts the given command whenever the condition changes from `false` to
* `true`.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to start
* @return this trigger, so calls can be chained
*/
Trigger OnTrue(Command* command);
/**
* Starts the given command whenever the condition changes from `false` to
* `true`. Moves command ownership to the button scheduler.
*
* @param command The command to bind.
* @return The trigger, for chained calls.
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
Trigger OnTrue(CommandPtr&& command);
/**
* Starts the given command whenever the condition changes from `true` to
* `false`.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to start
* @return this trigger, so calls can be chained
*/
Trigger OnFalse(Command* command);
/**
* Starts the given command whenever the condition changes from `true` to
* `false`.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* @param command The command to bind.
* @return The trigger, for chained calls.
*/
Trigger OnFalse(CommandPtr&& command);
/**
* Starts the given command when the condition changes to `true` and cancels
* it when the condition changes to `false`.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Doesn't re-start the command if it ends while the condition is still
* `true`. If the command should restart, see RepeatCommand.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to start
* @return this trigger, so calls can be chained
*/
Trigger WhileTrue(Command* command);
/**
* Starts the given command when the condition changes to `true` and cancels
* it when the condition changes to `false`. Moves command ownership to the
* button scheduler.
*
* <p>Doesn't re-start the command if it ends while the condition is still
* `true`. If the command should restart, see RepeatCommand.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* @param command The command to bind.
* @return The trigger, for chained calls.
*/
Trigger WhileTrue(CommandPtr&& command);
/**
* Starts the given command when the condition changes to `false` and cancels
* it when the condition changes to `true`.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Doesn't re-start the command if it ends while the condition is still
* `true`. If the command should restart, see RepeatCommand.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to start
* @return this trigger, so calls can be chained
*/
Trigger WhileFalse(Command* command);
/**
* Starts the given command when the condition changes to `false` and cancels
* it when the condition changes to `true`. Moves command ownership to the
* button scheduler.
*
* <p>Doesn't re-start the command if it ends while the condition is still
* `false`. If the command should restart, see RepeatCommand.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* @param command The command to bind.
* @return The trigger, for chained calls.
*/
Trigger WhileFalse(CommandPtr&& command);
/**
* Toggles a command when the condition changes from `false` to `true`.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to toggle
* @return this trigger, so calls can be chained
*/
Trigger ToggleOnTrue(Command* command);
/**
* Toggles a command when the condition changes from `false` to `true`.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to toggle
* @return this trigger, so calls can be chained
*/
Trigger ToggleOnTrue(CommandPtr&& command);
/**
* Toggles a command when the condition changes from `true` to the low
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* state.
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to toggle
* @return this trigger, so calls can be chained
*/
Trigger ToggleOnFalse(Command* command);
/**
* Toggles a command when the condition changes from `true` to the low
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* state.
*
* <p>Takes a raw pointer, and so is non-owning; users are responsible for the
* lifespan of the command.
*
* @param command the command to toggle
* @return this trigger, so calls can be chained
*/
Trigger ToggleOnFalse(CommandPtr&& command);
/**
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* Binds a command to start when the trigger becomes active. Takes a
* raw pointer, and so is non-owning; users are responsible for the lifespan
* of the command.
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnTrue(Command) instead
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use OnTrue(Command) instead")
Trigger WhenActive(Command* command);
/**
* Binds a command to start when the trigger becomes active. Transfers
* command ownership to the button scheduler, so the user does not have to
* worry about lifespan - rvalue refs will be *moved*, lvalue refs will be
* *copied.*
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnTrue(Command) instead
*/
template <class T, typename = std::enable_if_t<std::is_base_of_v<
Command, std::remove_reference_t<T>>>>
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use OnTrue(Command) instead")
Trigger WhenActive(T&& command) {
m_loop->Bind([condition = m_condition, previous = m_condition(),
command = std::make_unique<std::remove_reference_t<T>>(
std::forward<T>(command))]() mutable {
bool current = condition();
if (!previous && current) {
command->Schedule();
}
previous = current;
});
return *this;
}
/**
* Binds a runnable to execute when the trigger becomes active.
*
* @param toRun the runnable to execute.
* @param requirements the required subsystems.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnTrue(Command) instead and construct the InstantCommand
* manually
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED(
"Use OnTrue(Command) instead and construct the InstantCommand manually")
Trigger WhenActive(std::function<void()> toRun,
std::initializer_list<Subsystem*> requirements);
/**
* Binds a runnable to execute when the trigger becomes active.
*
* @param toRun the runnable to execute.
* @param requirements the required subsystems.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnTrue(Command) instead and construct the InstantCommand
* manually
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED(
"Use OnTrue(Command) instead and construct the InstantCommand manually")
Trigger WhenActive(std::function<void()> toRun,
std::span<Subsystem* const> requirements = {});
/**
* Binds a command to be started repeatedly while the trigger is active, and
* canceled when it becomes inactive. Takes a raw pointer, and so is
* non-owning; users are responsible for the lifespan of the command.
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use WhileTrue(Command) with RepeatCommand, or bind
command::Schedule with IfHigh(std::function<void()>).
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED(
"Use WhileTrue(Command) with RepeatCommand, or bind command::Schedule "
"with IfHigh(std::function<void()>).")
Trigger WhileActiveContinous(Command* command);
/**
* Binds a command to be started repeatedly while the trigger is active, and
* canceled when it becomes inactive. Transfers command ownership to the
* button scheduler, so the user does not have to worry about lifespan -
* rvalue refs will be *moved*, lvalue refs will be *copied.*
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use WhileTrue(Command) with RepeatCommand, or bind
command::Schedule with IfHigh(std::function<void()>).
*/
template <class T, typename = std::enable_if_t<std::is_base_of_v<
Command, std::remove_reference_t<T>>>>
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED(
"Use WhileTrue(Command) with RepeatCommand, or bind command::Schedule "
"with IfHigh(std::function<void()>).")
Trigger WhileActiveContinous(T&& command) {
m_loop->Bind([condition = m_condition, previous = m_condition(),
command = std::make_unique<std::remove_reference_t<T>>(
std::forward<T>(command))]() mutable {
bool current = condition();
if (current) {
command->Schedule();
} else if (previous && !current) {
command->Cancel();
}
previous = current;
});
return *this;
}
/**
* Binds a runnable to execute repeatedly while the trigger is active.
*
* @param toRun the runnable to execute.
* @param requirements the required subsystems.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use WhileTrue(Command) and construct a RunCommand manually
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use WhileTrue(Command) and construct a RunCommand manually")
Trigger WhileActiveContinous(std::function<void()> toRun,
std::initializer_list<Subsystem*> requirements);
/**
* Binds a runnable to execute repeatedly while the trigger is active.
*
* @param toRun the runnable to execute.
* @param requirements the required subsystems.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use WhileTrue(Command) and construct a RunCommand manually
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use WhileTrue(Command) and construct a RunCommand manually")
Trigger WhileActiveContinous(std::function<void()> toRun,
std::span<Subsystem* const> requirements = {});
/**
* Binds a command to be started when the trigger becomes active, and
* canceled when it becomes inactive. Takes a raw pointer, and so is
* non-owning; users are responsible for the lifespan of the command.
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use WhileTrue(Command) instead.
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use WhileTrue(Command) instead.")
Trigger WhileActiveOnce(Command* command);
/**
* Binds a command to be started when the trigger becomes active, and
* canceled when it becomes inactive. Transfers command ownership to the
* button scheduler, so the user does not have to worry about lifespan -
* rvalue refs will be *moved*, lvalue refs will be *copied.*
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use WhileTrue(Command) instead.
*/
template <class T, typename = std::enable_if_t<std::is_base_of_v<
Command, std::remove_reference_t<T>>>>
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use WhileTrue(Command) instead.")
Trigger WhileActiveOnce(T&& command) {
m_loop->Bind([condition = m_condition, previous = m_condition(),
command = std::make_unique<std::remove_reference_t<T>>(
std::forward<T>(command))]() mutable {
bool current = condition();
if (!previous && current) {
command->Schedule();
} else if (previous && !current) {
command->Cancel();
}
previous = current;
});
return *this;
}
/**
* Binds a command to start when the trigger becomes inactive. Takes a
* raw pointer, and so is non-owning; users are responsible for the lifespan
* of the command.
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnFalse(Command) instead.
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use OnFalse(Command) instead.")
Trigger WhenInactive(Command* command);
/**
* Binds a command to start when the trigger becomes inactive. Transfers
* command ownership to the button scheduler, so the user does not have to
* worry about lifespan - rvalue refs will be *moved*, lvalue refs will be
* *copied.*
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnFalse(Command) instead.
*/
template <class T, typename = std::enable_if_t<std::is_base_of_v<
Command, std::remove_reference_t<T>>>>
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use OnFalse(Command) instead.")
Trigger WhenInactive(T&& command) {
m_loop->Bind([condition = m_condition, previous = m_condition(),
command = std::make_unique<std::remove_reference_t<T>>(
std::forward<T>(command))]() mutable {
bool current = condition();
if (previous && !current) {
command->Schedule();
}
previous = current;
});
return *this;
}
/**
* Binds a runnable to execute when the trigger becomes inactive.
*
* @param toRun the runnable to execute.
* @param requirements the required subsystems.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnFalse(Command) instead and construct the InstantCommand
* manually
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED(
"Use OnFalse(Command) instead and construct the InstantCommand manually")
Trigger WhenInactive(std::function<void()> toRun,
std::initializer_list<Subsystem*> requirements);
/**
* Binds a runnable to execute when the trigger becomes inactive.
*
* @param toRun the runnable to execute.
* @param requirements the required subsystems.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use OnFalse(Command) instead and construct the InstantCommand
* manually
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED(
"Use OnFalse(Command) instead and construct the InstantCommand manually")
Trigger WhenInactive(std::function<void()> toRun,
std::span<Subsystem* const> requirements = {});
/**
* Binds a command to start when the trigger becomes active, and be canceled
* when it again becomes active. Takes a raw pointer, and so is non-owning;
* users are responsible for the lifespan of the command.
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use ToggleOnTrue(Command) instead.
*/
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use ToggleOnTrue(Command) instead.")
Trigger ToggleWhenActive(Command* command);
/**
* Binds a command to start when the trigger becomes active, and be canceled
* when it again becomes active. Transfers command ownership to the button
* scheduler, so the user does not have to worry about lifespan - rvalue refs
* will be *moved*, lvalue refs will be *copied.*
*
* @param command The command to bind.
* @return The trigger, for chained calls.
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
* @deprecated Use ToggleOnTrue(Command) instead.
*/
template <class T, typename = std::enable_if_t<std::is_base_of_v<
Command, std::remove_reference_t<T>>>>
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
WPI_DEPRECATED("Use ToggleOnTrue(Command) instead.")
Trigger ToggleWhenActive(T&& command) {
m_loop->Bind([condition = m_condition, previous = m_condition(),
command = std::make_unique<std::remove_reference_t<T>>(
std::forward<T>(command))]() mutable {
bool current = condition();
if (!previous && current) {
if (command->IsScheduled()) {
command->Cancel();
} else {
command->Schedule();
}
}
previous = current;
});
return *this;
}
/**
* Binds a command to be canceled when the trigger becomes active. Takes a
* raw pointer, and so is non-owning; users are responsible for the lifespan
* and scheduling of the command.
*
* @param command The command to bind.
* @return The trigger, for chained calls.
* @deprecated Pass this as a command end condition with Until() instead.
*/
WPI_DEPRECATED("Pass this as a command end condition with Until() instead.")
Trigger CancelWhenActive(Command* command);
/**
* Composes two triggers with logical AND.
*
* @return A trigger which is active when both component triggers are active.
*/
Trigger operator&&(std::function<bool()> rhs) {
return Trigger(m_loop, [condition = m_condition, rhs = std::move(rhs)] {
return condition() && rhs();
});
}
/**
* Composes two triggers with logical AND.
*
* @return A trigger which is active when both component triggers are active.
*/
Trigger operator&&(Trigger rhs) {
return Trigger(m_loop, [condition = m_condition, rhs] {
return condition() && rhs.m_condition();
});
}
/**
* Composes two triggers with logical OR.
*
* @return A trigger which is active when either component trigger is active.
*/
Trigger operator||(std::function<bool()> rhs) {
return Trigger(m_loop, [condition = m_condition, rhs = std::move(rhs)] {
return condition() || rhs();
});
}
/**
* Composes two triggers with logical OR.
*
* @return A trigger which is active when either component trigger is active.
*/
Trigger operator||(Trigger rhs) {
return Trigger(m_loop, [condition = m_condition, rhs] {
return condition() || rhs.m_condition();
});
}
/**
* Composes a trigger with logical NOT.
*
* @return A trigger which is active when the component trigger is inactive,
* and vice-versa.
*/
Trigger operator!() {
return Trigger(m_loop, [condition = m_condition] { return !condition(); });
}
/**
* Creates a new debounced trigger from this trigger - it will become active
* when this trigger has been active for longer than the specified period.
*
* @param debounceTime The debounce period.
* @param type The debounce type.
* @return The debounced trigger.
*/
Trigger Debounce(units::second_t debounceTime,
frc::Debouncer::DebounceType type =
frc::Debouncer::DebounceType::kRising);
[command] Rename trigger methods (#4210) Motivation Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following: - duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them. - the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge. - the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled". - whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing. Solution Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive. After consideration, deprecation of Button's subclasses was decided against: - NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API. - JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable. At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger. Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here: - onTrue (replaces whenActive): schedule on rising edge. - whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge. - toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled. Two binding types are completely deprecated: - cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()). - whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive. Notes It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-28 08:03:28 +03:00
private:
frc::EventLoop* m_loop;
std::function<bool()> m_condition;
};
} // namespace frc2