mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-21 01:01:43 +00:00
[commands] C++ unique_ptr migration (#4319)
Add a CommandPtr with an internal unique_ptr to enable not needing to move the underlying classes, which is error-prone due to the potential for lambda captures.
This commit is contained in:
@@ -24,15 +24,8 @@ std::string GetTypeName(const T& type) {
|
||||
return wpi::Demangle(typeid(type).name());
|
||||
}
|
||||
|
||||
class EndlessCommand;
|
||||
class ParallelCommandGroup;
|
||||
class ParallelRaceGroup;
|
||||
class ParallelDeadlineGroup;
|
||||
class SequentialCommandGroup;
|
||||
class PerpetualCommand;
|
||||
class ProxyScheduleCommand;
|
||||
class RepeatCommand;
|
||||
class ConditionalCommand;
|
||||
|
||||
/**
|
||||
* A state machine representing a complete action to be performed by the robot.
|
||||
@@ -121,6 +114,8 @@ class Command {
|
||||
kCancelIncoming
|
||||
};
|
||||
|
||||
friend class CommandPtr;
|
||||
|
||||
/**
|
||||
* Decorates this command with a timeout. If the specified timeout is
|
||||
* exceeded before the command finishes normally, the command will be
|
||||
@@ -130,7 +125,7 @@ class Command {
|
||||
* @param duration the timeout duration
|
||||
* @return the command with the timeout added
|
||||
*/
|
||||
ParallelRaceGroup WithTimeout(units::second_t duration) &&;
|
||||
[[nodiscard]] CommandPtr WithTimeout(units::second_t duration) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with an interrupt condition. If the specified
|
||||
@@ -141,7 +136,7 @@ class Command {
|
||||
* @param condition the interrupt condition
|
||||
* @return the command with the interrupt condition added
|
||||
*/
|
||||
ParallelRaceGroup Until(std::function<bool()> condition) &&;
|
||||
[[nodiscard]] CommandPtr Until(std::function<bool()> condition) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with an interrupt condition. If the specified
|
||||
@@ -154,7 +149,7 @@ class Command {
|
||||
* @deprecated Replace with Until()
|
||||
*/
|
||||
WPI_DEPRECATED("Replace with Until()")
|
||||
ParallelRaceGroup WithInterrupt(std::function<bool()> condition) &&;
|
||||
[[nodiscard]] CommandPtr WithInterrupt(std::function<bool()> condition) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a runnable to run before this command starts.
|
||||
@@ -163,7 +158,7 @@ class Command {
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
SequentialCommandGroup BeforeStarting(
|
||||
[[nodiscard]] CommandPtr BeforeStarting(
|
||||
std::function<void()> toRun,
|
||||
std::initializer_list<Subsystem*> requirements) &&;
|
||||
|
||||
@@ -174,7 +169,7 @@ class Command {
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
SequentialCommandGroup BeforeStarting(
|
||||
[[nodiscard]] CommandPtr BeforeStarting(
|
||||
std::function<void()> toRun,
|
||||
wpi::span<Subsystem* const> requirements = {}) &&;
|
||||
|
||||
@@ -185,7 +180,7 @@ class Command {
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
SequentialCommandGroup AndThen(
|
||||
[[nodiscard]] CommandPtr AndThen(
|
||||
std::function<void()> toRun,
|
||||
std::initializer_list<Subsystem*> requirements) &&;
|
||||
|
||||
@@ -196,7 +191,7 @@ class Command {
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
SequentialCommandGroup AndThen(
|
||||
[[nodiscard]] CommandPtr AndThen(
|
||||
std::function<void()> toRun,
|
||||
wpi::span<Subsystem* const> requirements = {}) &&;
|
||||
|
||||
@@ -216,7 +211,7 @@ class Command {
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
EndlessCommand Endlessly() &&;
|
||||
[[nodiscard]] CommandPtr Endlessly() &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run repeatedly, restarting it when it ends, until
|
||||
@@ -224,7 +219,7 @@ class Command {
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
RepeatCommand Repeatedly() &&;
|
||||
[[nodiscard]] CommandPtr Repeatedly() &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run "by proxy" by wrapping it in a
|
||||
@@ -232,9 +227,11 @@ class Command {
|
||||
* when the user does not wish to extend the command's requirements to the
|
||||
* entire command group.
|
||||
*
|
||||
* <p>This overload transfers command ownership to the returned CommandPtr.
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
ProxyScheduleCommand AsProxy();
|
||||
[[nodiscard]] CommandPtr AsProxy() &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to only run if this condition is not met. If the
|
||||
@@ -245,7 +242,7 @@ class Command {
|
||||
* @param condition the condition that will prevent the command from running
|
||||
* @return the decorated command
|
||||
*/
|
||||
ConditionalCommand Unless(std::function<bool()> condition) &&;
|
||||
[[nodiscard]] CommandPtr Unless(std::function<bool()> condition) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run or stop when disabled.
|
||||
@@ -253,7 +250,7 @@ class Command {
|
||||
* @param doesRunWhenDisabled true to run when disabled.
|
||||
* @return the decorated command
|
||||
*/
|
||||
std::unique_ptr<Command> IgnoringDisable(bool doesRunWhenDisabled) &&;
|
||||
[[nodiscard]] CommandPtr IgnoringDisable(bool doesRunWhenDisabled) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run or stop when disabled.
|
||||
@@ -261,8 +258,8 @@ class Command {
|
||||
* @param interruptBehavior true to run when disabled.
|
||||
* @return the decorated command
|
||||
*/
|
||||
std::unique_ptr<Command> WithInterruptBehavior(
|
||||
InterruptionBehavior interruptBehavior) &&;
|
||||
[[nodiscard]] CommandPtr WithInterruptBehavior(
|
||||
Command::InterruptionBehavior interruptBehavior) &&;
|
||||
|
||||
/**
|
||||
* Schedules this command.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "frc2/command/Command.h"
|
||||
#include "frc2/command/CommandPtr.h"
|
||||
|
||||
namespace frc2 {
|
||||
|
||||
@@ -28,6 +29,11 @@ class CommandHelper : public Base {
|
||||
public:
|
||||
CommandHelper() = default;
|
||||
|
||||
CommandPtr ToPtr() && {
|
||||
return CommandPtr(
|
||||
std::make_unique<CRTP>(std::move(*static_cast<CRTP*>(this))));
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Command> TransferOwnership() && override {
|
||||
return std::make_unique<CRTP>(std::move(*static_cast<CRTP*>(this)));
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
// 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 <string>
|
||||
#include <utility>
|
||||
|
||||
#include "frc2/command/Command.h"
|
||||
|
||||
namespace frc2 {
|
||||
class CommandPtr final {
|
||||
public:
|
||||
explicit CommandPtr(std::unique_ptr<Command>&& command)
|
||||
: m_ptr(std::move(command)) {}
|
||||
|
||||
template <class T, typename = std::enable_if_t<std::is_base_of_v<
|
||||
Command, std::remove_reference_t<T>>>>
|
||||
explicit CommandPtr(T&& command)
|
||||
: CommandPtr(std::make_unique<std::remove_reference_t<T>>(
|
||||
std::forward<T>(command))) {}
|
||||
|
||||
CommandPtr(CommandPtr&&) = default;
|
||||
CommandPtr& operator=(CommandPtr&&) = default;
|
||||
|
||||
/**
|
||||
* Decorates this command to run repeatedly, restarting it when it ends, until
|
||||
* this command is interrupted. The decorated command can still be canceled.
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Repeatedly() &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run endlessly, ignoring its ordinary end
|
||||
* conditions. The decorated command can still be interrupted or canceled.
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Endlessly() &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run "by proxy" by wrapping it in a
|
||||
* ProxyScheduleCommand. This is useful for "forking off" from command groups
|
||||
* when the user does not wish to extend the command's requirements to the
|
||||
* entire command group.
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr AsProxy() &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run or stop when disabled.
|
||||
*
|
||||
* @param doesRunWhenDisabled true to run when disabled.
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr IgnoringDisable(bool doesRunWhenDisabled) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run or stop when disabled.
|
||||
*
|
||||
* @param interruptBehavior true to run when disabled.
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr WithInterruptBehavior(
|
||||
Command::InterruptionBehavior interruptBehavior) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a runnable to run after the command finishes.
|
||||
*
|
||||
* @param toRun the Runnable to run
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr AndThen(
|
||||
std::function<void()> toRun,
|
||||
wpi::span<Subsystem* const> requirements = {}) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a runnable to run after the command finishes.
|
||||
*
|
||||
* @param toRun the Runnable to run
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr AndThen(
|
||||
std::function<void()> toRun,
|
||||
std::initializer_list<Subsystem*> requirements) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a runnable to run before this command starts.
|
||||
*
|
||||
* @param toRun the Runnable to run
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr BeforeStarting(
|
||||
std::function<void()> toRun,
|
||||
std::initializer_list<Subsystem*> requirements) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a runnable to run before this command starts.
|
||||
*
|
||||
* @param toRun the Runnable to run
|
||||
* @param requirements the required subsystems
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr BeforeStarting(
|
||||
std::function<void()> toRun,
|
||||
wpi::span<Subsystem* const> requirements = {}) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a timeout. If the specified timeout is
|
||||
* exceeded before the command finishes normally, the command will be
|
||||
* interrupted and un-scheduled. Note that the timeout only applies to the
|
||||
* command returned by this method; the calling command is not itself changed.
|
||||
*
|
||||
* @param duration the timeout duration
|
||||
* @return the command with the timeout added
|
||||
*/
|
||||
[[nodiscard]] CommandPtr WithTimeout(units::second_t duration) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with an interrupt condition. If the specified
|
||||
* condition becomes true before the command finishes normally, the command
|
||||
* will be interrupted and un-scheduled. Note that this only applies to the
|
||||
* command returned by this method; the calling command is not itself changed.
|
||||
*
|
||||
* @param condition the interrupt condition
|
||||
* @return the command with the interrupt condition added
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Until(std::function<bool()> condition) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to only run if this condition is not met. If the
|
||||
* command is already running and the condition changes to true, the command
|
||||
* will not stop running. The requirements of this command will be kept for
|
||||
* the new conditonal command.
|
||||
*
|
||||
* @param condition the condition that will prevent the command from running
|
||||
* @return the decorated command
|
||||
*/
|
||||
[[nodiscard]] CommandPtr Unless(std::function<bool()> condition) &&;
|
||||
|
||||
/**
|
||||
* Get a raw pointer to the held command.
|
||||
*/
|
||||
Command* get() const;
|
||||
|
||||
/**
|
||||
* Schedules this command.
|
||||
*/
|
||||
void Schedule() const;
|
||||
|
||||
/**
|
||||
* Cancels this command. Will call End(true). Commands will be canceled
|
||||
* regardless of interruption behavior.
|
||||
*/
|
||||
void Cancel() const;
|
||||
|
||||
/**
|
||||
* Whether or not the command is currently scheduled. Note that this does not
|
||||
* detect whether the command is being run by a CommandGroup, only whether it
|
||||
* is directly being run by the scheduler.
|
||||
*
|
||||
* @return Whether the command is scheduled.
|
||||
*/
|
||||
bool IsScheduled() const;
|
||||
|
||||
/**
|
||||
* Whether the command requires a given subsystem. Named "HasRequirement"
|
||||
* rather than "requires" to avoid confusion with Command::Requires(Subsystem)
|
||||
* -- this may be able to be changed in a few years.
|
||||
*
|
||||
* @param requirement the subsystem to inquire about
|
||||
* @return whether the subsystem is required
|
||||
*/
|
||||
bool HasRequirement(Subsystem* requirement) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Command> m_ptr;
|
||||
};
|
||||
|
||||
} // namespace frc2
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
namespace frc2 {
|
||||
class Command;
|
||||
class CommandPtr;
|
||||
class Subsystem;
|
||||
|
||||
/**
|
||||
@@ -82,6 +83,17 @@ class CommandScheduler final : public nt::NTSendable,
|
||||
WPI_DEPRECATED("Call Clear on the EventLoop instance directly!")
|
||||
void ClearButtons();
|
||||
|
||||
/**
|
||||
* Schedules a command for execution. Does nothing if the command is already
|
||||
* scheduled. If a command's requirements are not available, it will only be
|
||||
* started if all the commands currently using those requirements are
|
||||
* interruptible. If this is the case, they will be interrupted and the
|
||||
* command will be scheduled.
|
||||
*
|
||||
* @param command the command to schedule
|
||||
*/
|
||||
void Schedule(const CommandPtr& command);
|
||||
|
||||
/**
|
||||
* Schedules a command for execution. Does nothing if the command is already
|
||||
* scheduled. If a command's requirements are not available, it will only be
|
||||
@@ -200,6 +212,18 @@ class CommandScheduler final : public nt::NTSendable,
|
||||
*/
|
||||
void Cancel(Command* command);
|
||||
|
||||
/**
|
||||
* Cancels commands. The scheduler will only call Command::End()
|
||||
* method of the canceled command with true, indicating they were
|
||||
* canceled (as opposed to finishing normally).
|
||||
*
|
||||
* <p>Commands will be canceled even if they are not scheduled as
|
||||
* interruptible.
|
||||
*
|
||||
* @param command the command to cancel
|
||||
*/
|
||||
void Cancel(const CommandPtr& command);
|
||||
|
||||
/**
|
||||
* Cancels commands. The scheduler will only call Command::End()
|
||||
* method of the canceled command with true, indicating they were
|
||||
@@ -259,6 +283,16 @@ class CommandScheduler final : public nt::NTSendable,
|
||||
*/
|
||||
bool IsScheduled(const Command* command) const;
|
||||
|
||||
/**
|
||||
* Whether a given command is running. Note that this only works on commands
|
||||
* that are directly scheduled by the scheduler; it will not work on commands
|
||||
* inside of CommandGroups, as the scheduler does not see them.
|
||||
*
|
||||
* @param command the command to query
|
||||
* @return whether the command is currently scheduled
|
||||
*/
|
||||
bool IsScheduled(const CommandPtr& command) const;
|
||||
|
||||
/**
|
||||
* Returns the command currently requiring a given subsystem. Null if no
|
||||
* command is currently requiring the subsystem
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <wpi/span.h>
|
||||
|
||||
#include "Trigger.h"
|
||||
#include "frc2/command/CommandPtr.h"
|
||||
|
||||
namespace frc2 {
|
||||
class Command;
|
||||
@@ -47,6 +48,16 @@ class Button : public Trigger {
|
||||
*/
|
||||
Button WhenPressed(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the button is pressed. Transfers
|
||||
* command ownership to the button scheduler, so the user does not have to
|
||||
* worry about lifespan.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The trigger, for chained calls.
|
||||
*/
|
||||
Button WhenPressed(CommandPtr&& command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the button is pressed. Transfers
|
||||
* command ownership to the button scheduler, so the user does not have to
|
||||
@@ -91,6 +102,16 @@ class Button : public Trigger {
|
||||
*/
|
||||
Button WhileHeld(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started repeatedly while the button is pressed, and
|
||||
* canceled when it is released. Transfers command ownership to the button
|
||||
* scheduler, so the user does not have to worry about lifespan.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The button, for chained calls.
|
||||
*/
|
||||
Button WhileHeld(CommandPtr&& command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started repeatedly while the button is pressed, and
|
||||
* canceled when it is released. Transfers command ownership to the button
|
||||
@@ -135,6 +156,16 @@ class Button : public Trigger {
|
||||
*/
|
||||
Button WhenHeld(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started when the button is pressed, and canceled
|
||||
* when it is released. Transfers command ownership to the button scheduler,
|
||||
* so the user does not have to worry about lifespan.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The button, for chained calls.
|
||||
*/
|
||||
Button WhenHeld(CommandPtr&& command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started when the button is pressed, and canceled
|
||||
* when it is released. Transfers command ownership to the button scheduler,
|
||||
@@ -161,6 +192,16 @@ class Button : public Trigger {
|
||||
*/
|
||||
Button WhenReleased(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the button is pressed. Transfers
|
||||
* command ownership to the button scheduler, so the user does not have to
|
||||
* worry about lifespan.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The button, for chained calls.
|
||||
*/
|
||||
Button WhenReleased(CommandPtr&& command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the button is pressed. Transfers
|
||||
* command ownership to the button scheduler, so the user does not have to
|
||||
@@ -205,6 +246,16 @@ class Button : public Trigger {
|
||||
*/
|
||||
Button ToggleWhenPressed(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the button is pressed, and be canceled when
|
||||
* it is pessed again. Transfers command ownership to the button scheduler,
|
||||
* so the user does not have to worry about lifespan.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The button, for chained calls.
|
||||
*/
|
||||
Button ToggleWhenPressed(CommandPtr&& command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the button is pressed, and be canceled when
|
||||
* it is pessed again. Transfers command ownership to the button scheduler,
|
||||
|
||||
@@ -69,6 +69,15 @@ class Trigger : public frc::BooleanEvent {
|
||||
*/
|
||||
Trigger WhenActive(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the trigger becomes active. Moves
|
||||
* command ownership to the button scheduler.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The trigger, for chained calls.
|
||||
*/
|
||||
Trigger WhenActive(CommandPtr&& 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
|
||||
@@ -116,6 +125,16 @@ class Trigger : public frc::BooleanEvent {
|
||||
*/
|
||||
Trigger WhileActiveContinous(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started repeatedly while the trigger is active, and
|
||||
* canceled when it becomes inactive. Moves command ownership to the button
|
||||
* scheduler.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The trigger, for chained calls.
|
||||
*/
|
||||
Trigger WhileActiveContinous(CommandPtr&& command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started repeatedly while the trigger is active, and
|
||||
* canceled when it becomes inactive. Transfers command ownership to the
|
||||
@@ -164,6 +183,16 @@ class Trigger : public frc::BooleanEvent {
|
||||
*/
|
||||
Trigger WhileActiveOnce(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started when the trigger becomes active, and
|
||||
* canceled when it becomes inactive. Moves command ownership to the button
|
||||
* scheduler.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The trigger, for chained calls.
|
||||
*/
|
||||
Trigger WhileActiveOnce(CommandPtr&& command);
|
||||
|
||||
/**
|
||||
* Binds a command to be started when the trigger becomes active, and
|
||||
* canceled when it becomes inactive. Transfers command ownership to the
|
||||
@@ -195,6 +224,15 @@ class Trigger : public frc::BooleanEvent {
|
||||
*/
|
||||
Trigger WhenInactive(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the trigger becomes inactive. Moves
|
||||
* command ownership to the button scheduler.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The trigger, for chained calls.
|
||||
*/
|
||||
Trigger WhenInactive(CommandPtr&& 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
|
||||
@@ -242,6 +280,16 @@ class Trigger : public frc::BooleanEvent {
|
||||
*/
|
||||
Trigger ToggleWhenActive(Command* command);
|
||||
|
||||
/**
|
||||
* Binds a command to start when the trigger becomes active, and be canceled
|
||||
* when it again becomes active. Moves command ownership to the button
|
||||
* scheduler.
|
||||
*
|
||||
* @param command The command to bind.
|
||||
* @return The trigger, for chained calls.
|
||||
*/
|
||||
Trigger ToggleWhenActive(CommandPtr&& 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
|
||||
|
||||
Reference in New Issue
Block a user