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..f87e9ea4a96 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 @@ -218,6 +218,56 @@ public ParallelRaceGroup onlyWhile(BooleanSupplier condition) { return until(() -> !condition.getAsBoolean()); } + /** + * Decorates this command to run once a condition becomes true. + * + *

Note: This decorator works by adding this command to a composition. The command the + * decorator was called on cannot be scheduled independently or be added to a different + * composition (namely, decorators), unless it is manually cleared from the list of composed + * commands with {@link CommandScheduler#removeComposedCommand(Command)}. The command composition + * returned from this method can be further decorated without issue. + * + * @param condition the condition to wait for + * @return the decorated command + */ + public SequentialCommandGroup after(BooleanSupplier condition) { + // if we want this to bypass the `WaitUntilCommand` if the condition is already true, + // we can use a conditional command but it proposes some compositional issues + return new SequentialCommandGroup(new WaitUntilCommand(condition), this); + } + + /** + * Decorates this command to run after a time delay. + * + *

Note: This decorator works by adding this command to a composition. The command the + * decorator was called on cannot be scheduled independently or be added to a different + * composition (namely, decorators), unless it is manually cleared from the list of composed + * commands with {@link CommandScheduler#removeComposedCommand(Command)}. The command composition + * returned from this method can be further decorated without issue. + * + * @param seconds the seconds to wait + * @return the decorated command + */ + public SequentialCommandGroup afterSeconds(double seconds) { + return new SequentialCommandGroup(new WaitCommand(seconds), this); + } + + /** + * Decorates this command to run after a time delay. + * + *

Note: This decorator works by adding this command to a composition. The command the + * decorator was called on cannot be scheduled independently or be added to a different + * composition (namely, decorators), unless it is manually cleared from the list of composed + * commands with {@link CommandScheduler#removeComposedCommand(Command)}. The command composition + * returned from this method can be further decorated without issue. + * + * @param time the time to wait + * @return the decorated command + */ + public SequentialCommandGroup afterTime(Time time) { + return afterSeconds(time.in(Seconds)); + } + /** * Decorates this command with a runnable to run before this command starts. * diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp index ff5e8f6aa51..bf549c5d20b 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp @@ -84,6 +84,14 @@ CommandPtr Command::OnlyWhile(std::function condition) && { return std::move(*this).ToPtr().OnlyWhile(std::move(condition)); } +CommandPtr After(std::function condition) && { + return std::move(*this).ToPtr().After(std::move(condition)); +} + +CommandPtr AfterTime(units::second_t duration) && { + return std::move(*this).ToPtr().AfterTime(duration); +} + CommandPtr Command::IgnoringDisable(bool doesRunWhenDisabled) && { return std::move(*this).ToPtr().IgnoringDisable(doesRunWhenDisabled); } diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp index ee7182a7847..f4515e73553 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/CommandPtr.cpp @@ -165,6 +165,24 @@ CommandPtr CommandPtr::OnlyIf(std::function condition) && { return std::move(*this).Unless(std::not_fn(std::move(condition))); } +CommandPtr CommandPtr::After(std::function condition) && { + AssertValid(); + std::vector> temp; + temp.emplace_back(std::make_unique(std::move(condition))); + temp.emplace_back(std::move(m_ptr)); + m_ptr = std::make_unique(std::move(temp)); + return std::move(*this); +} + +CommandPtr CommandPtr::AfterTime(units::second_t duration) && { + AssertValid(); + std::vector> temp; + temp.emplace_back(std::make_unique(duration)); + temp.emplace_back(std::move(m_ptr)); + m_ptr = std::make_unique(std::move(temp)); + return std::move(*this); +} + CommandPtr CommandPtr::DeadlineWith(CommandPtr&& parallel) && { AssertValid(); std::vector> vec; diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Command.h b/wpilibNewCommands/src/main/native/include/frc2/command/Command.h index c4af1afe81b..e1228614be4 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/Command.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/Command.h @@ -217,6 +217,24 @@ class Command : public wpi::Sendable, public wpi::SendableHelper { [[nodiscard]] CommandPtr OnlyWhile(std::function condition) &&; + /** + * Decorates this command to run after a condition becomes true. + * + * @param condition the condition to run after + * @return the decorated command + */ + [[nodiscard]] + CommandPtr After(std::function condition) &&; + + /** + * Decorates this command to run after a specified amount of time. + * + * @param duration the time to wait before running + * @return the decorated command + */ + [[nodiscard]] + CommandPtr AfterTime(units::second_t duration) &&; + /** * Decorates this command with a runnable to run before this command starts. * diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h index e2f534f7547..b3bb65ded04 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/CommandPtr.h @@ -182,6 +182,24 @@ class CommandPtr final { [[nodiscard]] CommandPtr OnlyIf(std::function condition) &&; + /** + * Decorates this command to run after a condition becomes true. + * + * @param condition the condition to run after + * @return the decorated command + */ + [[nodiscard]] + CommandPtr After(std::function condition) &&; + + /** + * Decorates this command to run after a specified amount of time. + * + * @param duration the time to wait before running + * @return the decorated command + */ + [[nodiscard]] + CommandPtr AfterTime(units::second_t duration) &&; + /** * Decorates this command with a set of commands to run parallel to it, ending * when the calling command ends and interrupting all the others. Often more