mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
Split the two command implementations into separate libraries (#2012)
This will allow us at the user code side to determine to include old commands, new commands or both.
This commit is contained in:
committed by
Peter Johnson
parent
2ad15cae19
commit
509819d83f
242
wpilibNewCommands/src/main/native/include/frc2/command/Command.h
Normal file
242
wpilibNewCommands/src/main/native/include/frc2/command/Command.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2019 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <frc/ErrorBase.h>
|
||||
#include <frc/WPIErrors.h>
|
||||
#include <frc2/command/Subsystem.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <units/units.h>
|
||||
#include <wpi/ArrayRef.h>
|
||||
#include <wpi/Demangle.h>
|
||||
#include <wpi/SmallSet.h>
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
namespace frc2 {
|
||||
|
||||
template <typename T>
|
||||
std::string GetTypeName(const T& type) {
|
||||
return wpi::Demangle(typeid(type).name());
|
||||
}
|
||||
|
||||
class ParallelCommandGroup;
|
||||
class ParallelRaceGroup;
|
||||
class ParallelDeadlineGroup;
|
||||
class SequentialCommandGroup;
|
||||
class PerpetualCommand;
|
||||
class ProxyScheduleCommand;
|
||||
|
||||
/**
|
||||
* A state machine representing a complete action to be performed by the robot.
|
||||
* Commands are run by the CommandScheduler, and can be composed into
|
||||
* CommandGroups to allow users to build complicated multi-step actions without
|
||||
* the need to roll the state machine logic themselves.
|
||||
*
|
||||
* <p>Commands are run synchronously from the main robot loop; no multithreading
|
||||
* is used, unless specified explicitly from the command implementation.
|
||||
*
|
||||
* <p>Note: ALWAYS create a subclass by extending CommandHelper<Base, Subclass>,
|
||||
* or decorators will not function!
|
||||
*
|
||||
* @see CommandScheduler
|
||||
* @see CommandHelper
|
||||
*/
|
||||
class Command : public frc::ErrorBase {
|
||||
public:
|
||||
Command() = default;
|
||||
virtual ~Command();
|
||||
|
||||
Command(const Command&);
|
||||
Command& operator=(const Command&);
|
||||
Command(Command&&) = default;
|
||||
Command& operator=(Command&&) = default;
|
||||
|
||||
/**
|
||||
* The initial subroutine of a command. Called once when the command is
|
||||
* initially scheduled.
|
||||
*/
|
||||
virtual void Initialize();
|
||||
|
||||
/**
|
||||
* The main body of a command. Called repeatedly while the command is
|
||||
* scheduled.
|
||||
*/
|
||||
virtual void Execute();
|
||||
|
||||
/**
|
||||
* The action to take when the command ends. Called when either the command
|
||||
* finishes normally, or when it interrupted/canceled.
|
||||
*
|
||||
* @param interrupted whether the command was interrupted/canceled
|
||||
*/
|
||||
virtual void End(bool interrupted);
|
||||
|
||||
/**
|
||||
* Whether the command has finished. Once a command finishes, the scheduler
|
||||
* will call its end() method and un-schedule it.
|
||||
*
|
||||
* @return whether the command has finished.
|
||||
*/
|
||||
virtual bool IsFinished() { return false; }
|
||||
|
||||
/**
|
||||
* Specifies the set of subsystems used by this command. Two commands cannot
|
||||
* use the same subsystem at the same time. If the command is scheduled as
|
||||
* interruptible and another command is scheduled that shares a requirement,
|
||||
* the command will be interrupted. Else, the command will not be scheduled.
|
||||
* If no subsystems are required, return an empty set.
|
||||
*
|
||||
* <p>Note: it is recommended that user implementations contain the
|
||||
* requirements as a field, and return that field here, rather than allocating
|
||||
* a new set every time this is called.
|
||||
*
|
||||
* @return the set of subsystems that are required
|
||||
*/
|
||||
virtual wpi::SmallSet<Subsystem*, 4> GetRequirements() const = 0;
|
||||
|
||||
/**
|
||||
* Decorates this command with a timeout. If the specified timeout is
|
||||
* exceeded before the command finishes normally, the command will be
|
||||
* interrupted and un-scheduled. Note that the timeout only applies to the
|
||||
* command returned by this method; the calling command is not itself changed.
|
||||
*
|
||||
* @param duration the timeout duration
|
||||
* @return the command with the timeout added
|
||||
*/
|
||||
ParallelRaceGroup WithTimeout(units::second_t duration) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with an interrupt condition. If the specified
|
||||
* condition becomes true before the command finishes normally, the command
|
||||
* will be interrupted and un-scheduled. Note that this only applies to the
|
||||
* command returned by this method; the calling command is not itself changed.
|
||||
*
|
||||
* @param condition the interrupt condition
|
||||
* @return the command with the interrupt condition added
|
||||
*/
|
||||
ParallelRaceGroup WithInterrupt(std::function<bool()> condition) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a runnable to run before this command starts.
|
||||
*
|
||||
* @param toRun the Runnable to run
|
||||
* @return the decorated command
|
||||
*/
|
||||
SequentialCommandGroup BeforeStarting(std::function<void()> toRun) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command with a runnable to run after the command finishes.
|
||||
*
|
||||
* @param toRun the Runnable to run
|
||||
* @return the decorated command
|
||||
*/
|
||||
SequentialCommandGroup AndThen(std::function<void()> toRun) &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run perpetually, ignoring its ordinary end
|
||||
* conditions. The decorated command can still be interrupted or canceled.
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
PerpetualCommand Perpetually() &&;
|
||||
|
||||
/**
|
||||
* Decorates this command to run "by proxy" by wrapping it in a {@link
|
||||
* ProxyScheduleCommand}. This is useful for "forking off" from command groups
|
||||
* when the user does not wish to extend the command's requirements to the
|
||||
* entire command group.
|
||||
*
|
||||
* @return the decorated command
|
||||
*/
|
||||
ProxyScheduleCommand AsProxy();
|
||||
|
||||
/**
|
||||
* Schedules this command.
|
||||
*
|
||||
* @param interruptible whether this command can be interrupted by another
|
||||
* command that shares one of its requirements
|
||||
*/
|
||||
void Schedule(bool interruptible);
|
||||
|
||||
/**
|
||||
* Schedules this command, defaulting to interruptible.
|
||||
*/
|
||||
void Schedule() { Schedule(true); }
|
||||
|
||||
/**
|
||||
* Cancels this command. Will call the command's interrupted() method.
|
||||
* Commands will be canceled even if they are not marked as interruptible.
|
||||
*/
|
||||
void Cancel();
|
||||
|
||||
/**
|
||||
* Whether or not the command is currently scheduled. Note that this does not
|
||||
* detect whether the command is being run by a CommandGroup, only whether it
|
||||
* is directly being run by the scheduler.
|
||||
*
|
||||
* @return Whether the command is scheduled.
|
||||
*/
|
||||
bool IsScheduled() const;
|
||||
|
||||
/**
|
||||
* Whether the command requires a given subsystem. Named "hasRequirement"
|
||||
* rather than "requires" to avoid confusion with
|
||||
* {@link
|
||||
* edu.wpi.first.wpilibj.command.Command#requires(edu.wpi.first.wpilibj.command.Subsystem)}
|
||||
* - this may be able to be changed in a few years.
|
||||
*
|
||||
* @param requirement the subsystem to inquire about
|
||||
* @return whether the subsystem is required
|
||||
*/
|
||||
bool HasRequirement(Subsystem* requirement) const;
|
||||
|
||||
/**
|
||||
* Whether the command is currently grouped in a command group. Used as extra
|
||||
* insurance to prevent accidental independent use of grouped commands.
|
||||
*/
|
||||
bool IsGrouped() const;
|
||||
|
||||
/**
|
||||
* Sets whether the command is currently grouped in a command group. Can be
|
||||
* used to "reclaim" a command if a group is no longer going to use it. NOT
|
||||
* ADVISED!
|
||||
*/
|
||||
void SetGrouped(bool grouped);
|
||||
|
||||
/**
|
||||
* Whether the given command should run when the robot is disabled. Override
|
||||
* to return true if the command should run when disabled.
|
||||
*
|
||||
* @return whether the command should run when the robot is disabled
|
||||
*/
|
||||
virtual bool RunsWhenDisabled() const { return false; }
|
||||
|
||||
virtual std::string GetName() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Transfers ownership of this command to a unique pointer. Used for
|
||||
* decorator methods.
|
||||
*/
|
||||
virtual std::unique_ptr<Command> TransferOwnership() && = 0;
|
||||
|
||||
bool m_isGrouped = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if two commands have disjoint requirement sets.
|
||||
*
|
||||
* @param first The first command to check.
|
||||
* @param second The second command to check.
|
||||
* @return False if first and second share a requirement.
|
||||
*/
|
||||
bool RequirementsDisjoint(Command* first, Command* second);
|
||||
} // namespace frc2
|
||||
Reference in New Issue
Block a user