diff --git a/wpilibc/src/main/native/cpp/event/BooleanEvent.cpp b/wpilibc/src/main/native/cpp/event/BooleanEvent.cpp index fd9c831fe9..0f6cdfe22c 100644 --- a/wpilibc/src/main/native/cpp/event/BooleanEvent.cpp +++ b/wpilibc/src/main/native/cpp/event/BooleanEvent.cpp @@ -7,21 +7,21 @@ using namespace frc; BooleanEvent::BooleanEvent(EventLoop* loop, std::function condition) - : m_loop(loop), m_condition(std::move(condition)) { - m_state = std::make_shared(m_condition()); + : m_loop(loop), m_signal(std::move(condition)) { + m_state = std::make_shared(m_signal()); m_loop->Bind( // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - [condition = m_condition, state = m_state] { *state = condition(); }); -} - -BooleanEvent::operator std::function() { - return [state = m_state] { return *state; }; + [condition = m_signal, state = m_state] { *state = condition(); }); } bool BooleanEvent::GetAsBoolean() const { return *m_state; } +BooleanEvent::operator std::function() { + return [state = m_state] { return *state; }; +} + void BooleanEvent::IfHigh(std::function action) { m_loop->Bind([state = m_state, action = std::move(action)] { if (*state) { diff --git a/wpilibc/src/main/native/include/frc/event/BooleanEvent.h b/wpilibc/src/main/native/include/frc/event/BooleanEvent.h index 7c19c90e8b..e06a931988 100644 --- a/wpilibc/src/main/native/include/frc/event/BooleanEvent.h +++ b/wpilibc/src/main/native/include/frc/event/BooleanEvent.h @@ -17,36 +17,36 @@ namespace frc { /** - * This class provides an easy way to link actions to inputs. Each object - * represents a boolean condition to which callback actions can be bound using - * {@link #IfHigh(std::function)}. + * This class provides an easy way to link actions to active high logic signals. + * Each object represents a digital signal to which callback actions can be + * bound using {@link #IfHigh(std::function)}. * - *

These events can easily be composed using factories such as {@link - * #operator!}, - * {@link #operator||}, {@link #operator&&} etc. + *

BooleanEvents can easily be composed for advanced functionality using + * {@link #operator&&}, {@link #operator||}, and {@link #operator!}. * - *

To get an event that activates only when this one changes, see {@link + *

To get a new BooleanEvent that triggers when this one changes see {@link * #Falling()} and {@link #Rising()}. */ class BooleanEvent { public: /** - * Creates a new event with the given condition determining whether it is - * active. + * Creates a new event that is active when the condition is true. * * @param loop the loop that polls this event - * @param condition returns whether or not the event should be active + * @param signal the digital signal represented by this object. */ - BooleanEvent(EventLoop* loop, std::function condition); + BooleanEvent(EventLoop* loop, std::function signal); /** - * Check whether this event is active or not as of the last loop poll. + * Returns the state of this signal (high or low) as of the last loop poll. * - * @return true if active, false if not active. If the event was never polled, - * it returns the state at event construction. + * @return true for the high state, false for the low state. If the event was + * never polled, it returns the state at event construction. */ bool GetAsBoolean() const; + operator std::function(); // NOLINT + /** * Bind an action to this event. * @@ -54,8 +54,6 @@ class BooleanEvent { */ void IfHigh(std::function action); - operator std::function(); // NOLINT - /** * A method to "downcast" a BooleanEvent instance to a subclass (for example, * to a command-based version of this class). @@ -74,8 +72,7 @@ class BooleanEvent { } /** - * Creates a new event that is active when this event is inactive, i.e. that - * acts as the negation of this event. + * Creates a new event that is active when this event is inactive. * * @return the negated event */ @@ -106,16 +103,16 @@ class BooleanEvent { BooleanEvent operator||(std::function rhs); /** - * Get a new event that events only when this one newly changes to true. + * Creates a new event that triggers when this one changes from false to true. * - * @return a new event representing when this one newly changes to true. + * @return the new event. */ BooleanEvent Rising(); /** - * Get a new event that triggers only when this one newly changes to false. + * Creates a new event that triggers when this one changes from true to false. * - * @return a new event representing when this one newly changes to false. + * @return the event. */ BooleanEvent Falling(); @@ -133,7 +130,7 @@ class BooleanEvent { private: EventLoop* m_loop; - std::function m_condition; + std::function m_signal; std::shared_ptr m_state; // A programmer's worst nightmare. }; } // namespace frc diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/BooleanEvent.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/BooleanEvent.java index c8f58461c2..53d5d62153 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/BooleanEvent.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/BooleanEvent.java @@ -12,30 +12,29 @@ import java.util.function.BiFunction; import java.util.function.BooleanSupplier; /** - * This class provides an easy way to link actions to high-active logic signals. Each object + * This class provides an easy way to link actions to active high logic signals. Each object * represents a digital signal to which callback actions can be bound using {@link * #ifHigh(Runnable)}. * - *

These signals can easily be composed for advanced functionality using {@link - * #and(BooleanSupplier)}, {@link #or(BooleanSupplier)}, {@link #negate()} etc. + *

BooleanEvents can easily be composed for advanced functionality using {@link + * #and(BooleanSupplier)}, {@link #or(BooleanSupplier)}, and {@link #negate()}. * - *

To get an event that activates only when this one changes, see {@link #falling()} and {@link - * #rising()}. + *

To get a new BooleanEvent that triggers when this one changes see {@link #falling()} and + * {@link #rising()}. */ public class BooleanEvent implements BooleanSupplier { /** Poller loop. */ protected final EventLoop m_loop; - /** Condition. */ private final BooleanSupplier m_signal; /** The state of the condition in the current loop poll. Nightmare to manage. */ private final AtomicBoolean m_state = new AtomicBoolean(false); /** - * Creates a new event with the given signal determining whether it is active. + * Creates a new event that is active when the condition is true. * - * @param loop the loop that polls this event + * @param loop the loop that polls this event. * @param signal the digital signal represented by this object. */ public BooleanEvent(EventLoop loop, BooleanSupplier signal) { @@ -46,7 +45,7 @@ public class BooleanEvent implements BooleanSupplier { } /** - * Check the state of this signal (high or low) as of the last loop poll. + * Returns the state of this signal (high or low) as of the last loop poll. * * @return true for the high state, false for the low state. If the event was never polled, it * returns the state at event construction. @@ -71,9 +70,61 @@ public class BooleanEvent implements BooleanSupplier { } /** - * Get a new event that events only when this one newly changes to true. + * A method to "downcast" a BooleanEvent instance to a subclass (for example, to a command-based + * version of this class). * - * @return a new event representing when this one newly changes to true. + * @param ctor a method reference to the constructor of the subclass that accepts the loop as the + * first parameter and the condition/signal as the second. + * @param the subclass type + * @return an instance of the subclass. + */ + public T castTo(BiFunction ctor) { + return ctor.apply(m_loop, m_state::get); + } + + /** + * Creates a new event that is active when this event is inactive. + * + * @return the new event. + */ + public BooleanEvent negate() { + return new BooleanEvent(m_loop, () -> !m_state.get()); + } + + /** + * Composes this event with another event, returning a new event that is active when both events + * are active. + * + *

The events must use the same event loop. If the events use different event loops, the + * composed signal won't update until both loops are polled. + * + * @param other the event to compose with. + * @return the new event. + */ + public BooleanEvent and(BooleanSupplier other) { + requireNonNullParam(other, "other", "and"); + return new BooleanEvent(m_loop, () -> m_state.get() && other.getAsBoolean()); + } + + /** + * Composes this event with another event, returning a new event that is active when either event + * is active. + * + *

The events must use the same event loop. If the events use different event loops, the + * composed signal won't update until both loops are polled. + * + * @param other the event to compose with. + * @return the new event. + */ + public BooleanEvent or(BooleanSupplier other) { + requireNonNullParam(other, "other", "or"); + return new BooleanEvent(m_loop, () -> m_state.get() || other.getAsBoolean()); + } + + /** + * Creates a new event that triggers when this one changes from false to true. + * + * @return the new event. */ public BooleanEvent rising() { return new BooleanEvent( @@ -92,9 +143,9 @@ public class BooleanEvent implements BooleanSupplier { } /** - * Get a new event that triggers only when this one newly changes to false. + * Creates a new event that triggers when this one changes from true to false. * - * @return a new event representing when this one newly changes to false. + * @return the event. */ public BooleanEvent falling() { return new BooleanEvent( @@ -117,7 +168,7 @@ public class BooleanEvent implements BooleanSupplier { * active for longer than the specified period. * * @param seconds The debounce period. - * @return The debounced event (rising edges debounced only) + * @return The debounced event (rising edges debounced only). */ public BooleanEvent debounce(double seconds) { return debounce(seconds, Debouncer.DebounceType.kRising); @@ -143,57 +194,4 @@ public class BooleanEvent implements BooleanSupplier { } }); } - - /** - * Creates a new event that is active when this event is inactive, i.e. that acts as the negation - * of this event. - * - * @return the negated event - */ - public BooleanEvent negate() { - return new BooleanEvent(m_loop, () -> !m_state.get()); - } - - /** - * Composes this event with another event, returning a new signal that is in the high state when - * both signals are in the high state. - * - *

The events must use the same event loop. If the events use different event loops, the - * composed signal won't update until both loops are polled. - * - * @param other the event to compose with - * @return the event that is active when both events are active - */ - public BooleanEvent and(BooleanSupplier other) { - requireNonNullParam(other, "other", "and"); - return new BooleanEvent(m_loop, () -> m_state.get() && other.getAsBoolean()); - } - - /** - * Composes this event with another event, returning a new signal that is high when either signal - * is high. - * - *

The events must use the same event loop. If the events use different event loops, the - * composed signal won't update until both loops are polled. - * - * @param other the event to compose with - * @return a signal that is high when either signal is high. - */ - public BooleanEvent or(BooleanSupplier other) { - requireNonNullParam(other, "other", "or"); - return new BooleanEvent(m_loop, () -> m_state.get() || other.getAsBoolean()); - } - - /** - * A method to "downcast" a BooleanEvent instance to a subclass (for example, to a command-based - * version of this class). - * - * @param ctor a method reference to the constructor of the subclass that accepts the loop as the - * first parameter and the condition/signal as the second. - * @param the subclass type - * @return an instance of the subclass. - */ - public T castTo(BiFunction ctor) { - return ctor.apply(m_loop, m_state::get); - } }