WPILibC++ 2024.3.2-79-gc76b358
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 * Decorates this command with a set of commands to run parallel to it, ending
187 * when the calling command ends and interrupting all the others. Often more
188 * convenient/less-verbose than constructing a new {@link
189 * ParallelDeadlineGroup} explicitly.
190 *
191 * @param parallel the commands to run in parallel
192 * @return the decorated command
193 */
194 [[nodiscard]] [[deprecated("Replace with DeadlineFor")]]
196
197 /**
198 * Decorates this command with a set of commands to run parallel to it, ending
199 * when the calling command ends and interrupting all the others. Often more
200 * convenient/less-verbose than constructing a new {@link
201 * ParallelDeadlineGroup} explicitly.
202 *
203 * @param parallel the commands to run in parallel. Note the parallel commands
204 * will be interupted when the deadline command ends
205 * @return the decorated command
206 */
207 [[nodiscard]]
209 /**
210 * Decorates this command with a set of commands to run parallel to it, ending
211 * when the last command ends. Often more convenient/less-verbose than
212 * constructing a new {@link ParallelCommandGroup} explicitly.
213 *
214 * @param parallel the commands to run in parallel
215 * @return the decorated command
216 */
217 [[nodiscard]]
219
220 /**
221 * Decorates this command with a set of commands to run parallel to it, ending
222 * when the first command ends. Often more convenient/less-verbose than
223 * constructing a new {@link ParallelRaceGroup} explicitly.
224 *
225 * @param parallel the commands to run in parallel
226 * @return the decorated command
227 */
228 [[nodiscard]]
230
231 /**
232 * Decorates this command with a lambda to call on interrupt or end, following
233 * the command's inherent Command::End(bool) method.
234 *
235 * @param end a lambda accepting a boolean parameter specifying whether the
236 * command was interrupted
237 * @return the decorated command
238 */
239 [[nodiscard]]
240 CommandPtr FinallyDo(std::function<void(bool)> end) &&;
241
242 /**
243 * Decorates this command with a lambda to call on interrupt or end, following
244 * the command's inherent Command::End(bool) method. The provided lambda will
245 * run identically in both interrupt and end cases.
246 *
247 * @param end a lambda to run when the command ends, whether or not it was
248 * interrupted.
249 * @return the decorated command
250 */
251 [[nodiscard]]
252 CommandPtr FinallyDo(std::function<void()> end) &&;
253
254 /**
255 * Decorates this command with a lambda to call on interrupt, following the
256 * command's inherent Command::End(bool) method.
257 *
258 * @param handler a lambda to run when the command is interrupted
259 * @return the decorated command
260 */
261 [[nodiscard]]
262 CommandPtr HandleInterrupt(std::function<void()> handler) &&;
263
264 /**
265 * Decorates this Command with a name. Is an inline function for
266 * Command::SetName(std::string_view);
267 *
268 * @param name name
269 * @return the decorated Command
270 */
271 [[nodiscard]]
273
274 /**
275 * Get a raw pointer to the held command.
276 */
277 Command* get() const&;
278
279 // Prevent calls on a temporary, as the returned pointer would be invalid
280 Command* get() && = delete;
281
282 /**
283 * Convert to the underlying unique_ptr.
284 */
285 std::unique_ptr<Command> Unwrap() &&;
286
287 /**
288 * Schedules this command.
289 */
290 void Schedule() const&;
291
292 // Prevent calls on a temporary, as the returned pointer would be invalid
293 void Schedule() && = delete;
294
295 /**
296 * Cancels this command. Will call End(true). Commands will be canceled
297 * regardless of interruption behavior.
298 */
299 void Cancel() const&;
300
301 // Prevent calls on a temporary, as the returned pointer would be invalid
302 void Cancel() && = delete;
303
304 /**
305 * Whether or not the command is currently scheduled. Note that this does not
306 * detect whether the command is in a composition, only whether it is directly
307 * being run by the scheduler.
308 *
309 * @return Whether the command is scheduled.
310 */
311 bool IsScheduled() const&;
312
313 // Prevent calls on a temporary, as the returned pointer would be invalid
314 void IsScheduled() && = delete;
315
316 /**
317 * Whether the command requires a given subsystem. Named "HasRequirement"
318 * rather than "requires" to avoid confusion with Command::Requires(Subsystem)
319 * -- this may be able to be changed in a few years.
320 *
321 * @param requirement the subsystem to inquire about
322 * @return whether the subsystem is required
323 */
324 bool HasRequirement(Subsystem* requirement) const&;
325
326 // Prevent calls on a temporary, as the returned pointer would be invalid
327 void HasRequirement(Subsystem* requirement) && = delete;
328
329 /**
330 * Check if this CommandPtr object is valid and wasn't moved-from.
331 */
332 explicit operator bool() const&;
333
334 // Prevent calls on a temporary, as the returned pointer would be invalid
335 explicit operator bool() && = delete;
336
337 /**
338 * Convert a vector of CommandPtr objects to their underlying unique_ptrs.
339 */
340 static std::vector<std::unique_ptr<Command>> UnwrapVector(
341 std::vector<CommandPtr>&& vec);
342
343 private:
344 std::unique_ptr<Command> m_ptr;
345 std::string m_moveOutSite{""};
346 void AssertValid() const;
347};
348
349} // 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 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
basic_string_view< char > string_view
Definition: core.h:501
Definition: NotifierCommand.h:16
Implement std::hash so that hash_code can be used in STL containers.
Definition: array.h:89
typename std::decay< T >::type decay_t
Definition: expected:231