WPILibC++ 2023.4.3
Trigger.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <functional>
8#include <initializer_list>
9#include <memory>
10#include <span>
11#include <utility>
12
14#include <frc/event/EventLoop.h>
16#include <units/time.h>
17#include <wpi/deprecated.h>
18
21
22namespace frc2 {
23class Command;
24/**
25 * This class provides an easy way to link commands to conditions.
26 *
27 * <p>It is very easy to link a button to a command. For instance, you could
28 * link the trigger button of a joystick to a "score" command.
29 *
30 * <p>Triggers can easily be composed for advanced functionality using the
31 * {@link #operator!}, {@link #operator||}, {@link #operator&&} operators.
32 *
33 * <p>This class is provided by the NewCommands VendorDep
34 */
35class Trigger {
36 public:
37 /**
38 * Creates a new trigger based on the given condition.
39 *
40 * <p>Polled by the default scheduler button loop.
41 *
42 * @param condition the condition represented by this trigger
43 */
44 explicit Trigger(std::function<bool()> condition)
45 : Trigger{CommandScheduler::GetInstance().GetDefaultButtonLoop(),
46 std::move(condition)} {}
47
48 /**
49 * Creates a new trigger based on the given condition.
50 *
51 * @param loop The loop instance that polls this trigger.
52 * @param condition the condition represented by this trigger
53 */
54 Trigger(frc::EventLoop* loop, std::function<bool()> condition)
55 : m_loop{loop}, m_condition{std::move(condition)} {}
56
57 /**
58 * Create a new trigger that is always `false`.
59 */
60 Trigger() : Trigger([] { return false; }) {}
61
62 Trigger(const Trigger& other);
63
64 /**
65 * Starts the given command whenever the condition changes from `false` to
66 * `true`.
67 *
68 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
69 * lifespan of the command.
70 *
71 * @param command the command to start
72 * @return this trigger, so calls can be chained
73 */
75
76 /**
77 * Starts the given command whenever the condition changes from `false` to
78 * `true`. Moves command ownership to the button scheduler.
79 *
80 * @param command The command to bind.
81 * @return The trigger, for chained calls.
82 */
84
85 /**
86 * Starts the given command whenever the condition changes from `true` to
87 * `false`.
88 *
89 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
90 * lifespan of the command.
91 *
92 * @param command the command to start
93 * @return this trigger, so calls can be chained
94 */
96
97 /**
98 * Starts the given command whenever the condition changes from `true` to
99 * `false`.
100 *
101 * @param command The command to bind.
102 * @return The trigger, for chained calls.
103 */
105
106 /**
107 * Starts the given command when the condition changes to `true` and cancels
108 * it when the condition changes to `false`.
109 *
110 * <p>Doesn't re-start the command if it ends while the condition is still
111 * `true`. If the command should restart, see RepeatCommand.
112 *
113 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
114 * lifespan of the command.
115 *
116 * @param command the command to start
117 * @return this trigger, so calls can be chained
118 */
120
121 /**
122 * Starts the given command when the condition changes to `true` and cancels
123 * it when the condition changes to `false`. Moves command ownership to the
124 * button scheduler.
125 *
126 * <p>Doesn't re-start the command if it ends while the condition is still
127 * `true`. If the command should restart, see RepeatCommand.
128 *
129 * @param command The command to bind.
130 * @return The trigger, for chained calls.
131 */
133
134 /**
135 * Starts the given command when the condition changes to `false` and cancels
136 * it when the condition changes to `true`.
137 *
138 * <p>Doesn't re-start the command if it ends while the condition is still
139 * `true`. If the command should restart, see RepeatCommand.
140 *
141 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
142 * lifespan of the command.
143 *
144 * @param command the command to start
145 * @return this trigger, so calls can be chained
146 */
148
149 /**
150 * Starts the given command when the condition changes to `false` and cancels
151 * it when the condition changes to `true`. Moves command ownership to the
152 * button scheduler.
153 *
154 * <p>Doesn't re-start the command if it ends while the condition is still
155 * `false`. If the command should restart, see RepeatCommand.
156 *
157 * @param command The command to bind.
158 * @return The trigger, for chained calls.
159 */
161
162 /**
163 * Toggles a command when the condition changes from `false` to `true`.
164 *
165 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
166 * lifespan of the command.
167 *
168 * @param command the command to toggle
169 * @return this trigger, so calls can be chained
170 */
172
173 /**
174 * Toggles a command when the condition changes from `false` to `true`.
175 *
176 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
177 * lifespan of the command.
178 *
179 * @param command the command to toggle
180 * @return this trigger, so calls can be chained
181 */
183
184 /**
185 * Toggles a command when the condition changes from `true` to the low
186 * state.
187 *
188 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
189 * lifespan of the command.
190 *
191 * @param command the command to toggle
192 * @return this trigger, so calls can be chained
193 */
195
196 /**
197 * Toggles a command when the condition changes from `true` to `false`.
198 *
199 * <p>Takes a raw pointer, and so is non-owning; users are responsible for the
200 * lifespan of the command.
201 *
202 * @param command the command to toggle
203 * @return this trigger, so calls can be chained
204 */
206
207 /**
208 * Binds a command to start when the trigger becomes active. Takes a
209 * raw pointer, and so is non-owning; users are responsible for the lifespan
210 * of the command.
211 *
212 * @param command The command to bind.
213 * @return The trigger, for chained calls.
214 * @deprecated Use OnTrue(Command) instead
215 */
216 WPI_DEPRECATED("Use OnTrue(Command) instead")
218
219 /**
220 * Binds a command to start when the trigger becomes active. Transfers
221 * command ownership to the button scheduler, so the user does not have to
222 * worry about lifespan - rvalue refs will be *moved*, lvalue refs will be
223 * *copied.*
224 *
225 * @param command The command to bind.
226 * @return The trigger, for chained calls.
227 * @deprecated Use OnTrue(Command) instead
228 */
229 template <class T, typename = std::enable_if_t<std::is_base_of_v<
231 WPI_DEPRECATED("Use OnTrue(Command) instead")
232 Trigger WhenActive(T&& command) {
233 m_loop->Bind([condition = m_condition, previous = m_condition(),
234 command = std::make_unique<std::remove_reference_t<T>>(
235 std::forward<T>(command))]() mutable {
236 bool current = condition();
237
238 if (!previous && current) {
239 command->Schedule();
240 }
241
242 previous = current;
243 });
244 return *this;
245 }
246
247 /**
248 * Binds a runnable to execute when the trigger becomes active.
249 *
250 * @param toRun the runnable to execute.
251 * @param requirements the required subsystems.
252 * @deprecated Use OnTrue(Command) instead and construct the InstantCommand
253 * manually
254 */
255 WPI_DEPRECATED(
256 "Use OnTrue(Command) instead and construct the InstantCommand manually")
257 Trigger WhenActive(std::function<void()> toRun,
258 std::initializer_list<Subsystem*> requirements);
259
260 /**
261 * Binds a runnable to execute when the trigger becomes active.
262 *
263 * @param toRun the runnable to execute.
264 * @param requirements the required subsystems.
265 * @deprecated Use OnTrue(Command) instead and construct the InstantCommand
266 * manually
267 */
268 WPI_DEPRECATED(
269 "Use OnTrue(Command) instead and construct the InstantCommand manually")
270 Trigger WhenActive(std::function<void()> toRun,
271 std::span<Subsystem* const> requirements = {});
272
273 /**
274 * Binds a command to be started repeatedly while the trigger is active, and
275 * canceled when it becomes inactive. Takes a raw pointer, and so is
276 * non-owning; users are responsible for the lifespan of the command.
277 *
278 * @param command The command to bind.
279 * @return The trigger, for chained calls.
280 * @deprecated Use WhileTrue(Command) with RepeatCommand, or bind
281 command::Schedule with IfHigh(std::function<void()>).
282 */
283 WPI_DEPRECATED(
284 "Use WhileTrue(Command) with RepeatCommand, or bind command::Schedule "
285 "with IfHigh(std::function<void()>).")
287
288 /**
289 * Binds a command to be started repeatedly while the trigger is active, and
290 * canceled when it becomes inactive. Transfers command ownership to the
291 * button scheduler, so the user does not have to worry about lifespan -
292 * rvalue refs will be *moved*, lvalue refs will be *copied.*
293 *
294 * @param command The command to bind.
295 * @return The trigger, for chained calls.
296 * @deprecated Use WhileTrue(Command) with RepeatCommand, or bind
297 command::Schedule with IfHigh(std::function<void()>).
298 */
299 template <class T, typename = std::enable_if_t<std::is_base_of_v<
301 WPI_DEPRECATED(
302 "Use WhileTrue(Command) with RepeatCommand, or bind command::Schedule "
303 "with IfHigh(std::function<void()>).")
305 m_loop->Bind([condition = m_condition, previous = m_condition(),
306 command = std::make_unique<std::remove_reference_t<T>>(
307 std::forward<T>(command))]() mutable {
308 bool current = condition();
309
310 if (current) {
311 command->Schedule();
312 } else if (previous && !current) {
313 command->Cancel();
314 }
315
316 previous = current;
317 });
318
319 return *this;
320 }
321
322 /**
323 * Binds a runnable to execute repeatedly while the trigger is active.
324 *
325 * @param toRun the runnable to execute.
326 * @param requirements the required subsystems.
327 * @deprecated Use WhileTrue(Command) and construct a RunCommand manually
328 */
329 WPI_DEPRECATED("Use WhileTrue(Command) and construct a RunCommand manually")
330 Trigger WhileActiveContinous(std::function<void()> toRun,
331 std::initializer_list<Subsystem*> requirements);
332
333 /**
334 * Binds a runnable to execute repeatedly while the trigger is active.
335 *
336 * @param toRun the runnable to execute.
337 * @param requirements the required subsystems.
338 * @deprecated Use WhileTrue(Command) and construct a RunCommand manually
339 */
340 WPI_DEPRECATED("Use WhileTrue(Command) and construct a RunCommand manually")
341 Trigger WhileActiveContinous(std::function<void()> toRun,
342 std::span<Subsystem* const> requirements = {});
343
344 /**
345 * Binds a command to be started when the trigger becomes active, and
346 * canceled when it becomes inactive. Takes a raw pointer, and so is
347 * non-owning; users are responsible for the lifespan of the command.
348 *
349 * @param command The command to bind.
350 * @return The trigger, for chained calls.
351 * @deprecated Use WhileTrue(Command) instead.
352 */
353 WPI_DEPRECATED("Use WhileTrue(Command) instead.")
355
356 /**
357 * Binds a command to be started when the trigger becomes active, and
358 * canceled when it becomes inactive. Transfers command ownership to the
359 * button scheduler, so the user does not have to worry about lifespan -
360 * rvalue refs will be *moved*, lvalue refs will be *copied.*
361 *
362 * @param command The command to bind.
363 * @return The trigger, for chained calls.
364 * @deprecated Use WhileTrue(Command) instead.
365 */
366 template <class T, typename = std::enable_if_t<std::is_base_of_v<
368 WPI_DEPRECATED("Use WhileTrue(Command) instead.")
370 m_loop->Bind([condition = m_condition, previous = m_condition(),
371 command = std::make_unique<std::remove_reference_t<T>>(
372 std::forward<T>(command))]() mutable {
373 bool current = condition();
374
375 if (!previous && current) {
376 command->Schedule();
377 } else if (previous && !current) {
378 command->Cancel();
379 }
380
381 previous = current;
382 });
383 return *this;
384 }
385
386 /**
387 * Binds a command to start when the trigger becomes inactive. Takes a
388 * raw pointer, and so is non-owning; users are responsible for the lifespan
389 * of the command.
390 *
391 * @param command The command to bind.
392 * @return The trigger, for chained calls.
393 * @deprecated Use OnFalse(Command) instead.
394 */
395 WPI_DEPRECATED("Use OnFalse(Command) instead.")
397
398 /**
399 * Binds a command to start when the trigger becomes inactive. Transfers
400 * command ownership to the button scheduler, so the user does not have to
401 * worry about lifespan - rvalue refs will be *moved*, lvalue refs will be
402 * *copied.*
403 *
404 * @param command The command to bind.
405 * @return The trigger, for chained calls.
406 * @deprecated Use OnFalse(Command) instead.
407 */
408 template <class T, typename = std::enable_if_t<std::is_base_of_v<
410 WPI_DEPRECATED("Use OnFalse(Command) instead.")
411 Trigger WhenInactive(T&& command) {
412 m_loop->Bind([condition = m_condition, previous = m_condition(),
413 command = std::make_unique<std::remove_reference_t<T>>(
414 std::forward<T>(command))]() mutable {
415 bool current = condition();
416
417 if (previous && !current) {
418 command->Schedule();
419 }
420
421 previous = current;
422 });
423 return *this;
424 }
425
426 /**
427 * Binds a runnable to execute when the trigger becomes inactive.
428 *
429 * @param toRun the runnable to execute.
430 * @param requirements the required subsystems.
431 * @deprecated Use OnFalse(Command) instead and construct the InstantCommand
432 * manually
433 */
434 WPI_DEPRECATED(
435 "Use OnFalse(Command) instead and construct the InstantCommand manually")
436 Trigger WhenInactive(std::function<void()> toRun,
437 std::initializer_list<Subsystem*> requirements);
438
439 /**
440 * Binds a runnable to execute when the trigger becomes inactive.
441 *
442 * @param toRun the runnable to execute.
443 * @param requirements the required subsystems.
444 * @deprecated Use OnFalse(Command) instead and construct the InstantCommand
445 * manually
446 */
447 WPI_DEPRECATED(
448 "Use OnFalse(Command) instead and construct the InstantCommand manually")
449 Trigger WhenInactive(std::function<void()> toRun,
450 std::span<Subsystem* const> requirements = {});
451
452 /**
453 * Binds a command to start when the trigger becomes active, and be canceled
454 * when it again becomes active. Takes a raw pointer, and so is non-owning;
455 * users are responsible for the lifespan of the command.
456 *
457 * @param command The command to bind.
458 * @return The trigger, for chained calls.
459 * @deprecated Use ToggleOnTrue(Command) instead.
460 */
461 WPI_DEPRECATED("Use ToggleOnTrue(Command) instead.")
463
464 /**
465 * Binds a command to start when the trigger becomes active, and be canceled
466 * when it again becomes active. Transfers command ownership to the button
467 * scheduler, so the user does not have to worry about lifespan - rvalue refs
468 * will be *moved*, lvalue refs will be *copied.*
469 *
470 * @param command The command to bind.
471 * @return The trigger, for chained calls.
472 * @deprecated Use ToggleOnTrue(Command) instead.
473 */
474 template <class T, typename = std::enable_if_t<std::is_base_of_v<
476 WPI_DEPRECATED("Use ToggleOnTrue(Command) instead.")
478 m_loop->Bind([condition = m_condition, previous = m_condition(),
479 command = std::make_unique<std::remove_reference_t<T>>(
480 std::forward<T>(command))]() mutable {
481 bool current = condition();
482
483 if (!previous && current) {
484 if (command->IsScheduled()) {
485 command->Cancel();
486 } else {
487 command->Schedule();
488 }
489 }
490
491 previous = current;
492 });
493
494 return *this;
495 }
496
497 /**
498 * Binds a command to be canceled when the trigger becomes active. Takes a
499 * raw pointer, and so is non-owning; users are responsible for the lifespan
500 * and scheduling of the command.
501 *
502 * @param command The command to bind.
503 * @return The trigger, for chained calls.
504 * @deprecated Pass this as a command end condition with Until() instead.
505 */
506 WPI_DEPRECATED("Pass this as a command end condition with Until() instead.")
508
509 /**
510 * Composes two triggers with logical AND.
511 *
512 * @return A trigger which is active when both component triggers are active.
513 */
514 Trigger operator&&(std::function<bool()> rhs) {
515 return Trigger(m_loop, [condition = m_condition, rhs = std::move(rhs)] {
516 return condition() && rhs();
517 });
518 }
519
520 /**
521 * Composes two triggers with logical AND.
522 *
523 * @return A trigger which is active when both component triggers are active.
524 */
526 return Trigger(m_loop, [condition = m_condition, rhs] {
527 return condition() && rhs.m_condition();
528 });
529 }
530
531 /**
532 * Composes two triggers with logical OR.
533 *
534 * @return A trigger which is active when either component trigger is active.
535 */
536 Trigger operator||(std::function<bool()> rhs) {
537 return Trigger(m_loop, [condition = m_condition, rhs = std::move(rhs)] {
538 return condition() || rhs();
539 });
540 }
541
542 /**
543 * Composes two triggers with logical OR.
544 *
545 * @return A trigger which is active when either component trigger is active.
546 */
548 return Trigger(m_loop, [condition = m_condition, rhs] {
549 return condition() || rhs.m_condition();
550 });
551 }
552
553 /**
554 * Composes a trigger with logical NOT.
555 *
556 * @return A trigger which is active when the component trigger is inactive,
557 * and vice-versa.
558 */
560 return Trigger(m_loop, [condition = m_condition] { return !condition(); });
561 }
562
563 /**
564 * Creates a new debounced trigger from this trigger - it will become active
565 * when this trigger has been active for longer than the specified period.
566 *
567 * @param debounceTime The debounce period.
568 * @param type The debounce type.
569 * @return The debounced trigger.
570 */
571 Trigger Debounce(units::second_t debounceTime,
573 frc::Debouncer::DebounceType::kRising);
574
575 private:
576 frc::EventLoop* m_loop;
577 std::function<bool()> m_condition;
578};
579} // namespace frc2
and(b) You must cause any modified files to carry prominent notices stating that You changed the files
or
Definition: ThirdPartyNotices.txt:199
A state machine representing a complete action to be performed by the robot.
Definition: Command.h:47
A wrapper around std::unique_ptr<Command> so commands have move-only semantics.
Definition: CommandPtr.h:28
The scheduler responsible for running Commands.
Definition: CommandScheduler.h:36
A Command that runs instantly; it will initialize, execute once, and end on the same iteration of the...
Definition: InstantCommand.h:22
A command that runs another command repeatedly, restarting it when it ends, until this command is int...
Definition: RepeatCommand.h:31
A command that runs a Runnable continuously.
Definition: RunCommand.h:23
A robot subsystem.
Definition: Subsystem.h:39
This class provides an easy way to link commands to conditions.
Definition: Trigger.h:35
Trigger OnFalse(CommandPtr &&command)
Starts the given command whenever the condition changes from true to false.
Trigger()
Create a new trigger that is always false.
Definition: Trigger.h:60
Trigger CancelWhenActive(Command *command)
Binds a command to be canceled when the trigger becomes active.
Trigger WhileTrue(CommandPtr &&command)
Starts the given command when the condition changes to true and cancels it when the condition changes...
Trigger operator!()
Composes a trigger with logical NOT.
Definition: Trigger.h:559
Trigger WhenInactive(Command *command)
Binds a command to start when the trigger becomes inactive.
Trigger WhileFalse(Command *command)
Starts the given command when the condition changes to false and cancels it when the condition change...
Trigger OnFalse(Command *command)
Starts the given command whenever the condition changes from true to false.
Trigger operator&&(Trigger rhs)
Composes two triggers with logical AND.
Definition: Trigger.h:525
Trigger ToggleWhenActive(Command *command)
Binds a command to start when the trigger becomes active, and be canceled when it again becomes activ...
Trigger Debounce(units::second_t debounceTime, frc::Debouncer::DebounceType type=frc::Debouncer::DebounceType::kRising)
Creates a new debounced trigger from this trigger - it will become active when this trigger has been ...
Trigger OnTrue(CommandPtr &&command)
Starts the given command whenever the condition changes from false to true.
Trigger OnTrue(Command *command)
Starts the given command whenever the condition changes from false to true.
Trigger WhileActiveContinous(Command *command)
Binds a command to be started repeatedly while the trigger is active, and canceled when it becomes in...
Trigger WhileFalse(CommandPtr &&command)
Starts the given command when the condition changes to false and cancels it when the condition change...
Trigger(const Trigger &other)
Trigger ToggleOnTrue(Command *command)
Toggles a command when the condition changes from false to true.
Trigger operator||(Trigger rhs)
Composes two triggers with logical OR.
Definition: Trigger.h:547
Trigger operator||(std::function< bool()> rhs)
Composes two triggers with logical OR.
Definition: Trigger.h:536
Trigger WhenActive(Command *command)
Binds a command to start when the trigger becomes active.
Trigger ToggleOnFalse(CommandPtr &&command)
Toggles a command when the condition changes from true to false.
Trigger WhileTrue(Command *command)
Starts the given command when the condition changes to true and cancels it when the condition changes...
Trigger ToggleOnTrue(CommandPtr &&command)
Toggles a command when the condition changes from false to true.
Trigger(frc::EventLoop *loop, std::function< bool()> condition)
Creates a new trigger based on the given condition.
Definition: Trigger.h:54
Trigger WhileActiveOnce(Command *command)
Binds a command to be started when the trigger becomes active, and canceled when it becomes inactive.
Trigger(std::function< bool()> condition)
Creates a new trigger based on the given condition.
Definition: Trigger.h:44
Trigger ToggleOnFalse(Command *command)
Toggles a command when the condition changes from true to the low state.
DebounceType
Definition: Debouncer.h:20
The loop polling BooleanEvent objects and executing the actions bound to them.
Definition: EventLoop.h:15
void Bind(wpi::unique_function< void()> action)
Bind a new action to run.
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:298
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:303
type
Definition: core.h:575
Definition: InstantCommand.h:14
Definition: StdDeque.h:50