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 0fecef2338..63459c8308 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
@@ -67,11 +67,11 @@ public interface 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.
*
- *
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.
+ *
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 timeout duration
* @return the command with the timeout added
@@ -86,11 +86,11 @@ public interface Command {
* 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.
+ *
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 interrupt condition
* @return the command with the interrupt condition added
@@ -105,11 +105,11 @@ public interface Command {
* 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.
+ *
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 interrupt condition
* @return the command with the interrupt condition added
@@ -123,11 +123,11 @@ public interface Command {
/**
* Decorates this command with a runnable to run before this command starts.
*
- *
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.
+ *
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 toRun the Runnable to run
* @param requirements the required subsystems
@@ -140,11 +140,11 @@ public interface Command {
/**
* Decorates this command with another command to run before this command starts.
*
- *
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.
+ *
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 before the command to run before this one
* @return the decorated command
@@ -156,11 +156,11 @@ public interface Command {
/**
* Decorates this command with a runnable to run after the command finishes.
*
- *
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.
+ *
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 toRun the Runnable to run
* @param requirements the required subsystems
@@ -174,11 +174,11 @@ public interface Command {
* Decorates this command with a set of commands to run after it in sequence. Often more
* convenient/less-verbose than constructing a new {@link SequentialCommandGroup} explicitly.
*
- *
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.
+ *
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 next the commands to run next
* @return the decorated command
@@ -194,11 +194,11 @@ public interface Command {
* command ends and interrupting all the others. Often more convenient/less-verbose than
* constructing a new {@link ParallelDeadlineGroup} explicitly.
*
- *
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.
+ *
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 parallel the commands to run in parallel
* @return the decorated command
@@ -212,11 +212,11 @@ public interface Command {
* command ends. Often more convenient/less-verbose than constructing a new {@link
* ParallelCommandGroup} explicitly.
*
- *
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.
+ *
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 parallel the commands to run in parallel
* @return the decorated command
@@ -232,11 +232,11 @@ public interface Command {
* command ends. Often more convenient/less-verbose than constructing a new {@link
* ParallelRaceGroup} explicitly.
*
- *
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.
+ *
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 parallel the commands to run in parallel
* @return the decorated command
@@ -251,11 +251,11 @@ public interface Command {
* Decorates this command to run perpetually, ignoring its ordinary end conditions. The decorated
* command can still be interrupted or canceled.
*
- *
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.
+ *
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.
*
* @return the decorated command
* @deprecated PerpetualCommand violates the assumption that execute() doesn't get called after
@@ -273,11 +273,11 @@ public interface Command {
* Decorates this command to run repeatedly, restarting it when it ends, until this command is
* interrupted. The decorated command can still be canceled.
*
- *
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.
+ *
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.
*
* @return the decorated command
*/
@@ -287,8 +287,8 @@ public interface Command {
/**
* Decorates this command to run "by proxy" by wrapping it in a {@link ProxyCommand}. 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.
+ * useful for "forking off" from command compositions when the user does not wish to extend the
+ * command's requirements to the entire command composition.
*
* @return the decorated command
*/
@@ -391,7 +391,7 @@ public interface Command {
/**
* 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.
+ * command is in a composition, only whether it is directly being run by the scheduler.
*
* @return Whether the command is scheduled.
*/
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandBase.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandBase.java
index 25b2156c1d..30b8686d2b 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandBase.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandBase.java
@@ -104,6 +104,6 @@ public abstract class CommandBase implements Sendable, Command {
}
});
builder.addBooleanProperty(
- ".isParented", () -> CommandGroupBase.getGroupedCommands().contains(this), null);
+ ".isParented", () -> CommandScheduler.getInstance().isComposed(this), null);
}
}
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandGroupBase.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandGroupBase.java
index ad62554bcb..73a13423ee 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandGroupBase.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandGroupBase.java
@@ -4,75 +4,15 @@
package edu.wpi.first.wpilibj2.command;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-import java.util.WeakHashMap;
-
/**
- * A base for CommandGroups. Statically tracks commands that have been allocated to groups to ensure
- * those commands are not also used independently, which can result in inconsistent command state
- * and unpredictable execution.
+ * A base for CommandGroups.
*
*
This class is provided by the NewCommands VendorDep
+ *
+ * @deprecated This class is an empty abstraction. Inherit directly from CommandBase/Command.
*/
+@Deprecated(forRemoval = true)
public abstract class CommandGroupBase extends CommandBase {
- private static final Set m_groupedCommands =
- Collections.newSetFromMap(new WeakHashMap<>());
-
- static void registerGroupedCommands(Command... commands) {
- m_groupedCommands.addAll(Set.of(commands));
- }
-
- /**
- * Clears the list of grouped commands, allowing all commands to be freely used again.
- *
- *
WARNING: Using this haphazardly can result in unexpected/undesirable behavior. Do not use
- * this unless you fully understand what you are doing.
- */
- public static void clearGroupedCommands() {
- m_groupedCommands.clear();
- }
-
- /**
- * Removes a single command from the list of grouped commands, allowing it to be freely used
- * again.
- *
- *
WARNING: Using this haphazardly can result in unexpected/undesirable behavior. Do not use
- * this unless you fully understand what you are doing.
- *
- * @param command the command to remove from the list of grouped commands
- */
- public static void clearGroupedCommand(Command command) {
- m_groupedCommands.remove(command);
- }
-
- /**
- * Requires that the specified commands not have been already allocated to a CommandGroup. Throws
- * an {@link IllegalArgumentException} if commands have been allocated.
- *
- * @param commands The commands to check
- */
- public static void requireUngrouped(Command... commands) {
- requireUngrouped(Set.of(commands));
- }
-
- /**
- * Requires that the specified commands not have been already allocated to a CommandGroup. Throws
- * an {@link IllegalArgumentException} if commands have been allocated.
- *
- * @param commands The commands to check
- */
- public static void requireUngrouped(Collection commands) {
- if (!Collections.disjoint(commands, getGroupedCommands())) {
- throw new IllegalArgumentException("Commands cannot be added to more than one CommandGroup");
- }
- }
-
- static Set getGroupedCommands() {
- return m_groupedCommands;
- }
-
/**
* Adds the given commands to the command group.
*
@@ -85,8 +25,10 @@ public abstract class CommandGroupBase extends CommandBase {
*
* @param commands the commands to include
* @return the command group
+ * @deprecated Replace with {@link Commands#sequence(Command...)}
*/
- public static CommandGroupBase sequence(Command... commands) {
+ @Deprecated
+ public static SequentialCommandGroup sequence(Command... commands) {
return new SequentialCommandGroup(commands);
}
@@ -95,8 +37,10 @@ public abstract class CommandGroupBase extends CommandBase {
*
* @param commands the commands to include
* @return the command group
+ * @deprecated Replace with {@link Commands#parallel(Command...)}
*/
- public static CommandGroupBase parallel(Command... commands) {
+ @Deprecated
+ public static ParallelCommandGroup parallel(Command... commands) {
return new ParallelCommandGroup(commands);
}
@@ -105,8 +49,10 @@ public abstract class CommandGroupBase extends CommandBase {
*
* @param commands the commands to include
* @return the command group
+ * @deprecated Replace with {@link Commands#race(Command...)}
*/
- public static CommandGroupBase race(Command... commands) {
+ @Deprecated
+ public static ParallelRaceGroup race(Command... commands) {
return new ParallelRaceGroup(commands);
}
@@ -116,8 +62,10 @@ public abstract class CommandGroupBase extends CommandBase {
* @param deadline the deadline command
* @param commands the commands to include
* @return the command group
+ * @deprecated Replace with {@link Commands#deadline(Command, Command...)}
*/
- public static CommandGroupBase deadline(Command deadline, Command... commands) {
+ @Deprecated
+ public static ParallelDeadlineGroup deadline(Command deadline, Command... commands) {
return new ParallelDeadlineGroup(deadline, commands);
}
}
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandScheduler.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandScheduler.java
index 4fb89ac361..82d89f6fe1 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandScheduler.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/CommandScheduler.java
@@ -26,6 +26,7 @@ import edu.wpi.first.wpilibj.event.EventLoop;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj2.command.Command.InterruptionBehavior;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -33,6 +34,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.WeakHashMap;
import java.util.function.Consumer;
/**
@@ -60,6 +62,8 @@ public final class CommandScheduler implements NTSendable, AutoCloseable {
return instance;
}
+ private final Set m_composedCommands = Collections.newSetFromMap(new WeakHashMap<>());
+
// A set of the currently-running commands.
private final Set m_scheduledCommands = new LinkedHashSet<>();
@@ -208,10 +212,7 @@ public final class CommandScheduler implements NTSendable, AutoCloseable {
return;
}
- if (CommandGroupBase.getGroupedCommands().contains(command)) {
- throw new IllegalArgumentException(
- "A command that is part of a command group cannot be independently scheduled");
- }
+ requireNotComposed(command);
// Do nothing if the scheduler is disabled, the robot is disabled and the command doesn't
// run when disabled, or the command is already scheduled.
@@ -405,6 +406,8 @@ public final class CommandScheduler implements NTSendable, AutoCloseable {
return;
}
+ requireNotComposed(defaultCommand);
+
if (!defaultCommand.getRequirements().contains(subsystem)) {
throw new IllegalArgumentException("Default commands must require their subsystem!");
}
@@ -489,8 +492,8 @@ public final class CommandScheduler implements NTSendable, AutoCloseable {
/**
* Whether the given commands are running. Note that this only works on commands that are directly
- * scheduled by the scheduler; it will not work on commands inside of CommandGroups, as the
- * scheduler does not see them.
+ * scheduled by the scheduler; it will not work on commands inside compositions, as the scheduler
+ * does not see them.
*
* @param commands the command to query
* @return whether the command is currently scheduled
@@ -557,6 +560,85 @@ public final class CommandScheduler implements NTSendable, AutoCloseable {
m_finishActions.add(requireNonNullParam(action, "action", "onCommandFinish"));
}
+ /**
+ * Register commands as composed. An exception will be thrown if these commands are scheduled
+ * directly or added to a composition.
+ *
+ * @param commands the commands to register
+ * @throws IllegalArgumentException if the given commands have already been composed.
+ */
+ public void registerComposedCommands(Command... commands) {
+ var commandSet = Set.of(commands);
+ requireNotComposed(commandSet);
+ m_composedCommands.addAll(commandSet);
+ }
+
+ /**
+ * Clears the list of composed commands, allowing all commands to be freely used again.
+ *
+ *
WARNING: Using this haphazardly can result in unexpected/undesirable behavior. Do not use
+ * this unless you fully understand what you are doing.
+ */
+ public void clearComposedCommands() {
+ m_composedCommands.clear();
+ }
+
+ /**
+ * Removes a single command from the list of composed commands, allowing it to be freely used
+ * again.
+ *
+ *
WARNING: Using this haphazardly can result in unexpected/undesirable behavior. Do not use
+ * this unless you fully understand what you are doing.
+ *
+ * @param command the command to remove from the list of grouped commands
+ */
+ public void removeComposedCommand(Command command) {
+ m_composedCommands.remove(command);
+ }
+
+ /**
+ * Requires that the specified command hasn't been already added to a composition.
+ *
+ * @param command The command to check
+ * @throws IllegalArgumentException if the given commands have already been composed.
+ */
+ public void requireNotComposed(Command command) {
+ if (m_composedCommands.contains(command)) {
+ throw new IllegalArgumentException(
+ "Commands that have been composed may not be added to another composition or scheduled"
+ + "individually!");
+ }
+ }
+
+ /**
+ * Requires that the specified commands not have been already added to a composition.
+ *
+ * @param commands The commands to check
+ * @throws IllegalArgumentException if the given commands have already been composed.
+ */
+ public void requireNotComposed(Collection commands) {
+ if (!Collections.disjoint(commands, getComposedCommands())) {
+ throw new IllegalArgumentException(
+ "Commands that have been composed may not be added to another composition or scheduled"
+ + "individually!");
+ }
+ }
+
+ /**
+ * Check if the given command has been composed.
+ *
+ * @param command The command to check
+ * @return true if composed
+ * @throws IllegalArgumentException if the given commands have already been composed.
+ */
+ public boolean isComposed(Command command) {
+ return getComposedCommands().contains(command);
+ }
+
+ Set getComposedCommands() {
+ return m_composedCommands;
+ }
+
@Override
public void initSendable(NTSendableBuilder builder) {
builder.setSmartDashboardType("Scheduler");
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ConditionalCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ConditionalCommand.java
index 18d392aa7a..8a299b2dbb 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ConditionalCommand.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ConditionalCommand.java
@@ -5,22 +5,16 @@
package edu.wpi.first.wpilibj2.command;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
-import static edu.wpi.first.wpilibj2.command.CommandGroupBase.requireUngrouped;
import java.util.function.BooleanSupplier;
/**
- * Runs one of two commands, depending on the value of the given condition when this command is
- * initialized. Does not actually schedule the selected command - rather, the command is run through
- * this command; this ensures that the command will behave as expected if used as part of a
- * CommandGroup. Requires the requirements of both commands, again to ensure proper functioning when
- * used in a CommandGroup. If this is undesired, consider using {@link ScheduleCommand}.
+ * A command composition that runs one of two commands, depending on the value of the given
+ * condition when this command is initialized.
*
- *
As this command contains multiple component commands within it, it is technically a command
- * group; the command instances that are passed to it cannot be added to any other groups, or
- * scheduled individually.
- *
- *
As a rule, CommandGroups require the union of the requirements of their component commands.
+ *
The rules for command compositions apply: command instances that are passed to it cannot be
+ * added to any other composition or scheduled individually, and the composition requires all
+ * subsystems its components require.
*
*
This class is provided by the NewCommands VendorDep
*/
@@ -38,13 +32,12 @@ public class ConditionalCommand extends CommandBase {
* @param condition the condition to determine which command to run
*/
public ConditionalCommand(Command onTrue, Command onFalse, BooleanSupplier condition) {
- requireUngrouped(onTrue, onFalse);
-
- CommandGroupBase.registerGroupedCommands(onTrue, onFalse);
-
- m_onTrue = onTrue;
- m_onFalse = onFalse;
+ m_onTrue = requireNonNullParam(onTrue, "onTrue", "ConditionalCommand");
+ m_onFalse = requireNonNullParam(onFalse, "onFalse", "ConditionalCommand");
m_condition = requireNonNullParam(condition, "condition", "ConditionalCommand");
+
+ CommandScheduler.getInstance().registerComposedCommands(onTrue, onFalse);
+
m_requirements.addAll(m_onTrue.getRequirements());
m_requirements.addAll(m_onFalse.getRequirements());
}
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelCommandGroup.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelCommandGroup.java
index 40a85a714c..3b36f42eca 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelCommandGroup.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelCommandGroup.java
@@ -9,24 +9,27 @@ import java.util.HashMap;
import java.util.Map;
/**
- * A CommandGroup that runs a set of commands in parallel, ending when the last command ends.
+ * A command composition that runs a set of commands in parallel, ending when the last command ends.
*
- *
As a rule, CommandGroups require the union of the requirements of their component commands.
+ *
The rules for command compositions apply: command instances that are passed to it cannot be
+ * added to any other composition or scheduled individually, and the composition requires all
+ * subsystems its components require.
*
*
This class is provided by the NewCommands VendorDep
*/
+@SuppressWarnings("removal")
public class ParallelCommandGroup extends CommandGroupBase {
- // maps commands in this group to whether they are still running
+ // maps commands in this composition to whether they are still running
private final Map m_commands = new HashMap<>();
private boolean m_runWhenDisabled = true;
private InterruptionBehavior m_interruptBehavior = InterruptionBehavior.kCancelIncoming;
/**
* Creates a new ParallelCommandGroup. The given commands will be executed simultaneously. The
- * command group will finish when the last command finishes. If the CommandGroup is interrupted,
- * only the commands that are still running will be interrupted.
+ * command composition will finish when the last command finishes. If the composition is
+ * interrupted, only the commands that are still running will be interrupted.
*
- * @param commands the commands to include in this group.
+ * @param commands the commands to include in this composition.
*/
public ParallelCommandGroup(Command... commands) {
addCommands(commands);
@@ -34,19 +37,17 @@ public class ParallelCommandGroup extends CommandGroupBase {
@Override
public final void addCommands(Command... commands) {
- requireUngrouped(commands);
-
if (m_commands.containsValue(true)) {
throw new IllegalStateException(
- "Commands cannot be added to a CommandGroup while the group is running");
+ "Commands cannot be added to a composition while it's running");
}
- registerGroupedCommands(commands);
+ CommandScheduler.getInstance().registerComposedCommands(commands);
for (Command command : commands) {
if (!Collections.disjoint(command.getRequirements(), m_requirements)) {
throw new IllegalArgumentException(
- "Multiple commands in a parallel group cannot" + "require the same subsystems");
+ "Multiple commands in a parallel composition cannot require the same subsystems");
}
m_commands.put(command, false);
m_requirements.addAll(command.getRequirements());
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelDeadlineGroup.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelDeadlineGroup.java
index e3ac8fd85f..0687ed1a9c 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelDeadlineGroup.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelDeadlineGroup.java
@@ -9,15 +9,19 @@ import java.util.HashMap;
import java.util.Map;
/**
- * A CommandGroup that runs a set of commands in parallel, ending only when a specific command (the
- * "deadline") ends, interrupting all other commands that are still running at that point.
+ * A command composition that runs a set of commands in parallel, ending only when a specific
+ * command (the "deadline") ends, interrupting all other commands that are still running at that
+ * point.
*
- *
As a rule, CommandGroups require the union of the requirements of their component commands.
+ *
The rules for command compositions apply: command instances that are passed to it cannot be
+ * added to any other composition or scheduled individually, and the composition requires all
+ * subsystems its components require.
*
*
This class is provided by the NewCommands VendorDep
*/
+@SuppressWarnings("removal")
public class ParallelDeadlineGroup extends CommandGroupBase {
- // maps commands in this group to whether they are still running
+ // maps commands in this composition to whether they are still running
private final Map m_commands = new HashMap<>();
private boolean m_runWhenDisabled = true;
private boolean m_finished = true;
@@ -26,11 +30,11 @@ public class ParallelDeadlineGroup extends CommandGroupBase {
/**
* Creates a new ParallelDeadlineGroup. The given commands (including the deadline) will be
- * executed simultaneously. The CommandGroup will finish when the deadline finishes, interrupting
- * all other still-running commands. If the CommandGroup is interrupted, only the commands still
+ * executed simultaneously. The composition will finish when the deadline finishes, interrupting
+ * all other still-running commands. If the composition is interrupted, only the commands still
* running will be interrupted.
*
- * @param deadline the command that determines when the group ends
+ * @param deadline the command that determines when the composition ends
* @param commands the commands to be executed
*/
public ParallelDeadlineGroup(Command deadline, Command... commands) {
@@ -56,14 +60,12 @@ public class ParallelDeadlineGroup extends CommandGroupBase {
@Override
public final void addCommands(Command... commands) {
- requireUngrouped(commands);
-
if (!m_finished) {
throw new IllegalStateException(
- "Commands cannot be added to a CommandGroup while the group is running");
+ "Commands cannot be added to a composition while it's running");
}
- registerGroupedCommands(commands);
+ CommandScheduler.getInstance().registerComposedCommands(commands);
for (Command command : commands) {
if (!Collections.disjoint(command.getRequirements(), m_requirements)) {
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelRaceGroup.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelRaceGroup.java
index 43172af6df..e5ba80d173 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelRaceGroup.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ParallelRaceGroup.java
@@ -9,13 +9,16 @@ import java.util.HashSet;
import java.util.Set;
/**
- * A CommandGroup that runs a set of commands in parallel, ending when any one of the commands ends
+ * A composition that runs a set of commands in parallel, ending when any one of the commands ends
* and interrupting all the others.
*
- *
As a rule, CommandGroups require the union of the requirements of their component commands.
+ *
The rules for command compositions apply: command instances that are passed to it cannot be
+ * added to any other composition or scheduled individually, and the composition requires all
+ * subsystems its components require.
*
*
This class is provided by the NewCommands VendorDep
*/
+@SuppressWarnings("removal")
public class ParallelRaceGroup extends CommandGroupBase {
private final Set m_commands = new HashSet<>();
private boolean m_runWhenDisabled = true;
@@ -27,7 +30,7 @@ public class ParallelRaceGroup extends CommandGroupBase {
* "race to the finish" - the first command to finish ends the entire command, with all other
* commands being interrupted.
*
- * @param commands the commands to include in this group.
+ * @param commands the commands to include in this composition.
*/
public ParallelRaceGroup(Command... commands) {
addCommands(commands);
@@ -35,19 +38,17 @@ public class ParallelRaceGroup extends CommandGroupBase {
@Override
public final void addCommands(Command... commands) {
- requireUngrouped(commands);
-
if (!m_finished) {
throw new IllegalStateException(
- "Commands cannot be added to a CommandGroup while the group is running");
+ "Commands cannot be added to a composition while it's running!");
}
- registerGroupedCommands(commands);
+ CommandScheduler.getInstance().registerComposedCommands(commands);
for (Command command : commands) {
if (!Collections.disjoint(command.getRequirements(), m_requirements)) {
throw new IllegalArgumentException(
- "Multiple commands in a parallel group cannot" + " require the same subsystems");
+ "Multiple commands in a parallel composition cannot require the same subsystems");
}
m_commands.add(command);
m_requirements.addAll(command.getRequirements());
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/PerpetualCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/PerpetualCommand.java
index 9ef643e4a4..9fb90190a7 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/PerpetualCommand.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/PerpetualCommand.java
@@ -4,12 +4,9 @@
package edu.wpi.first.wpilibj2.command;
-import static edu.wpi.first.wpilibj2.command.CommandGroupBase.registerGroupedCommands;
-import static edu.wpi.first.wpilibj2.command.CommandGroupBase.requireUngrouped;
-
/**
* A command that runs another command in perpetuity, ignoring that command's end conditions. While
- * this class does not extend {@link CommandGroupBase}, it is still considered a CommandGroup, as it
+ * this class does not extend {@link CommandGroupBase}, it is still considered a composition, as it
* allows one to compose another command within it; the command instances that are passed to it
* cannot be added to any other groups, or scheduled individually.
*
@@ -33,8 +30,7 @@ public class PerpetualCommand extends CommandBase {
* @param command the command to run perpetually
*/
public PerpetualCommand(Command command) {
- requireUngrouped(command);
- registerGroupedCommands(command);
+ CommandScheduler.getInstance().registerComposedCommands(command);
m_command = command;
m_requirements.addAll(command.getRequirements());
}
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RepeatCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RepeatCommand.java
index c1401ec626..b70f9c521c 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RepeatCommand.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/RepeatCommand.java
@@ -4,16 +4,16 @@
package edu.wpi.first.wpilibj2.command;
-import static edu.wpi.first.wpilibj2.command.CommandGroupBase.registerGroupedCommands;
-import static edu.wpi.first.wpilibj2.command.CommandGroupBase.requireUngrouped;
+import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
/**
* A command that runs another command repeatedly, restarting it when it ends, until this command is
- * interrupted. While this class does not extend {@link CommandGroupBase}, it is still considered a
- * CommandGroup, as it allows one to compose another command within it; the command instances that
- * are passed to it cannot be added to any other groups, or scheduled individually.
+ * interrupted. Command instances that are passed to it cannot be added to any other groups, or
+ * scheduled individually.
*
- *
As a rule, CommandGroups require the union of the requirements of their component commands.
+ *
The rules for command compositions apply: command instances that are passed to it cannot be
+ * added to any other composition or scheduled individually,and the composition requires all
+ * subsystems its components require.
*
*
This class is provided by the NewCommands VendorDep
*/
@@ -28,9 +28,8 @@ public class RepeatCommand extends CommandBase {
* @param command the command to run repeatedly
*/
public RepeatCommand(Command command) {
- requireUngrouped(command);
- registerGroupedCommands(command);
- m_command = command;
+ m_command = requireNonNullParam(command, "command", "RepeatCommand");
+ CommandScheduler.getInstance().registerComposedCommands(command);
m_requirements.addAll(command.getRequirements());
}
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ScheduleCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ScheduleCommand.java
index 98062f9a90..a61be2f336 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ScheduleCommand.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/ScheduleCommand.java
@@ -8,8 +8,8 @@ import java.util.Set;
/**
* Schedules the given commands when this command is initialized. Useful for forking off from
- * CommandGroups. Note that if run from a CommandGroup, the group will not know about the status of
- * the scheduled commands, and will treat this command as finishing instantly.
+ * CommandGroups. 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.
*
*
This class is provided by the NewCommands VendorDep
*/
diff --git a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/SelectCommand.java b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/SelectCommand.java
index b3cd97b56d..a020c1fc9f 100644
--- a/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/SelectCommand.java
+++ b/wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/SelectCommand.java
@@ -5,24 +5,17 @@
package edu.wpi.first.wpilibj2.command;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
-import static edu.wpi.first.wpilibj2.command.CommandGroupBase.requireUngrouped;
import java.util.Map;
import java.util.function.Supplier;
/**
- * Runs one of a selection of commands, either using a selector and a key to command mapping, or a
- * supplier that returns the command directly at runtime. Does not actually schedule the selected
- * command - rather, the command is run through this command; this ensures that the command will
- * behave as expected if used as part of a CommandGroup. Requires the requirements of all included
- * commands, again to ensure proper functioning when used in a CommandGroup. If this is undesired,
- * consider using {@link ScheduleCommand}.
+ * A command composition that runs one of a selection of commands, either using a selector and a key
+ * to command mapping, or a supplier that returns the command directly at runtime.
*
- *
As this command contains multiple component commands within it, it is technically a command
- * group; the command instances that are passed to it cannot be added to any other groups, or
- * scheduled individually.
- *
- *
As a rule, CommandGroups require the union of the requirements of their component commands.
+ *
The rules for command compositions apply: command instances that are passed to it cannot be
+ * added to any other composition or scheduled individually, and the composition requires all
+ * subsystems its components require.
*
*
This class is provided by the NewCommands VendorDep
*/
@@ -41,13 +34,12 @@ public class SelectCommand extends CommandBase {
* @param selector the selector to determine which command to run
*/
public SelectCommand(Map