Files
allwpilib/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h
2023-05-31 22:10:53 -07:00

285 lines
7.6 KiB
C++

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <functional>
#include <initializer_list>
#include <memory>
#include <span>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "frc2/command/CommandPtr.h"
#include "frc2/command/SelectCommand.h"
namespace frc2 {
class Subsystem;
/**
* Namespace for command factories.
*/
namespace cmd {
/**
* Constructs a command that does nothing, finishing immediately.
*/
[[nodiscard]]
CommandPtr None();
// Action Commands
/**
* Constructs a command that runs an action once and finishes.
*
* @param action the action to run
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr RunOnce(std::function<void()> action,
std::initializer_list<Subsystem*> requirements);
/**
* Constructs a command that runs an action once and finishes.
*
* @param action the action to run
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr RunOnce(std::function<void()> action,
std::span<Subsystem* const> requirements = {});
/**
* Constructs a command that runs an action every iteration until interrupted.
*
* @param action the action to run
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr Run(std::function<void()> action,
std::initializer_list<Subsystem*> requirements);
/**
* Constructs a command that runs an action every iteration until interrupted.
*
* @param action the action to run
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr Run(std::function<void()> action,
std::span<Subsystem* const> requirements = {});
/**
* Constructs a command that runs an action once and another action when the
* command is interrupted.
*
* @param start the action to run on start
* @param end the action to run on interrupt
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr StartEnd(std::function<void()> start, std::function<void()> end,
std::initializer_list<Subsystem*> requirements);
/**
* Constructs a command that runs an action once and another action when the
* command is interrupted.
*
* @param start the action to run on start
* @param end the action to run on interrupt
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr StartEnd(std::function<void()> start, std::function<void()> end,
std::span<Subsystem* const> requirements = {});
/**
* Constructs a command that runs an action every iteration until interrupted,
* and then runs a second action.
*
* @param run the action to run every iteration
* @param end the action to run on interrupt
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr RunEnd(std::function<void()> run, std::function<void()> end,
std::initializer_list<Subsystem*> requirements);
/**
* Constructs a command that runs an action every iteration until interrupted,
* and then runs a second action.
*
* @param run the action to run every iteration
* @param end the action to run on interrupt
* @param requirements subsystems the action requires
*/
[[nodiscard]]
CommandPtr RunEnd(std::function<void()> run, std::function<void()> end,
std::span<Subsystem* const> requirements = {});
/**
* Constructs a command that prints a message and finishes.
*
* @param msg the message to print
*/
[[nodiscard]]
CommandPtr Print(std::string_view msg);
// Idling Commands
/**
* Constructs a command that does nothing, finishing after a specified duration.
*
* @param duration after how long the command finishes
*/
[[nodiscard]]
CommandPtr Wait(units::second_t duration);
/**
* Constructs a command that does nothing, finishing once a condition becomes
* true.
*
* @param condition the condition
*/
[[nodiscard]]
CommandPtr WaitUntil(std::function<bool()> condition);
// Selector Commands
/**
* Runs one of two commands, based on the boolean selector function.
*
* @param onTrue the command to run if the selector function returns true
* @param onFalse the command to run if the selector function returns false
* @param selector the selector function
*/
[[nodiscard]]
CommandPtr Either(CommandPtr&& onTrue, CommandPtr&& onFalse,
std::function<bool()> selector);
/**
* Runs one of several commands, based on the selector function.
*
* @param selector the selector function
* @param commands map of commands to select from
*/
template <typename Key, class... Types>
[[nodiscard]]
CommandPtr Select(std::function<Key()> selector,
std::pair<Key, Types>&&... commands) {
std::vector<std::pair<Key, std::unique_ptr<Command>>> vec;
((void)vec.emplace_back(commands.first, std::move(commands.second).Unwrap()),
...);
return SelectCommand(std::move(selector), std::move(vec)).ToPtr();
}
// Command Groups
namespace impl {
/**
* Create a vector of commands.
*/
template <typename... Args>
std::vector<CommandPtr> MakeVector(Args&&... args) {
std::vector<CommandPtr> data;
data.reserve(sizeof...(Args));
(data.emplace_back(std::forward<Args>(args)), ...);
return data;
}
} // namespace impl
/**
* Runs a group of commands in series, one after the other.
*/
[[nodiscard]]
CommandPtr Sequence(std::vector<CommandPtr>&& commands);
/**
* Runs a group of commands in series, one after the other.
*/
template <typename... Args>
[[nodiscard]]
CommandPtr Sequence(Args&&... commands) {
return Sequence(impl::MakeVector(std::forward<Args>(commands)...));
}
/**
* Runs a group of commands in series, one after the other. Once the last
* command ends, the group is restarted.
*/
[[nodiscard]]
CommandPtr RepeatingSequence(std::vector<CommandPtr>&& commands);
/**
* Runs a group of commands in series, one after the other. Once the last
* command ends, the group is restarted.
*/
template <typename... Args>
[[nodiscard]]
CommandPtr RepeatingSequence(Args&&... commands) {
return RepeatingSequence(impl::MakeVector(std::forward<Args>(commands)...));
}
/**
* Runs a group of commands at the same time. Ends once all commands in the
* group finish.
*/
[[nodiscard]]
CommandPtr Parallel(std::vector<CommandPtr>&& commands);
/**
* Runs a group of commands at the same time. Ends once all commands in the
* group finish.
*/
template <typename... Args>
[[nodiscard]]
CommandPtr Parallel(Args&&... commands) {
return Parallel(impl::MakeVector(std::forward<Args>(commands)...));
}
/**
* Runs a group of commands at the same time. Ends once any command in the group
* finishes, and cancels the others.
*/
[[nodiscard]]
CommandPtr Race(std::vector<CommandPtr>&& commands);
/**
* Runs a group of commands at the same time. Ends once any command in the group
* finishes, and cancels the others.
*/
template <typename... Args>
[[nodiscard]]
CommandPtr Race(Args&&... commands) {
return Race(impl::MakeVector(std::forward<Args>(commands)...));
}
/**
* Runs a group of commands at the same time. Ends once a specific command
* finishes, and cancels the others.
*/
[[nodiscard]]
CommandPtr Deadline(CommandPtr&& deadline, std::vector<CommandPtr>&& others);
/**
* Runs a group of commands at the same time. Ends once a specific command
* finishes, and cancels the others.
*/
template <typename... Args>
[[nodiscard]]
CommandPtr Deadline(CommandPtr&& deadline, Args&&... commands) {
return Deadline(std::move(deadline),
impl::MakeVector(std::forward<Args>(commands)...));
}
} // namespace cmd
} // namespace frc2