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