WPILibC++  2020.3.2
Trigger.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2019-2020 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #pragma once
9 
10 #include <functional>
11 #include <initializer_list>
12 #include <memory>
13 #include <utility>
14 
15 #include <wpi/ArrayRef.h>
16 
17 #include "frc2/command/Command.h"
18 #include "frc2/command/CommandScheduler.h"
19 
20 namespace frc2 {
21 class Command;
30 class Trigger {
31  public:
37  explicit Trigger(std::function<bool()> isActive)
38  : m_isActive{std::move(isActive)} {}
39 
44  Trigger() {
45  m_isActive = [] { return false; };
46  }
47 
48  Trigger(const Trigger& other);
49 
59  Trigger WhenActive(Command* command, bool interruptible = true);
60 
71  template <class T, typename = std::enable_if_t<std::is_base_of_v<
72  Command, std::remove_reference_t<T>>>>
73  Trigger WhenActive(T&& command, bool interruptible = true) {
75  [pressedLast = m_isActive(), *this,
76  command = std::make_unique<std::remove_reference_t<T>>(
77  std::forward<T>(command)),
78  interruptible]() mutable {
79  bool pressed = m_isActive();
80 
81  if (!pressedLast && pressed) {
82  command->Schedule(interruptible);
83  }
84 
85  pressedLast = pressed;
86  });
87 
88  return *this;
89  }
90 
97  Trigger WhenActive(std::function<void()> toRun,
98  std::initializer_list<Subsystem*> requirements);
99 
106  Trigger WhenActive(std::function<void()> toRun,
107  wpi::ArrayRef<Subsystem*> requirements = {});
108 
118  Trigger WhileActiveContinous(Command* command, bool interruptible = true);
119 
130  template <class T, typename = std::enable_if_t<std::is_base_of_v<
131  Command, std::remove_reference_t<T>>>>
132  Trigger WhileActiveContinous(T&& command, bool interruptible = true) {
134  [pressedLast = m_isActive(), *this,
135  command = std::make_unique<std::remove_reference_t<T>>(
136  std::forward<T>(command)),
137  interruptible]() mutable {
138  bool pressed = m_isActive();
139 
140  if (pressed) {
141  command->Schedule(interruptible);
142  } else if (pressedLast && !pressed) {
143  command->Cancel();
144  }
145 
146  pressedLast = pressed;
147  });
148  return *this;
149  }
150 
157  Trigger WhileActiveContinous(std::function<void()> toRun,
158  std::initializer_list<Subsystem*> requirements);
159 
166  Trigger WhileActiveContinous(std::function<void()> toRun,
167  wpi::ArrayRef<Subsystem*> requirements = {});
168 
178  Trigger WhileActiveOnce(Command* command, bool interruptible = true);
179 
190  template <class T, typename = std::enable_if_t<std::is_base_of_v<
191  Command, std::remove_reference_t<T>>>>
192  Trigger WhileActiveOnce(T&& command, bool interruptible = true) {
194  [pressedLast = m_isActive(), *this,
195  command = std::make_unique<std::remove_reference_t<T>>(
196  std::forward<T>(command)),
197  interruptible]() mutable {
198  bool pressed = m_isActive();
199 
200  if (!pressedLast && pressed) {
201  command->Schedule(interruptible);
202  } else if (pressedLast && !pressed) {
203  command->Cancel();
204  }
205 
206  pressedLast = pressed;
207  });
208  return *this;
209  }
210 
220  Trigger WhenInactive(Command* command, bool interruptible = true);
221 
232  template <class T, typename = std::enable_if_t<std::is_base_of_v<
233  Command, std::remove_reference_t<T>>>>
234  Trigger WhenInactive(T&& command, bool interruptible = true) {
236  [pressedLast = m_isActive(), *this,
237  command = std::make_unique<std::remove_reference_t<T>>(
238  std::forward<T>(command)),
239  interruptible]() mutable {
240  bool pressed = m_isActive();
241 
242  if (pressedLast && !pressed) {
243  command->Schedule(interruptible);
244  }
245 
246  pressedLast = pressed;
247  });
248  return *this;
249  }
250 
257  Trigger WhenInactive(std::function<void()> toRun,
258  std::initializer_list<Subsystem*> requirements);
259 
266  Trigger WhenInactive(std::function<void()> toRun,
267  wpi::ArrayRef<Subsystem*> requirements = {});
268 
278  Trigger ToggleWhenActive(Command* command, bool interruptible = true);
279 
290  template <class T, typename = std::enable_if_t<std::is_base_of_v<
291  Command, std::remove_reference_t<T>>>>
292  Trigger ToggleWhenActive(T&& command, bool interruptible = true) {
294  [pressedLast = m_isActive(), *this,
295  command = std::make_unique<std::remove_reference_t<T>>(
296  std::forward<T>(command)),
297  interruptible]() mutable {
298  bool pressed = m_isActive();
299 
300  if (!pressedLast && pressed) {
301  if (command->IsScheduled()) {
302  command->Cancel();
303  } else {
304  command->Schedule(interruptible);
305  }
306  }
307 
308  pressedLast = pressed;
309  });
310  return *this;
311  }
312 
321  Trigger CancelWhenActive(Command* command);
322 
329  return Trigger([*this, rhs] { return m_isActive() && rhs.m_isActive(); });
330  }
331 
338  return Trigger([*this, rhs] { return m_isActive() || rhs.m_isActive(); });
339  }
340 
348  return Trigger([*this] { return !m_isActive(); });
349  }
350 
351  private:
352  std::function<bool()> m_isActive;
353 };
354 } // namespace frc2
frc2::Trigger
A class used to bind command scheduling to events.
Definition: Trigger.h:30
frc2::Trigger::ToggleWhenActive
Trigger ToggleWhenActive(T &&command, bool interruptible=true)
Binds a command to start when the trigger becomes active, and be cancelled when it again becomes acti...
Definition: Trigger.h:292
frc2::Trigger::WhileActiveOnce
Trigger WhileActiveOnce(Command *command, bool interruptible=true)
Binds a command to be started when the trigger becomes active, and cancelled when it becomes inactive...
frc2::Trigger::WhenInactive
Trigger WhenInactive(T &&command, bool interruptible=true)
Binds a command to start when the trigger becomes inactive.
Definition: Trigger.h:234
frc2::Trigger::CancelWhenActive
Trigger CancelWhenActive(Command *command)
Binds a command to be cancelled when the trigger becomes active.
wpi::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:42
frc2::CommandScheduler::GetInstance
static CommandScheduler & GetInstance()
Returns the Scheduler instance.
frc2::Trigger::operator&&
Trigger operator&&(Trigger rhs)
Composes two triggers with logical AND.
Definition: Trigger.h:328
frc2::Trigger::WhileActiveOnce
Trigger WhileActiveOnce(T &&command, bool interruptible=true)
Binds a command to be started when the trigger becomes active, and cancelled when it becomes inactive...
Definition: Trigger.h:192
frc2::Trigger::Trigger
Trigger()
Create a new trigger that is never active (default constructor) - activity can be further determined ...
Definition: Trigger.h:44
frc2::Command
A state machine representing a complete action to be performed by the robot.
Definition: Command.h:52
frc2::Trigger::WhenActive
Trigger WhenActive(T &&command, bool interruptible=true)
Binds a command to start when the trigger becomes active.
Definition: Trigger.h:73
frc2::Trigger::WhenInactive
Trigger WhenInactive(Command *command, bool interruptible=true)
Binds a command to start when the trigger becomes inactive.
frc2::Trigger::WhenActive
Trigger WhenActive(Command *command, bool interruptible=true)
Binds a command to start when the trigger becomes active.
frc2::CommandScheduler::AddButton
void AddButton(wpi::unique_function< void()> button)
Adds a button binding to the scheduler, which will be polled to schedule commands.
frc2::Trigger::operator||
Trigger operator||(Trigger rhs)
Composes two triggers with logical OR.
Definition: Trigger.h:337
frc2::Trigger::Trigger
Trigger(std::function< bool()> isActive)
Create a new trigger that is active when the given condition is true.
Definition: Trigger.h:37
frc2::Trigger::ToggleWhenActive
Trigger ToggleWhenActive(Command *command, bool interruptible=true)
Binds a command to start when the trigger becomes active, and be cancelled when it again becomes acti...
frc2::Trigger::operator!
Trigger operator!()
Composes a trigger with logical NOT.
Definition: Trigger.h:347
frc2::Trigger::WhileActiveContinous
Trigger WhileActiveContinous(Command *command, bool interruptible=true)
Binds a command to be started repeatedly while the trigger is active, and cancelled when it becomes i...
frc2::Trigger::WhileActiveContinous
Trigger WhileActiveContinous(T &&command, bool interruptible=true)
Binds a command to be started repeatedly while the trigger is active, and cancelled when it becomes i...
Definition: Trigger.h:132