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