WPILibC++ 2025.2.1
Loading...
Searching...
No Matches
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 <concepts>
8#include <functional>
9#include <memory>
10#include <string>
11#include <utility>
12#include <vector>
13
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<Command>&& command);
31
32 template <std::derived_from<Command> T>
33 // NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
34 explicit CommandPtr(T&& command)
35 : CommandPtr(
36 std::make_unique<std::decay_t<T>>(std::forward<T>(command))) {}
37
40
41 explicit CommandPtr(std::nullptr_t) = delete;
42
43 /**
44 * Decorates this command to run repeatedly, restarting it when it ends, until
45 * this command is interrupted. The decorated command can still be canceled.
46 *
47 * @return the decorated command
48 */
49 [[nodiscard]]
51
52 /**
53 * Decorates this command to run "by proxy" by wrapping it in a ProxyCommand.
54 * Use this for "forking off" from command compositions when the user does not
55 * wish to extend the command's requirements to the entire command
56 * composition. ProxyCommand has unique implications and semantics, see <a
57 * href="https://docs.wpilib.org/en/stable/docs/software/commandbased/command-compositions.html#scheduling-other-commands">the
58 * WPILib docs</a> for a full explanation.
59 *
60 * @return the decorated command
61 * @see ProxyCommand
62 */
63 [[nodiscard]]
65
66 /**
67 * Decorates this command to run or stop when disabled.
68 *
69 * @param doesRunWhenDisabled true to run when disabled
70 * @return the decorated command
71 */
72 [[nodiscard]]
73 CommandPtr IgnoringDisable(bool doesRunWhenDisabled) &&;
74
75 /**
76 * Decorates this command to have a different interrupt behavior.
77 *
78 * @param interruptBehavior the desired interrupt behavior
79 * @return the decorated command
80 */
81 [[nodiscard]]
83 Command::InterruptionBehavior interruptBehavior) &&;
84
85 /**
86 * Decorates this command with a runnable to run after the command finishes.
87 *
88 * @param toRun the Runnable to run
89 * @param requirements the required subsystems
90 * @return the decorated command
91 */
92 [[nodiscard]]
93 CommandPtr AndThen(std::function<void()> toRun,
94 Requirements requirements = {}) &&;
95
96 /**
97 * Decorates this command with a set of commands to run after it in sequence.
98 * Often more convenient/less-verbose than constructing a new {@link
99 * SequentialCommandGroup} explicitly.
100 *
101 * @param next the commands to run next
102 * @return the decorated command
103 */
104 [[nodiscard]]
106
107 /**
108 * Decorates this command with a runnable to run before this command starts.
109 *
110 * @param toRun the Runnable to run
111 * @param requirements the required subsystems
112 * @return the decorated command
113 */
114 [[nodiscard]]
115 CommandPtr BeforeStarting(std::function<void()> toRun,
116 Requirements requirements = {}) &&;
117
118 /**
119 * Decorates this command with another command to run before this command
120 * starts.
121 *
122 * @param before the command to run before this one
123 * @return the decorated command
124 */
125 [[nodiscard]]
127
128 /**
129 * Decorates this command with a timeout. If the specified timeout is
130 * exceeded before the command finishes normally, the command will be
131 * interrupted and un-scheduled.
132 *
133 * @param duration the timeout duration
134 * @return the command with the timeout added
135 */
136 [[nodiscard]]
137 CommandPtr WithTimeout(units::second_t duration) &&;
138
139 /**
140 * Decorates this command with an interrupt condition. If the specified
141 * condition becomes true before the command finishes normally, the command
142 * will be interrupted and un-scheduled.
143 *
144 * @param condition the interrupt condition
145 * @return the command with the interrupt condition added
146 */
147 [[nodiscard]]
148 CommandPtr Until(std::function<bool()> condition) &&;
149
150 /**
151 * Decorates this command with a run condition. If the specified condition
152 * becomes false before the command finishes normally, the command will be
153 * interrupted and un-scheduled.
154 *
155 * @param condition the run condition
156 * @return the command with the run condition added
157 */
158 [[nodiscard]]
159 CommandPtr OnlyWhile(std::function<bool()> condition) &&;
160
161 /**
162 * Decorates this command to only run if this condition is not met. If the
163 * command is already running and the condition changes to true, the command
164 * will not stop running. The requirements of this command will be kept for
165 * the new conditional command.
166 *
167 * @param condition the condition that will prevent the command from running
168 * @return the decorated command
169 */
170 [[nodiscard]]
171 CommandPtr Unless(std::function<bool()> condition) &&;
172
173 /**
174 * Decorates this command to only run if this condition is met. If the command
175 * is already running and the condition changes to false, the command will not
176 * stop running. The requirements of this command will be kept for the new
177 * conditional command.
178 *
179 * @param condition the condition that will allow the command to run
180 * @return the decorated command
181 */
182 [[nodiscard]]
183 CommandPtr OnlyIf(std::function<bool()> condition) &&;
184
185 /**
186 * Creates a new command that runs this command and the deadline in parallel,
187 * finishing (and interrupting this command) when the deadline finishes.
188 *
189 * @param deadline the deadline of the command group
190 * @return the decorated command
191 * @see DeadlineFor
192 */
194
195 /**
196 * Decorates this command with a set of commands to run parallel to it, ending
197 * when the calling command ends and interrupting all the others. Often more
198 * convenient/less-verbose than constructing a new {@link
199 * ParallelDeadlineGroup} explicitly.
200 *
201 * @param parallel the commands to run in parallel
202 * @return the decorated command
203 */
204 [[nodiscard]] [[deprecated("Replace with DeadlineFor")]]
206
207 /**
208 * Decorates this command with a set of commands to run parallel to it, ending
209 * when the calling command ends and interrupting all the others. Often more
210 * convenient/less-verbose than constructing a new {@link
211 * ParallelDeadlineGroup} explicitly.
212 *
213 * @param parallel the commands to run in parallel. Note the parallel commands
214 * will be interupted when the deadline command ends
215 * @return the decorated command
216 */
217 [[nodiscard]]
219 /**
220 * Decorates this command with a set of commands to run parallel to it, ending
221 * when the last command ends. Often more convenient/less-verbose than
222 * constructing a new {@link ParallelCommandGroup} explicitly.
223 *
224 * @param parallel the commands to run in parallel
225 * @return the decorated command
226 */
227 [[nodiscard]]
229
230 /**
231 * Decorates this command with a set of commands to run parallel to it, ending
232 * when the first command ends. Often more convenient/less-verbose than
233 * constructing a new {@link ParallelRaceGroup} explicitly.
234 *
235 * @param parallel the commands to run in parallel
236 * @return the decorated command
237 */
238 [[nodiscard]]
240
241 /**
242 * Decorates this command with a lambda to call on interrupt or end, following
243 * the command's inherent Command::End(bool) method.
244 *
245 * @param end a lambda accepting a boolean parameter specifying whether the
246 * command was interrupted
247 * @return the decorated command
248 */
249 [[nodiscard]]
250 CommandPtr FinallyDo(std::function<void(bool)> end) &&;
251
252 /**
253 * Decorates this command with a lambda to call on interrupt or end, following
254 * the command's inherent Command::End(bool) method. The provided lambda will
255 * run identically in both interrupt and end cases.
256 *
257 * @param end a lambda to run when the command ends, whether or not it was
258 * interrupted.
259 * @return the decorated command
260 */
261 [[nodiscard]]
262 CommandPtr FinallyDo(std::function<void()> end) &&;
263
264 /**
265 * Decorates this command with a lambda to call on interrupt, following the
266 * command's inherent Command::End(bool) method.
267 *
268 * @param handler a lambda to run when the command is interrupted
269 * @return the decorated command
270 */
271 [[nodiscard]]
272 CommandPtr HandleInterrupt(std::function<void()> handler) &&;
273
274 /**
275 * Decorates this Command with a name. Is an inline function for
276 * Command::SetName(std::string_view);
277 *
278 * @param name name
279 * @return the decorated Command
280 */
281 [[nodiscard]]
282 CommandPtr WithName(std::string_view name) &&;
283
284 /**
285 * Get a raw pointer to the held command.
286 */
287 Command* get() const&;
288
289 // Prevent calls on a temporary, as the returned pointer would be invalid
290 Command* get() && = delete;
291
292 /**
293 * Convert to the underlying unique_ptr.
294 */
295 std::unique_ptr<Command> Unwrap() &&;
296
297 /**
298 * Schedules this command.
299 */
300 void Schedule() const&;
301
302 // Prevent calls on a temporary, as the returned pointer would be invalid
303 void Schedule() && = delete;
304
305 /**
306 * Cancels this command. Will call End(true). Commands will be canceled
307 * regardless of interruption behavior.
308 */
309 void Cancel() const&;
310
311 // Prevent calls on a temporary, as the returned pointer would be invalid
312 void Cancel() && = delete;
313
314 /**
315 * Whether or not the command is currently scheduled. Note that this does not
316 * detect whether the command is in a composition, only whether it is directly
317 * being run by the scheduler.
318 *
319 * @return Whether the command is scheduled.
320 */
321 bool IsScheduled() const&;
322
323 // Prevent calls on a temporary, as the returned pointer would be invalid
324 void IsScheduled() && = delete;
325
326 /**
327 * Whether the command requires a given subsystem. Named "HasRequirement"
328 * rather than "requires" to avoid confusion with Command::Requires(Subsystem)
329 * -- this may be able to be changed in a few years.
330 *
331 * @param requirement the subsystem to inquire about
332 * @return whether the subsystem is required
333 */
334 bool HasRequirement(Subsystem* requirement) const&;
335
336 // Prevent calls on a temporary, as the returned pointer would be invalid
337 void HasRequirement(Subsystem* requirement) && = delete;
338
339 /**
340 * Check if this CommandPtr object is valid and wasn't moved-from.
341 */
342 explicit operator bool() const&;
343
344 // Prevent calls on a temporary, as the returned pointer would be invalid
345 explicit operator bool() && = delete;
346
347 /**
348 * Convert a vector of CommandPtr objects to their underlying unique_ptrs.
349 */
350 static std::vector<std::unique_ptr<Command>> UnwrapVector(
351 std::vector<CommandPtr>&& vec);
352
353 private:
354 std::unique_ptr<Command> m_ptr;
355 std::string m_moveOutSite{""};
356 void AssertValid() const;
357};
358
359} // namespace frc2
A state machine representing a complete action to be performed by the robot.
Definition Command.h:41
InterruptionBehavior
An enum describing the command's behavior when another command with a shared requirement is scheduled...
Definition Command.h:173
A wrapper around std::unique_ptr<Command> so commands have move-only semantics.
Definition CommandPtr.h:28
CommandPtr OnlyIf(std::function< bool()> condition) &&
Decorates this command to only run if this condition is met.
void Cancel() const &
Cancels this command.
std::unique_ptr< Command > Unwrap() &&
Convert to the underlying unique_ptr.
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 WithDeadline(CommandPtr &&deadline) &&
Creates a new command that runs this command and the deadline in parallel, finishing (and interruptin...
CommandPtr FinallyDo(std::function< void()> end) &&
Decorates this command with a lambda to call on interrupt or end, following the command's inherent Co...
CommandPtr BeforeStarting(std::function< void()> toRun, Requirements requirements={}) &&
Decorates this command with a runnable to run before this command starts.
Command * get() const &
Get a raw pointer to the held command.
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 have a different interrupt behavior.
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...
CommandPtr(std::unique_ptr< Command > &&command)
CommandPtr(CommandPtr &&)
CommandPtr(T &&command)
Definition CommandPtr.h:34
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.
CommandPtr(std::nullptr_t)=delete
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 OnlyWhile(std::function< bool()> condition) &&
Decorates this command with a run condition.
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, Requirements requirements={}) &&
Decorates this command with a runnable to run after the command finishes.
CommandPtr DeadlineFor(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the calling command ...
CommandPtr DeadlineWith(CommandPtr &&parallel) &&
Decorates this command with a set of commands to run parallel to it, ending when the calling command ...
Represents requirements for a command, which is a set of (pointers to) subsystems.
Definition Requirements.h:20
A robot subsystem.
Definition Subsystem.h:43
Definition FunctionalCommand.h:13
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
typename std::decay< T >::type decay_t
Definition base.h:311