diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java index a53d792d0e4..10974f45b11 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Command.java @@ -398,6 +398,23 @@ public ProxyCommand asProxy() { return new ProxyCommand(this); } + /** + * Decorates this command to run "forked" by wrapping it in a {@link ScheduleCommand}. Use this + * for "forking off" from command compositions when the user does not wish to extend the command's + * requirements to the entire command composition. Note that if run from a composition, the + * composition will not know about the status of the scheduled commands, and will treat this + * command as finishing instantly. + * + * @return the decorated command + * @see ScheduleCommand + * @see WPILib + * docs + */ + public ScheduleCommand fork() { + return new ScheduleCommand(this); + } + /** * Decorates this command to only run if this condition is not met. If the command is already * running and the condition changes to true, the command will not stop running. The requirements diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java index c53409a033d..8c81106f83b 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java @@ -209,6 +209,25 @@ public static Command deferredProxy(Supplier supplier) { return new ProxyCommand(supplier); } + /** + * Constructs a command by wrapping the provided commands in a {@link ScheduleCommand}. Use this + * for "forking off" from command compositions when the user does not wish to extend the command's + * requirements to the entire command composition. Note that if run from a composition, the + * composition will not know about the status of the scheduled commands, and will treat this + * command as finishing instantly. Multiple commands can be added to this and will be scheduled in + * order. + * + * @param commands the commands to schedule in order + * @return the command + * @see ScheduleCommand + * @see WPILib + * docs + */ + public static Command fork(Command... commands) { + return new ScheduleCommand(commands); + } + // Command Groups /** diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp index 298cc2e50ca..6b373b7f01e 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp @@ -18,6 +18,7 @@ #include "frc2/command/ParallelRaceGroup.h" #include "frc2/command/ProxyCommand.h" #include "frc2/command/RepeatCommand.h" +#include "frc2/command/ScheduleCommand.h" #include "frc2/command/SequentialCommandGroup.h" #include "frc2/command/WaitCommand.h" #include "frc2/command/WaitUntilCommand.h" @@ -56,6 +57,13 @@ CommandPtr CommandPtr::AsProxy() && { return std::move(*this); } +CommandPtr CommandPtr::Fork() && { + AssertValid(); + std::vector vec{m_ptr.get()}; + m_ptr = make_unique(std::span(vec)); + return std::move(*this); +} + class RunsWhenDisabledCommand : public WrapperCommand { public: RunsWhenDisabledCommand(std::unique_ptr&& command, diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp index bc4bd39da73..0650d6e4be3 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/Commands.cpp @@ -6,7 +6,7 @@ #include #include - +#include #include #include "frc2/command/ConditionalCommand.h" @@ -83,6 +83,21 @@ CommandPtr cmd::DeferredProxy(wpi::unique_function supplier) { } WPI_UNIGNORE_DEPRECATED +CommandPtr cmd::Fork(CommandPtr&& other) { + std::vector vec{other.get()}; + auto m_ptr = make_unique(std::span(vec)); + return ScheduleCommand(std::move(*m_ptr)).ToPtr(); +} + +CommandPtr cmd::Fork(std::vector&& commands) { + std::vector vec{}; + for (auto&& ptr : commands) { + vec.emplace_back(std::move(ptr).Unwrap().get()); + } + auto m_ptr = make_unique(std::span(vec)); + return ScheduleCommand(std::move(*m_ptr)).ToPtr(); +} + CommandPtr cmd::Wait(units::second_t duration) { return WaitCommand(duration).ToPtr(); } diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h index e2f534f7547..17fa93c8b3a 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h @@ -63,6 +63,20 @@ class CommandPtr final { [[nodiscard]] CommandPtr AsProxy() &&; + /** + * Decorates this command to run "forked" by wrapping it in a {@link + * ScheduleCommand}. Use this for "forking off" from command compositions when + * the user does not wish to extend the command's requirements to the entire + * command composition. Note that if run from a composition, the composition + * will not know about the status of the scheduled commands, and will treat + * this command as finishing instantly. + * + * @return the decorated command + * @see ScheduleCommand + */ + [[nodiscard]] + CommandPtr Fork() &&; + /** * Decorates this command to run or stop when disabled. * diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h index 6cfad01b1f0..fca01f1f11d 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/Commands.h @@ -16,6 +16,7 @@ #include "frc2/command/CommandPtr.h" #include "frc2/command/Requirements.h" +#include "frc2/command/ScheduleCommand.h" #include "frc2/command/SelectCommand.h" namespace frc2 { @@ -192,6 +193,36 @@ CommandPtr DeferredProxy(wpi::unique_function supplier); "Defer(supplier).AsProxy() instead.")]] CommandPtr DeferredProxy(wpi::unique_function supplier); WPI_UNIGNORE_DEPRECATED + + /** + * Constructs a command by wrapping the provided commands in a {@link ScheduleCommand}. Use this + * for "forking off" from command compositions when the user does not wish to extend the command's + * requirements to the entire command composition. Note that if run from a composition, the + * composition will not know about the status of the scheduled commands, and will treat this + * command as finishing instantly. Multiple commands can be added to this and will be scheduled in order. + * + * @param commands the commands to schedule in order + * @return the command + * @see ScheduleCommand + */ + [[nodiscard]] + CommandPtr Fork(CommandPtr&& commands); + + /** + * Constructs a command by wrapping the provided commands in a {@link ScheduleCommand}. Use this + * for "forking off" from command compositions when the user does not wish to extend the command's + * requirements to the entire command composition. Note that if run from a composition, the + * composition will not know about the status of the scheduled commands, and will treat this + * command as finishing instantly. Multiple commands can be added to this and will be scheduled in order. + * + * @param commands the commands to schedule in order + * @return the command + * @see ScheduleCommand + */ + [[nodiscard]] + CommandPtr Fork(std::vector&& commands); + + // Command Groups namespace impl {