WPILibC++ 2023.4.3
CommandPtr.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 <string>
12#include <utility>
13#include <vector>
14
16
17namespace frc2 {
18/**
19 * A wrapper around std::unique_ptr<Command> so commands have move-only
20 * semantics. Commands should only be stored and passed around when held in a
21 * CommandPtr instance. For more info, see
22 * https://github.com/wpilibsuite/allwpilib/issues/4303.
23 *
24 * Various classes in the command-based library accept a
25 * std::unique_ptr<Command>, use CommandPtr::Unwrap to convert.
26 * CommandPtr::UnwrapVector does the same for vectors.
27 */
28class CommandPtr final {
29 public:
30 explicit CommandPtr(std::unique_ptr<CommandBase>&& command)
31 : m_ptr(std::move(command)) {}
32
33 template <class T, typename = std::enable_if_t<std::is_base_of_v<
34 Command, std::remove_reference_t<T>>>>
35 explicit CommandPtr(T&& command)
36 : CommandPtr(std::make_unique<std::remove_reference_t<T>>(
37 std::forward<T>(command))) {}
38
39 CommandPtr(CommandPtr&&) = default;
41
42 /**
43 * Decorates this command to run repeatedly, restarting it when it ends, until
44 * this command is interrupted. The decorated command can still be canceled.
45 *
46 * @return the decorated command
47 */
48 [[nodiscard]] CommandPtr Repeatedly() &&;
49
50 /**
51 * Decorates this command to run "by proxy" by wrapping it in a
52 * ProxyCommand. This is useful for "forking off" from command groups
53 * when the user does not wish to extend the command's requirements to the
54 * entire command group.
55 *
56 * @return the decorated command
57 */
58 [[nodiscard]] CommandPtr AsProxy() &&;
59
60 /**
61 * Decorates this command to run or stop when disabled.
62 *
63 * @param doesRunWhenDisabled true to run when disabled.
64 * @return the decorated command
65 */
66 [[nodiscard]] CommandPtr IgnoringDisable(bool doesRunWhenDisabled) &&;
67
68 /**
69 * Decorates this command to run or stop when disabled.
70 *
71 * @param interruptBehavior true to run when disabled.
72 * @return the decorated command
73 */
75 Command::InterruptionBehavior interruptBehavior) &&;
76
77 /**
78 * Decorates this command with a runnable to run after the command finishes.
79 *
80 * @param toRun the Runnable to run
81 * @param requirements the required subsystems
82 * @return the decorated command
83 */
84 [[nodiscard]] CommandPtr AndThen(
85 std::function<void()> toRun,
86 std::span<Subsystem* const> requirements = {}) &&;
87
88 /**
89 * Decorates this command with a runnable to run after the command finishes.
90 *
91 * @param toRun the Runnable to run
92 * @param requirements the required subsystems
93 * @return the decorated command
94 */
95 [[nodiscard]] CommandPtr AndThen(
96 std::function<void()> toRun,
97 std::initializer_list<Subsystem*> requirements) &&;
98
99 /**
100 * Decorates this command with a set of commands to run after it in sequence.
101 * Often more convenient/less-verbose than constructing a new {@link
102 * SequentialCommandGroup} explicitly.
103 *
104 * @param next the commands to run next
105 * @return the decorated command
106 */
107 [[nodiscard]] CommandPtr AndThen(CommandPtr&& next) &&;
108
109 /**
110 * Decorates this command with a runnable to run before this command starts.
111 *
112 * @param toRun the Runnable to run
113 * @param requirements the required subsystems
114 * @return the decorated command
115 */
117 std::function<void()> toRun,
118 std::initializer_list<Subsystem*> requirements) &&;
119
120 /**
121 * Decorates this command with a runnable to run before this command starts.
122 *
123 * @param toRun the Runnable to run
124 * @param requirements the required subsystems
125 * @return the decorated command
126 */
128 std::function<void()> toRun,
129 std::span<Subsystem* const> requirements = {}) &&;
130
131 /**
132 * Decorates this command with another command to run before this command
133 * starts.
134 *
135 * @param before the command to run before this one
136 * @return the decorated command
137 */
138 [[nodiscard]] CommandPtr BeforeStarting(CommandPtr&& before) &&;
139
140 /**
141 * Decorates this command with a timeout. If the specified timeout is
142 * exceeded before the command finishes normally, the command will be
143 * interrupted and un-scheduled. Note that the timeout only applies to the
144 * command returned by this method; the calling command is not itself changed.
145 *
146 * @param duration the timeout duration
147 * @return the command with the timeout added
148 */
149 [[nodiscard]] CommandPtr WithTimeout(units::second_t duration) &&;
150
151 /**
152 * Decorates this command with an interrupt condition. If the specified
153 * condition becomes true before the command finishes normally, the command
154 * will be interrupted and un-scheduled. Note that this only applies to the
155 * command returned by this method; the calling command is not itself changed.
156 *
157 * @param condition the interrupt condition
158 * @return the command with the interrupt condition added
159 */
160 [[nodiscard]] CommandPtr Until(std::function<bool()> condition) &&;
161
162 /**
163 * Decorates this command to only run if this condition is not met. If the
164 * command is already running and the condition changes to true, the command
165 * will not stop running. The requirements of this command will be kept for
166 * the new conditional command.
167 *
168 * @param condition the condition that will prevent the command from running
169 * @return the decorated command
170 */
171 [[nodiscard]] CommandPtr Unless(std::function<bool()> condition) &&;
172
173 /**
174 * Decorates this command with a set of commands to run parallel to it, ending
175 * when the calling command ends and interrupting all the others. Often more
176 * convenient/less-verbose than constructing a new {@link
177 * ParallelDeadlineGroup} explicitly.
178 *
179 * @param parallel the commands to run in parallel
180 * @return the decorated command
181 */
182 [[nodiscard]] CommandPtr DeadlineWith(CommandPtr&& parallel) &&;
183
184 /**
185 * Decorates this command with a set of commands to run parallel to it, ending
186 * when the last command ends. Often more convenient/less-verbose than
187 * constructing a new {@link ParallelCommandGroup} explicitly.
188 *
189 * @param parallel the commands to run in parallel
190 * @return the decorated command
191 */
192 [[nodiscard]] CommandPtr AlongWith(CommandPtr&& parallel) &&;
193
194 /**
195 * Decorates this command with a set of commands to run parallel to it, ending
196 * when the first command ends. Often more convenient/less-verbose than
197 * constructing a new {@link ParallelRaceGroup} explicitly.
198 *
199 * @param parallel the commands to run in parallel
200 * @return the decorated command
201 */
202 [[nodiscard]] CommandPtr RaceWith(CommandPtr&& parallel) &&;
203
204 /**
205 * Decorates this command with a lambda to call on interrupt or end, following
206 * the command's inherent Command::End(bool) method.
207 *
208 * @param end a lambda accepting a boolean parameter specifying whether the
209 * command was interrupted.
210 * @return the decorated command
211 */
212 [[nodiscard]] CommandPtr FinallyDo(std::function<void(bool)> end) &&;
213
214 /**
215 * Decorates this command with a lambda to call on interrupt, following the
216 * command's inherent Command::End(bool) method.
217 *
218 * @param handler a lambda to run when the command is interrupted
219 * @return the decorated command
220 */
221 [[nodiscard]] CommandPtr HandleInterrupt(std::function<void()> handler) &&;
222
223 /**
224 * Decorates this Command with a name. Is an inline function for
225 * Command::SetName(std::string_view);
226 *
227 * @param name name
228 * @return the decorated Command
229 */
230 [[nodiscard]] CommandPtr WithName(std::string_view name) &&;
231
232 /**
233 * Get a raw pointer to the held command.
234 */
235 CommandBase* get() const&;
236
237 // Prevent calls on a temporary, as the returned pointer would be invalid
238 CommandBase* get() && = delete;
239
240 /**
241 * Convert to the underlying unique_ptr.
242 */
243 std::unique_ptr<CommandBase> Unwrap() &&;
244
245 /**
246 * Schedules this command.
247 */
248 void Schedule() const&;
249
250 // Prevent calls on a temporary, as the returned pointer would be invalid
251 void Schedule() && = delete;
252
253 /**
254 * Cancels this command. Will call End(true). Commands will be canceled
255 * regardless of interruption behavior.
256 */
257 void Cancel() const&;
258
259 // Prevent calls on a temporary, as the returned pointer would be invalid
260 void Cancel() && = delete;
261
262 /**
263 * Whether or not the command is currently scheduled. Note that this does not
264 * detect whether the command is in a composition, only whether it is directly
265 * being run by the scheduler.
266 *
267 * @return Whether the command is scheduled.
268 */
269 bool IsScheduled() const&;
270
271 // Prevent calls on a temporary, as the returned pointer would be invalid
272 void IsScheduled() && = delete;
273
274 /**
275 * Whether the command requires a given subsystem. Named "HasRequirement"
276 * rather than "requires" to avoid confusion with Command::Requires(Subsystem)
277 * -- this may be able to be changed in a few years.
278 *
279 * @param requirement the subsystem to inquire about
280 * @return whether the subsystem is required
281 */
282 bool HasRequirement(Subsystem* requirement) const&;
283
284 // Prevent calls on a temporary, as the returned pointer would be invalid
285 void HasRequirement(Subsystem* requirement) && = delete;
286
287 /**
288 * Check if this CommandPtr object is valid and wasn't moved-from.
289 */
290 explicit operator bool() const&;
291
292 // Prevent calls on a temporary, as the returned pointer would be invalid
293 explicit operator bool() && = delete;
294
295 /**
296 * Convert a vector of CommandPtr objects to their underlying unique_ptrs.
297 */
298 static std::vector<std::unique_ptr<Command>> UnwrapVector(
299 std::vector<CommandPtr>&& vec);
300
301 private:
302 std::unique_ptr<CommandBase> m_ptr;
303 void AssertValid() const;
304};
305
306} // namespace frc2
A Sendable base class for Commands.
Definition: CommandBase.h:26
A state machine representing a complete action to be performed by the robot.
Definition: Command.h:47
InterruptionBehavior
An enum describing the command's behavior when another command with a shared requirement is scheduled...
Definition: Command.h:104
A wrapper around std::unique_ptr<Command> so commands have move-only semantics.
Definition: CommandPtr.h:28
void Cancel() const &
Cancels this command.
CommandPtr(std::unique_ptr< CommandBase > &&command)
Definition: CommandPtr.h:30
CommandBase * get() const &
Get a raw pointer to the held command.
CommandPtr BeforeStarting(std::function< void()> toRun, std::initializer_list< Subsystem * > requirements) &&
Decorates this command with a runnable to run before this command starts.
CommandPtr(CommandPtr &&)=default
CommandPtr HandleInterrupt(std::function< void()> handler) &&
Decorates this command with a lambda to call on interrupt, following the command's inherent Command::...
CommandPtr Unless(std::function< bool()> condition) &&
Decorates this command to only run if this condition is not met.
CommandPtr BeforeStarting(std::function< void()> toRun, std::span< Subsystem *const > requirements={}) &&
Decorates this command with a runnable to run before this command starts.
CommandPtr RaceWith(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the first command en...
bool HasRequirement(Subsystem *requirement) const &
Whether the command requires a given subsystem.
CommandPtr AndThen(CommandPtr &&next) &&
Decorates this command with a set of commands to run after it in sequence.
CommandPtr Until(std::function< bool()> condition) &&
Decorates this command with an interrupt condition.
CommandPtr IgnoringDisable(bool doesRunWhenDisabled) &&
Decorates this command to run or stop when disabled.
CommandPtr WithInterruptBehavior(Command::InterruptionBehavior interruptBehavior) &&
Decorates this command to run or stop when disabled.
CommandPtr(T &&command)
Definition: CommandPtr.h:35
CommandPtr BeforeStarting(CommandPtr &&before) &&
Decorates this command with another command to run before this command starts.
CommandPtr WithName(std::string_view name) &&
Decorates this Command with a name.
CommandPtr AlongWith(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the last command end...
static std::vector< std::unique_ptr< Command > > UnwrapVector(std::vector< CommandPtr > &&vec)
Convert a vector of CommandPtr objects to their underlying unique_ptrs.
void Schedule() const &
Schedules this command.
bool IsScheduled() const &
Whether or not the command is currently scheduled.
CommandPtr AsProxy() &&
Decorates this command to run "by proxy" by wrapping it in a ProxyCommand.
CommandPtr AndThen(std::function< void()> toRun, std::span< Subsystem *const > requirements={}) &&
Decorates this command with a runnable to run after the command finishes.
std::unique_ptr< CommandBase > Unwrap() &&
Convert to the underlying unique_ptr.
CommandPtr FinallyDo(std::function< void(bool)> end) &&
Decorates this command with a lambda to call on interrupt or end, following the command's inherent Co...
CommandPtr WithTimeout(units::second_t duration) &&
Decorates this command with a timeout.
CommandPtr Repeatedly() &&
Decorates this command to run repeatedly, restarting it when it ends, until this command is interrupt...
CommandPtr & operator=(CommandPtr &&)=default
CommandPtr AndThen(std::function< void()> toRun, std::initializer_list< Subsystem * > requirements) &&
Decorates this command with a runnable to run after the command finishes.
CommandPtr DeadlineWith(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the calling command ...
A robot subsystem.
Definition: Subsystem.h:39
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:298
basic_string_view< char > string_view
Definition: core.h:520
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:303
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: InstantCommand.h:14
Definition: StdDeque.h:50