mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-06 03:31:43 +00:00
[wpilib] Synchronize C++ and Java versions of BooleanEvent (#6776)
This commit is contained in:
committed by
GitHub
parent
8d857cdb78
commit
45823abe86
@@ -7,21 +7,21 @@
|
||||
using namespace frc;
|
||||
|
||||
BooleanEvent::BooleanEvent(EventLoop* loop, std::function<bool()> condition)
|
||||
: m_loop(loop), m_condition(std::move(condition)) {
|
||||
m_state = std::make_shared<bool>(m_condition());
|
||||
: m_loop(loop), m_signal(std::move(condition)) {
|
||||
m_state = std::make_shared<bool>(m_signal());
|
||||
m_loop->Bind(
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
[condition = m_condition, state = m_state] { *state = condition(); });
|
||||
}
|
||||
|
||||
BooleanEvent::operator std::function<bool()>() {
|
||||
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<bool()>() {
|
||||
return [state = m_state] { return *state; };
|
||||
}
|
||||
|
||||
void BooleanEvent::IfHigh(std::function<void()> action) {
|
||||
m_loop->Bind([state = m_state, action = std::move(action)] {
|
||||
if (*state) {
|
||||
|
||||
@@ -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<void()>)}.
|
||||
* 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<void()>)}.
|
||||
*
|
||||
* <p>These events can easily be composed using factories such as {@link
|
||||
* #operator!},
|
||||
* {@link #operator||}, {@link #operator&&} etc.
|
||||
* <p>BooleanEvents can easily be composed for advanced functionality using
|
||||
* {@link #operator&&}, {@link #operator||}, and {@link #operator!}.
|
||||
*
|
||||
* <p>To get an event that activates only when this one changes, see {@link
|
||||
* <p>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<bool()> condition);
|
||||
BooleanEvent(EventLoop* loop, std::function<bool()> 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<bool()>(); // NOLINT
|
||||
|
||||
/**
|
||||
* Bind an action to this event.
|
||||
*
|
||||
@@ -54,8 +54,6 @@ class BooleanEvent {
|
||||
*/
|
||||
void IfHigh(std::function<void()> action);
|
||||
|
||||
operator std::function<bool()>(); // 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<bool()> 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<bool()> m_condition;
|
||||
std::function<bool()> m_signal;
|
||||
std::shared_ptr<bool> m_state; // A programmer's worst nightmare.
|
||||
};
|
||||
} // namespace frc
|
||||
|
||||
@@ -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)}.
|
||||
*
|
||||
* <p>These signals can easily be composed for advanced functionality using {@link
|
||||
* #and(BooleanSupplier)}, {@link #or(BooleanSupplier)}, {@link #negate()} etc.
|
||||
* <p>BooleanEvents can easily be composed for advanced functionality using {@link
|
||||
* #and(BooleanSupplier)}, {@link #or(BooleanSupplier)}, and {@link #negate()}.
|
||||
*
|
||||
* <p>To get an event that activates only when this one changes, see {@link #falling()} and {@link
|
||||
* #rising()}.
|
||||
* <p>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 <T> the subclass type
|
||||
* @return an instance of the subclass.
|
||||
*/
|
||||
public <T extends BooleanSupplier> T castTo(BiFunction<EventLoop, BooleanSupplier, T> 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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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 <T> the subclass type
|
||||
* @return an instance of the subclass.
|
||||
*/
|
||||
public <T extends BooleanSupplier> T castTo(BiFunction<EventLoop, BooleanSupplier, T> ctor) {
|
||||
return ctor.apply(m_loop, m_state::get);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user