WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
SelectCommand.hpp
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#ifdef _WIN32
8#pragma warning(push)
9#pragma warning(disable : 4521)
10#endif
11
12#include <concepts>
13#include <functional>
14#include <memory>
15#include <string>
16#include <unordered_map>
17#include <utility>
18#include <vector>
19
23
24namespace wpi::cmd {
25/**
26 * A command composition that runs one of a selection of commands using a
27 * selector and a key to command mapping.
28 *
29 * <p>The rules for command compositions apply: command instances that are
30 * passed to it are owned by the composition and cannot be added to any other
31 * composition or scheduled individually, and the composition requires all
32 * subsystems its components require.
33 *
34 * This class is provided by the NewCommands VendorDep
35 */
36template <typename Key>
37class SelectCommand : public CommandHelper<Command, SelectCommand<Key>> {
38 public:
39 /**
40 * Creates a new SelectCommand.
41 *
42 * @param commands the map of commands to choose from
43 * @param selector the selector to determine which command to run
44 */
45 template <std::derived_from<Command>... Commands>
46 explicit SelectCommand(std::function<Key()> selector,
47 std::pair<Key, Commands>... commands)
48 : m_selector{std::move(selector)} {
49 std::vector<std::pair<Key, std::unique_ptr<Command>>> foo;
50
51 ((void)foo.emplace_back(
52 commands.first,
53 std::make_unique<std::decay_t<Commands>>(std::move(commands.second))),
54 ...);
55
56 m_defaultCommand.SetComposed(true);
57 for (auto&& command : foo) {
59 command.second.get());
60 command.second.get()->SetComposed(true);
61 }
62
63 for (auto&& command : foo) {
64 this->AddRequirements(command.second->GetRequirements());
65 m_runsWhenDisabled &= command.second->RunsWhenDisabled();
66 if (command.second->GetInterruptionBehavior() ==
69 }
70 m_commands.emplace(std::move(command.first), std::move(command.second));
71 }
72 }
73
75 std::function<Key()> selector,
76 std::vector<std::pair<Key, std::unique_ptr<Command>>>&& commands)
77 : m_selector{std::move(selector)} {
78 m_defaultCommand.SetComposed(true);
79 for (auto&& command : commands) {
81 command.second.get());
82 command.second.get()->SetComposed(true);
83 }
84
85 for (auto&& command : commands) {
86 this->AddRequirements(command.second->GetRequirements());
87 m_runsWhenDisabled &= command.second->RunsWhenDisabled();
88 if (command.second->GetInterruptionBehavior() ==
91 }
92 m_commands.emplace(std::move(command.first), std::move(command.second));
93 }
94 }
95
96 // No copy constructors for command groups
97 SelectCommand(const SelectCommand& other) = delete;
98
99 // Prevent template expansion from emulating copy ctor
101
102 SelectCommand(SelectCommand&& other) = default;
103
104 void Initialize() override;
105
106 void Execute() override { m_selectedCommand->Execute(); }
107
108 void End(bool interrupted) override {
109 return m_selectedCommand->End(interrupted);
110 }
111
112 bool IsFinished() override { return m_selectedCommand->IsFinished(); }
113
114 bool RunsWhenDisabled() const override { return m_runsWhenDisabled; }
115
117 return m_interruptBehavior;
118 }
119
120 void InitSendable(wpi::util::SendableBuilder& builder) override {
121 Command::InitSendable(builder);
122
123 builder.AddStringProperty(
124 "selected",
125 [this] {
126 if (m_selectedCommand) {
127 return m_selectedCommand->GetName();
128 } else {
129 return std::string{"null"};
130 }
131 },
132 nullptr);
133 }
134
135 private:
136 std::unordered_map<Key, std::unique_ptr<Command>> m_commands;
137 std::function<Key()> m_selector;
138 Command* m_selectedCommand;
139 bool m_runsWhenDisabled = true;
140 Command::InterruptionBehavior m_interruptBehavior{
142
143 PrintCommand m_defaultCommand{
144 "SelectCommand selector value does not correspond to any command!"};
145};
146
147template <typename T>
149 auto find = m_commands.find(m_selector());
150 if (find == m_commands.end()) {
151 m_selectedCommand = &m_defaultCommand;
152 } else {
153 m_selectedCommand = find->second.get();
154 }
155 m_selectedCommand->Initialize();
156}
157
158} // namespace wpi::cmd
159
160#ifdef _WIN32
161#pragma warning(pop)
162#endif
A state machine representing a complete action to be performed by the robot.
Definition Command.hpp:41
InterruptionBehavior
An enum describing the command's behavior when another command with a shared requirement is scheduled...
Definition Command.hpp:173
@ kCancelSelf
This command ends, End(true) is called, and the incoming command is scheduled normally.
Definition Command.hpp:180
@ kCancelIncoming
This command continues, and the incoming command is not scheduled.
Definition Command.hpp:182
void InitSendable(wpi::util::SendableBuilder &builder) override
Initializes this Sendable object.
void RequireUngroupedAndUnscheduled(const Command *command)
Requires that the specified command has not already been added to a composition and is not currently ...
static CommandScheduler & GetInstance()
Returns the Scheduler instance.
SelectCommand(const SelectCommand &other)=delete
void Initialize() override
Definition SelectCommand.hpp:148
void Execute() override
Definition SelectCommand.hpp:106
bool IsFinished() override
Definition SelectCommand.hpp:112
void End(bool interrupted) override
Definition SelectCommand.hpp:108
void InitSendable(wpi::util::SendableBuilder &builder) override
Definition SelectCommand.hpp:120
Command::InterruptionBehavior GetInterruptionBehavior() const override
Definition SelectCommand.hpp:116
SelectCommand(SelectCommand &&other)=default
bool RunsWhenDisabled() const override
Definition SelectCommand.hpp:114
SelectCommand(std::function< Key()> selector, std::pair< Key, Commands >... commands)
Creates a new SelectCommand.
Definition SelectCommand.hpp:46
SelectCommand(SelectCommand &)=delete
SelectCommand(std::function< Key()> selector, std::vector< std::pair< Key, std::unique_ptr< Command > > > &&commands)
Definition SelectCommand.hpp:74
Helper class for building Sendable dashboard representations.
Definition SendableBuilder.hpp:21
virtual void AddStringProperty(std::string_view key, std::function< std::string()> getter, std::function< void(std::string_view)> setter)=0
Add a string property.
Definition StringMap.hpp:773
Definition CommandNiDsStadiaController.hpp:15