diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/Trigger.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/Trigger.java index d7b1dd08937..8dc3ae52b3d 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/Trigger.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/button/Trigger.java @@ -24,6 +24,18 @@ *

This class is provided by the NewCommands VendorDep */ public class Trigger implements BooleanSupplier { + /** Functional interface for the body of a trigger binding. */ + @FunctionalInterface + private interface BindingBody { + /** + * Executes the body of the binding. + * + * @param previous The previous state of the condition. + * @param current The current state of the condition. + */ + void run(boolean previous, boolean current); + } + private final BooleanSupplier m_condition; private final EventLoop m_loop; @@ -50,26 +62,38 @@ public Trigger(BooleanSupplier condition) { } /** - * Starts the command when the condition changes. + * Adds a binding to the EventLoop. * - * @param command the command to start - * @return this trigger, so calls can be chained + * @param body The body of the binding to add. */ - public Trigger onChange(Command command) { - requireNonNullParam(command, "command", "onChange"); + private void addBinding(BindingBody body) { m_loop.bind( new Runnable() { - private boolean m_pressedLast = m_condition.getAsBoolean(); + private boolean m_previous = m_condition.getAsBoolean(); @Override public void run() { - boolean pressed = m_condition.getAsBoolean(); + boolean current = m_condition.getAsBoolean(); - if (m_pressedLast != pressed) { - command.schedule(); - } + body.run(m_previous, current); - m_pressedLast = pressed; + m_previous = current; + } + }); + } + + /** + * Starts the command when the condition changes. + * + * @param command the command to start + * @return this trigger, so calls can be chained + */ + public Trigger onChange(Command command) { + requireNonNullParam(command, "command", "onChange"); + addBinding( + (previous, current) -> { + if (previous != current) { + command.schedule(); } }); return this; @@ -83,19 +107,10 @@ public void run() { */ public Trigger onTrue(Command command) { requireNonNullParam(command, "command", "onTrue"); - m_loop.bind( - new Runnable() { - private boolean m_pressedLast = m_condition.getAsBoolean(); - - @Override - public void run() { - boolean pressed = m_condition.getAsBoolean(); - - if (!m_pressedLast && pressed) { - command.schedule(); - } - - m_pressedLast = pressed; + addBinding( + (previous, current) -> { + if (!previous && current) { + command.schedule(); } }); return this; @@ -109,19 +124,10 @@ public void run() { */ public Trigger onFalse(Command command) { requireNonNullParam(command, "command", "onFalse"); - m_loop.bind( - new Runnable() { - private boolean m_pressedLast = m_condition.getAsBoolean(); - - @Override - public void run() { - boolean pressed = m_condition.getAsBoolean(); - - if (m_pressedLast && !pressed) { - command.schedule(); - } - - m_pressedLast = pressed; + addBinding( + (previous, current) -> { + if (previous && !current) { + command.schedule(); } }); return this; @@ -139,21 +145,12 @@ public void run() { */ public Trigger whileTrue(Command command) { requireNonNullParam(command, "command", "whileTrue"); - m_loop.bind( - new Runnable() { - private boolean m_pressedLast = m_condition.getAsBoolean(); - - @Override - public void run() { - boolean pressed = m_condition.getAsBoolean(); - - if (!m_pressedLast && pressed) { - command.schedule(); - } else if (m_pressedLast && !pressed) { - command.cancel(); - } - - m_pressedLast = pressed; + addBinding( + (previous, current) -> { + if (!previous && current) { + command.schedule(); + } else if (previous && !current) { + command.cancel(); } }); return this; @@ -171,21 +168,12 @@ public void run() { */ public Trigger whileFalse(Command command) { requireNonNullParam(command, "command", "whileFalse"); - m_loop.bind( - new Runnable() { - private boolean m_pressedLast = m_condition.getAsBoolean(); - - @Override - public void run() { - boolean pressed = m_condition.getAsBoolean(); - - if (m_pressedLast && !pressed) { - command.schedule(); - } else if (!m_pressedLast && pressed) { - command.cancel(); - } - - m_pressedLast = pressed; + addBinding( + (previous, current) -> { + if (previous && !current) { + command.schedule(); + } else if (!previous && current) { + command.cancel(); } }); return this; @@ -199,23 +187,14 @@ public void run() { */ public Trigger toggleOnTrue(Command command) { requireNonNullParam(command, "command", "toggleOnTrue"); - m_loop.bind( - new Runnable() { - private boolean m_pressedLast = m_condition.getAsBoolean(); - - @Override - public void run() { - boolean pressed = m_condition.getAsBoolean(); - - if (!m_pressedLast && pressed) { - if (command.isScheduled()) { - command.cancel(); - } else { - command.schedule(); - } + addBinding( + (previous, current) -> { + if (!previous && current) { + if (command.isScheduled()) { + command.cancel(); + } else { + command.schedule(); } - - m_pressedLast = pressed; } }); return this; @@ -229,23 +208,14 @@ public void run() { */ public Trigger toggleOnFalse(Command command) { requireNonNullParam(command, "command", "toggleOnFalse"); - m_loop.bind( - new Runnable() { - private boolean m_pressedLast = m_condition.getAsBoolean(); - - @Override - public void run() { - boolean pressed = m_condition.getAsBoolean(); - - if (m_pressedLast && !pressed) { - if (command.isScheduled()) { - command.cancel(); - } else { - command.schedule(); - } + addBinding( + (previous, current) -> { + if (previous && !current) { + if (command.isScheduled()) { + command.cancel(); + } else { + command.schedule(); } - - m_pressedLast = pressed; } }); return this; diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/button/Trigger.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/button/Trigger.cpp index a3b02d18f3a..00f179da084 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/button/Trigger.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/button/Trigger.cpp @@ -15,159 +15,117 @@ using namespace frc2; Trigger::Trigger(const Trigger& other) = default; -Trigger Trigger::OnChange(Command* command) { - m_loop->Bind( - [condition = m_condition, previous = m_condition(), command]() mutable { - bool current = condition(); +void Trigger::AddBinding(wpi::unique_function&& body) { + m_loop->Bind([condition = m_condition, previous = m_condition(), + body = std::move(body)]() mutable { + bool current = condition(); - if (previous != current) { - command->Schedule(); - } + body(previous, current); + + previous = current; + }); +} - previous = current; - }); +Trigger Trigger::OnChange(Command* command) { + AddBinding([command](bool previous, bool current) { + if (previous != current) { + command->Schedule(); + } + }); return *this; } Trigger Trigger::OnChange(CommandPtr&& command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::move(command)]() mutable { - bool current = condition(); - + AddBinding([command = std::move(command)](bool previous, bool current) { if (previous != current) { command.Schedule(); } - - previous = current; }); return *this; } Trigger Trigger::OnTrue(Command* command) { - m_loop->Bind( - [condition = m_condition, previous = m_condition(), command]() mutable { - bool current = condition(); - - if (!previous && current) { - command->Schedule(); - } - - previous = current; - }); + AddBinding([command](bool previous, bool current) { + if (!previous && current) { + command->Schedule(); + } + }); return *this; } Trigger Trigger::OnTrue(CommandPtr&& command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::move(command)]() mutable { - bool current = condition(); - + AddBinding([command = std::move(command)](bool previous, bool current) { if (!previous && current) { command.Schedule(); } - - previous = current; }); return *this; } Trigger Trigger::OnFalse(Command* command) { - m_loop->Bind( - [condition = m_condition, previous = m_condition(), command]() mutable { - bool current = condition(); - - if (previous && !current) { - command->Schedule(); - } - - previous = current; - }); + AddBinding([command](bool previous, bool current) { + if (previous && !current) { + command->Schedule(); + } + }); return *this; } Trigger Trigger::OnFalse(CommandPtr&& command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::move(command)]() mutable { - bool current = condition(); - + AddBinding([command = std::move(command)](bool previous, bool current) { if (previous && !current) { command.Schedule(); } - - previous = current; }); return *this; } Trigger Trigger::WhileTrue(Command* command) { - m_loop->Bind( - [condition = m_condition, previous = m_condition(), command]() mutable { - bool current = condition(); - - if (!previous && current) { - command->Schedule(); - } else if (previous && !current) { - command->Cancel(); - } - - previous = current; - }); + AddBinding([command](bool previous, bool current) { + if (!previous && current) { + command->Schedule(); + } else if (previous && !current) { + command->Cancel(); + } + }); return *this; } Trigger Trigger::WhileTrue(CommandPtr&& command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::move(command)]() mutable { - bool current = condition(); - + AddBinding([command = std::move(command)](bool previous, bool current) { if (!previous && current) { command.Schedule(); } else if (previous && !current) { command.Cancel(); } - - previous = current; }); return *this; } Trigger Trigger::WhileFalse(Command* command) { - m_loop->Bind( - [condition = m_condition, previous = m_condition(), command]() mutable { - bool current = condition(); - - if (previous && !current) { - command->Schedule(); - } else if (!previous && current) { - command->Cancel(); - } - - previous = current; - }); + AddBinding([command](bool previous, bool current) { + if (previous && !current) { + command->Schedule(); + } else if (!previous && current) { + command->Cancel(); + } + }); return *this; } Trigger Trigger::WhileFalse(CommandPtr&& command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::move(command)]() mutable { - bool current = condition(); - + AddBinding([command = std::move(command)](bool previous, bool current) { if (!previous && current) { command.Schedule(); } else if (previous && !current) { command.Cancel(); } - - previous = current; }); return *this; } Trigger Trigger::ToggleOnTrue(Command* command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = command]() mutable { - bool current = condition(); - + AddBinding([command](bool previous, bool current) { if (!previous && current) { if (command->IsScheduled()) { command->Cancel(); @@ -175,17 +133,12 @@ Trigger Trigger::ToggleOnTrue(Command* command) { command->Schedule(); } } - - previous = current; }); return *this; } Trigger Trigger::ToggleOnTrue(CommandPtr&& command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::move(command)]() mutable { - bool current = condition(); - + AddBinding([command = std::move(command)](bool previous, bool current) { if (!previous && current) { if (command.IsScheduled()) { command.Cancel(); @@ -193,17 +146,12 @@ Trigger Trigger::ToggleOnTrue(CommandPtr&& command) { command.Schedule(); } } - - previous = current; }); return *this; } Trigger Trigger::ToggleOnFalse(Command* command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = command]() mutable { - bool current = condition(); - + AddBinding([command](bool previous, bool current) { if (previous && !current) { if (command->IsScheduled()) { command->Cancel(); @@ -211,17 +159,12 @@ Trigger Trigger::ToggleOnFalse(Command* command) { command->Schedule(); } } - - previous = current; }); return *this; } Trigger Trigger::ToggleOnFalse(CommandPtr&& command) { - m_loop->Bind([condition = m_condition, previous = m_condition(), - command = std::move(command)]() mutable { - bool current = condition(); - + AddBinding([command = std::move(command)](bool previous, bool current) { if (previous && !current) { if (command.IsScheduled()) { command.Cancel(); @@ -229,8 +172,6 @@ Trigger Trigger::ToggleOnFalse(CommandPtr&& command) { command.Schedule(); } } - - previous = current; }); return *this; } diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h b/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h index a2382631334..9e86b1b7004 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/button/Trigger.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "frc2/command/Command.h" #include "frc2/command/CommandScheduler.h" @@ -291,6 +292,13 @@ class Trigger { bool Get() const; private: + /** + * Adds a binding to the EventLoop. + * + * @param body The body of the binding to add. + */ + void AddBinding(wpi::unique_function&& body); + frc::EventLoop* m_loop; std::function m_condition; };