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 bc464f34d6..82c6bc4995 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 @@ -91,10 +91,29 @@ public interface Command { * @param condition the interrupt condition * @return the command with the interrupt condition added */ - default ParallelRaceGroup withInterrupt(BooleanSupplier condition) { + default ParallelRaceGroup until(BooleanSupplier condition) { return raceWith(new WaitUntilCommand(condition)); } + /** + * 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. + * + *

Note: This decorator works by composing this command within a CommandGroup. The command + * cannot be used independently after being decorated, or be re-decorated with a different + * decorator, unless it is manually cleared from the list of grouped commands with {@link + * CommandGroupBase#clearGroupedCommand(Command)}. The decorated command can, however, be further + * decorated without issue. + * + * @param condition the interrupt condition + * @return the command with the interrupt condition added + */ + default ParallelRaceGroup withInterrupt(BooleanSupplier condition) { + return until(condition); + } + /** * Decorates this command with a runnable to run before this command starts. * diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/NotifierCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/NotifierCommand.java index 751c5075e5..730ef1bcc6 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/NotifierCommand.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/NotifierCommand.java @@ -9,7 +9,7 @@ import edu.wpi.first.wpilibj.Notifier; /** * A command that starts a notifier to run the given runnable periodically in a separate thread. Has * no end condition as-is; either subclass it or use {@link Command#withTimeout(double)} or {@link - * Command#withInterrupt(java.util.function.BooleanSupplier)} to give it one. + * Command#until(java.util.function.BooleanSupplier)} to give it one. * *

WARNING: Do not use this class unless you are confident in your ability to make the executed * code thread-safe. If you do not know what "thread-safe" means, that is a good sign that you diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RunCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RunCommand.java index c48f6c8d75..2ae1c9214f 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RunCommand.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RunCommand.java @@ -10,8 +10,8 @@ import java.util.function.BooleanSupplier; /** * A command that runs a Runnable continuously. Has no end condition as-is; either subclass it or - * use {@link Command#withTimeout(double)} or {@link Command#withInterrupt(BooleanSupplier)} to give - * it one. If you only wish to execute a Runnable once, use {@link InstantCommand}. + * use {@link Command#withTimeout(double)} or {@link Command#until(BooleanSupplier)} to give it one. + * If you only wish to execute a Runnable once, use {@link InstantCommand}. * *

This class is provided by the NewCommands VendorDep */ diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/StartEndCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/StartEndCommand.java index 5fd6a7ced6..8c0b99e42a 100644 --- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/StartEndCommand.java +++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/StartEndCommand.java @@ -10,7 +10,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam; * A command that runs a given runnable when it is initialized, and another runnable when it ends. * Useful for running and then stopping a motor, or extending and then retracting a solenoid. Has no * end condition as-is; either subclass it or use {@link Command#withTimeout(double)} or {@link - * Command#withInterrupt(java.util.function.BooleanSupplier)} to give it one. + * Command#until(java.util.function.BooleanSupplier)} to give it one. * *

This class is provided by the NewCommands VendorDep */ diff --git a/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp b/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp index b434c1be05..ea6276b50b 100644 --- a/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp +++ b/wpilibNewCommands/src/main/native/cpp/frc2/command/Command.cpp @@ -37,6 +37,13 @@ ParallelRaceGroup Command::WithTimeout(units::second_t duration) && { return ParallelRaceGroup(std::move(temp)); } +ParallelRaceGroup Command::Until(std::function condition) && { + std::vector> temp; + temp.emplace_back(std::make_unique(std::move(condition))); + temp.emplace_back(std::move(*this).TransferOwnership()); + return ParallelRaceGroup(std::move(temp)); +} + ParallelRaceGroup Command::WithInterrupt(std::function condition) && { std::vector> temp; temp.emplace_back(std::make_unique(std::move(condition))); diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/Command.h b/wpilibNewCommands/src/main/native/include/frc2/command/Command.h index a19441b274..f8da72815b 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/Command.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/Command.h @@ -111,6 +111,17 @@ class Command { */ virtual 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 + */ + virtual ParallelRaceGroup Until(std::function condition) &&; + /** * Decorates this command with an interrupt condition. If the specified * condition becomes true before the command finishes normally, the command diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/NotifierCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/NotifierCommand.h index ec77134361..d2be98544c 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/NotifierCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/NotifierCommand.h @@ -18,7 +18,7 @@ namespace frc2 { /** * A command that starts a notifier to run the given runnable periodically in a * separate thread. Has no end condition as-is; either subclass it or use - * Command::WithTimeout(double) or Command::WithInterrupt(BooleanSupplier) to + * Command::WithTimeout(double) or Command::Until(BooleanSupplier) to * give it one. * *

WARNING: Do not use this class unless you are confident in your ability to diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/RunCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/RunCommand.h index 692aff59e6..b9e1efd624 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/RunCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/RunCommand.h @@ -16,7 +16,7 @@ namespace frc2 { /** * A command that runs a Runnable continuously. Has no end condition as-is; * either subclass it or use Command.WithTimeout() or - * Command.WithInterrupt() to give it one. If you only wish + * Command.Until() to give it one. If you only wish * to execute a Runnable once, use InstantCommand. * * This class is provided by the NewCommands VendorDep diff --git a/wpilibNewCommands/src/main/native/include/frc2/command/StartEndCommand.h b/wpilibNewCommands/src/main/native/include/frc2/command/StartEndCommand.h index 908420dff8..e5af2bbc43 100644 --- a/wpilibNewCommands/src/main/native/include/frc2/command/StartEndCommand.h +++ b/wpilibNewCommands/src/main/native/include/frc2/command/StartEndCommand.h @@ -17,7 +17,7 @@ namespace frc2 { * A command that runs a given runnable when it is initialized, and another * runnable when it ends. Useful for running and then stopping a motor, or * extending and then retracting a solenoid. Has no end condition as-is; either - * subclass it or use Command.WithTimeout() or Command.WithInterrupt() to give + * subclass it or use Command.WithTimeout() or Command.Until() to give * it one. * * This class is provided by the NewCommands VendorDep diff --git a/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandDecoratorTest.java b/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandDecoratorTest.java index b2f482c113..66593ca414 100644 --- a/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandDecoratorTest.java +++ b/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandDecoratorTest.java @@ -39,11 +39,11 @@ class CommandDecoratorTest extends CommandTestBase { } @Test - void withInterruptTest() { + void untilTest() { try (CommandScheduler scheduler = new CommandScheduler()) { ConditionHolder condition = new ConditionHolder(); - Command command = new WaitCommand(10).withInterrupt(condition::getCondition); + Command command = new WaitCommand(10).until(condition::getCondition); scheduler.schedule(command); scheduler.run(); diff --git a/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandGroupErrorTest.java b/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandGroupErrorTest.java index 8da92c751c..4fb44a50f6 100644 --- a/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandGroupErrorTest.java +++ b/wpilibNewCommands/src/test/java/edu/wpi/first/wpilibj2/command/CommandGroupErrorTest.java @@ -40,7 +40,7 @@ class CommandGroupErrorTest extends CommandTestBase { void redecoratedCommandErrorTest() { Command command = new InstantCommand(); - assertDoesNotThrow(() -> command.withTimeout(10).withInterrupt(() -> false)); + assertDoesNotThrow(() -> command.withTimeout(10).until(() -> false)); assertThrows(IllegalArgumentException.class, () -> command.withTimeout(10)); CommandGroupBase.clearGroupedCommand(command); assertDoesNotThrow(() -> command.withTimeout(10)); diff --git a/wpilibNewCommands/src/test/native/cpp/frc2/command/CommandDecoratorTest.cpp b/wpilibNewCommands/src/test/native/cpp/frc2/command/CommandDecoratorTest.cpp index 5ae17cc690..4a7c137a47 100644 --- a/wpilibNewCommands/src/test/native/cpp/frc2/command/CommandDecoratorTest.cpp +++ b/wpilibNewCommands/src/test/native/cpp/frc2/command/CommandDecoratorTest.cpp @@ -34,13 +34,12 @@ TEST_F(CommandDecoratorTest, WithTimeout) { frc::sim::ResumeTiming(); } -TEST_F(CommandDecoratorTest, WithInterrupt) { +TEST_F(CommandDecoratorTest, Until) { CommandScheduler scheduler = GetScheduler(); bool finished = false; - auto command = - RunCommand([] {}, {}).WithInterrupt([&finished] { return finished; }); + auto command = RunCommand([] {}, {}).Until([&finished] { return finished; }); scheduler.Schedule(&command);