WPILibC++ 2023.4.3-108-ge5452e3
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 <initializer_list>
10#include <memory>
11#include <span>
12#include <string>
13#include <utility>
14#include <vector>
15
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<CommandBase>&& command)
32 : m_ptr(std::move(command)) {}
33
34 template <std::derived_from<Command> T>
35 // NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
36 explicit CommandPtr(T&& command)
37 : CommandPtr(
38 std::make_unique<std::decay_t<T>>(std::forward<T>(command))) {}
39
40 CommandPtr(CommandPtr&&) = default;
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
54 * ProxyCommand. This is useful for "forking off" from command groups
55 * when the user does not wish to extend the command's requirements to the
56 * entire command group.
57 *
58 * @return the decorated command
59 */
60 [[nodiscard]]
62
63 /**
64 * Decorates this command to run or stop when disabled.
65 *
66 * @param doesRunWhenDisabled true to run when disabled
67 * @return the decorated command
68 */
69 [[nodiscard]]
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 */
78 [[nodiscard]]
80 Command::InterruptionBehavior interruptBehavior) &&;
81
82 /**
83 * Decorates this command with a runnable to run after the command finishes.
84 *
85 * @param toRun the Runnable to run
86 * @param requirements the required subsystems
87 * @return the decorated command
88 */
89 [[nodiscard]]
90 CommandPtr AndThen(std::function<void()> toRun,
91 std::span<Subsystem* const> requirements = {}) &&;
92
93 /**
94 * Decorates this command with a runnable to run after the command finishes.
95 *
96 * @param toRun the Runnable to run
97 * @param requirements the required subsystems
98 * @return the decorated command
99 */
100 [[nodiscard]]
101 CommandPtr AndThen(std::function<void()> toRun,
102 std::initializer_list<Subsystem*> requirements) &&;
103
104 /**
105 * Decorates this command with a set of commands to run after it in sequence.
106 * Often more convenient/less-verbose than constructing a new {@link
107 * SequentialCommandGroup} explicitly.
108 *
109 * @param next the commands to run next
110 * @return the decorated command
111 */
112 [[nodiscard]]
114
115 /**
116 * Decorates this command with a runnable to run before this command starts.
117 *
118 * @param toRun the Runnable to run
119 * @param requirements the required subsystems
120 * @return the decorated command
121 */
122 [[nodiscard]]
123 CommandPtr BeforeStarting(std::function<void()> toRun,
124 std::initializer_list<Subsystem*> requirements) &&;
125
126 /**
127 * Decorates this command with a runnable to run before this command starts.
128 *
129 * @param toRun the Runnable to run
130 * @param requirements the required subsystems
131 * @return the decorated command
132 */
133 [[nodiscard]]
134 CommandPtr BeforeStarting(std::function<void()> toRun,
135 std::span<Subsystem* const> requirements = {}) &&;
136
137 /**
138 * Decorates this command with another command to run before this command
139 * starts.
140 *
141 * @param before the command to run before this one
142 * @return the decorated command
143 */
144 [[nodiscard]]
146
147 /**
148 * Decorates this command with a timeout. If the specified timeout is
149 * exceeded before the command finishes normally, the command will be
150 * interrupted and un-scheduled.
151 *
152 * @param duration the timeout duration
153 * @return the command with the timeout added
154 */
155 [[nodiscard]]
156 CommandPtr WithTimeout(units::second_t duration) &&;
157
158 /**
159 * Decorates this command with an interrupt condition. If the specified
160 * condition becomes true before the command finishes normally, the command
161 * will be interrupted and un-scheduled.
162 *
163 * @param condition the interrupt condition
164 * @return the command with the interrupt condition added
165 */
166 [[nodiscard]]
167 CommandPtr Until(std::function<bool()> condition) &&;
168
169 /**
170 * Decorates this command with a run condition. If the specified condition
171 * becomes false before the command finishes normally, the command will be
172 * interrupted and un-scheduled.
173 *
174 * @param condition the run condition
175 * @return the command with the run condition added
176 */
177 [[nodiscard]]
178 CommandPtr OnlyWhile(std::function<bool()> condition) &&;
179
180 /**
181 * Decorates this command to only run if this condition is not met. If the
182 * command is already running and the condition changes to true, the command
183 * will not stop running. The requirements of this command will be kept for
184 * the new conditional command.
185 *
186 * @param condition the condition that will prevent the command from running
187 * @return the decorated command
188 */
189 [[nodiscard]]
190 CommandPtr Unless(std::function<bool()> condition) &&;
191
192 /**
193 * Decorates this command to only run if this condition is met. If the command
194 * is already running and the condition changes to false, the command will not
195 * stop running. The requirements of this command will be kept for the new
196 * conditional command.
197 *
198 * @param condition the condition that will allow the command to run
199 * @return the decorated command
200 */
201 [[nodiscard]]
202 CommandPtr OnlyIf(std::function<bool()> condition) &&;
203
204 /**
205 * Decorates this command with a set of commands to run parallel to it, ending
206 * when the calling command ends and interrupting all the others. Often more
207 * convenient/less-verbose than constructing a new {@link
208 * ParallelDeadlineGroup} explicitly.
209 *
210 * @param parallel the commands to run in parallel
211 * @return the decorated command
212 */
213 [[nodiscard]]
215
216 /**
217 * Decorates this command with a set of commands to run parallel to it, ending
218 * when the last command ends. Often more convenient/less-verbose than
219 * constructing a new {@link ParallelCommandGroup} explicitly.
220 *
221 * @param parallel the commands to run in parallel
222 * @return the decorated command
223 */
224 [[nodiscard]]
226
227 /**
228 * Decorates this command with a set of commands to run parallel to it, ending
229 * when the first command ends. Often more convenient/less-verbose than
230 * constructing a new {@link ParallelRaceGroup} explicitly.
231 *
232 * @param parallel the commands to run in parallel
233 * @return the decorated command
234 */
235 [[nodiscard]]
237
238 /**
239 * Decorates this command with a lambda to call on interrupt or end, following
240 * the command's inherent Command::End(bool) method.
241 *
242 * @param end a lambda accepting a boolean parameter specifying whether the
243 * command was interrupted
244 * @return the decorated command
245 */
246 [[nodiscard]]
247 CommandPtr FinallyDo(std::function<void(bool)> end) &&;
248
249 /**
250 * Decorates this command with a lambda to call on interrupt, following the
251 * command's inherent Command::End(bool) method.
252 *
253 * @param handler a lambda to run when the command is interrupted
254 * @return the decorated command
255 */
256 [[nodiscard]]
257 CommandPtr HandleInterrupt(std::function<void()> handler) &&;
258
259 /**
260 * Decorates this Command with a name. Is an inline function for
261 * Command::SetName(std::string_view);
262 *
263 * @param name name
264 * @return the decorated Command
265 */
266 [[nodiscard]]
268
269 /**
270 * Get a raw pointer to the held command.
271 */
272 CommandBase* get() const&;
273
274 // Prevent calls on a temporary, as the returned pointer would be invalid
275 CommandBase* get() && = delete;
276
277 /**
278 * Convert to the underlying unique_ptr.
279 */
280 std::unique_ptr<CommandBase> Unwrap() &&;
281
282 /**
283 * Schedules this command.
284 */
285 void Schedule() const&;
286
287 // Prevent calls on a temporary, as the returned pointer would be invalid
288 void Schedule() && = delete;
289
290 /**
291 * Cancels this command. Will call End(true). Commands will be canceled
292 * regardless of interruption behavior.
293 */
294 void Cancel() const&;
295
296 // Prevent calls on a temporary, as the returned pointer would be invalid
297 void Cancel() && = delete;
298
299 /**
300 * Whether or not the command is currently scheduled. Note that this does not
301 * detect whether the command is in a composition, only whether it is directly
302 * being run by the scheduler.
303 *
304 * @return Whether the command is scheduled.
305 */
306 bool IsScheduled() const&;
307
308 // Prevent calls on a temporary, as the returned pointer would be invalid
309 void IsScheduled() && = delete;
310
311 /**
312 * Whether the command requires a given subsystem. Named "HasRequirement"
313 * rather than "requires" to avoid confusion with Command::Requires(Subsystem)
314 * -- this may be able to be changed in a few years.
315 *
316 * @param requirement the subsystem to inquire about
317 * @return whether the subsystem is required
318 */
319 bool HasRequirement(Subsystem* requirement) const&;
320
321 // Prevent calls on a temporary, as the returned pointer would be invalid
322 void HasRequirement(Subsystem* requirement) && = delete;
323
324 /**
325 * Check if this CommandPtr object is valid and wasn't moved-from.
326 */
327 explicit operator bool() const&;
328
329 // Prevent calls on a temporary, as the returned pointer would be invalid
330 explicit operator bool() && = delete;
331
332 /**
333 * Convert a vector of CommandPtr objects to their underlying unique_ptrs.
334 */
335 static std::vector<std::unique_ptr<Command>> UnwrapVector(
336 std::vector<CommandPtr>&& vec);
337
338 private:
339 std::unique_ptr<CommandBase> m_ptr;
340 void AssertValid() const;
341};
342
343} // 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:44
InterruptionBehavior
An enum describing the command's behavior when another command with a shared requirement is scheduled...
Definition: Command.h:101
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.
CommandPtr(std::unique_ptr< CommandBase > &&command)
Definition: CommandPtr.h:31
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 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(T &&command)
Definition: CommandPtr.h:36
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 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, 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
basic_string_view< char > string_view
Definition: core.h:520
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: ProfiledPIDCommand.h:18
Definition: BFloat16.h:88