Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cmd] Define order of parallel groups #6602

Merged
merged 6 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
package edu.wpi.first.wpilibj2.command;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
Expand All @@ -19,7 +19,7 @@
*/
public class ParallelCommandGroup extends Command {
// maps commands in this composition to whether they are still running
private final Map<Command, Boolean> m_commands = new HashMap<>();
private final Map<Command, Boolean> m_commands = new LinkedHashMap<>();
KangarooKoala marked this conversation as resolved.
Show resolved Hide resolved
private boolean m_runWhenDisabled = true;
private InterruptionBehavior m_interruptBehavior = InterruptionBehavior.kCancelIncoming;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import edu.wpi.first.util.sendable.SendableBuilder;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
Expand All @@ -22,7 +22,7 @@
*/
public class ParallelDeadlineGroup extends Command {
// maps commands in this composition to whether they are still running
private final Map<Command, Boolean> m_commands = new HashMap<>();
private final Map<Command, Boolean> m_commands = new LinkedHashMap<>();
private boolean m_runWhenDisabled = true;
private boolean m_finished = true;
private Command m_deadline;
Expand All @@ -39,8 +39,8 @@ public class ParallelDeadlineGroup extends Command {
* @throws IllegalArgumentException if the deadline command is also in the otherCommands argument
*/
public ParallelDeadlineGroup(Command deadline, Command... otherCommands) {
addCommands(otherCommands);
setDeadline(deadline);
addCommands(otherCommands);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
package edu.wpi.first.wpilibj2.command;

import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

/**
Expand All @@ -19,7 +19,7 @@
* <p>This class is provided by the NewCommands VendorDep
*/
public class ParallelRaceGroup extends Command {
private final Set<Command> m_commands = new HashSet<>();
private final Set<Command> m_commands = new LinkedHashSet<>();
private boolean m_runWhenDisabled = true;
private boolean m_finished = true;
private InterruptionBehavior m_interruptBehavior = InterruptionBehavior.kCancelIncoming;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,17 @@ CommandPtr CommandPtr::BeforeStarting(CommandPtr&& before) && {
CommandPtr CommandPtr::WithTimeout(units::second_t duration) && {
AssertValid();
std::vector<std::unique_ptr<Command>> temp;
temp.emplace_back(std::make_unique<WaitCommand>(duration));
temp.emplace_back(std::move(m_ptr));
temp.emplace_back(std::make_unique<WaitCommand>(duration));
m_ptr = std::make_unique<ParallelRaceGroup>(std::move(temp));
return std::move(*this);
}

CommandPtr CommandPtr::Until(std::function<bool()> condition) && {
AssertValid();
std::vector<std::unique_ptr<Command>> temp;
temp.emplace_back(std::make_unique<WaitUntilCommand>(std::move(condition)));
temp.emplace_back(std::move(m_ptr));
temp.emplace_back(std::make_unique<WaitUntilCommand>(std::move(condition)));
m_ptr = std::make_unique<ParallelRaceGroup>(std::move(temp));
return std::move(*this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package edu.wpi.first.wpilibj2.command;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -57,6 +58,36 @@ void untilTest() {
}
}

@Test
void untilOrderTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
AtomicBoolean firstHasRun = new AtomicBoolean(false);
AtomicBoolean firstWasPolled = new AtomicBoolean(false);

Command first =
new FunctionalCommand(
() -> {},
() -> firstHasRun.set(true),
interrupted -> {},
() -> {
firstWasPolled.set(true);
return true;
});
Command command =
first.until(
() -> {
assertAll(
() -> assertTrue(firstHasRun.get()), () -> assertTrue(firstWasPolled.get()));
return true;
});

scheduler.schedule(command);
scheduler.run();

assertAll(() -> assertTrue(firstHasRun.get()), () -> assertTrue(firstWasPolled.get()));
}
}

@Test
void onlyWhileTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
Expand All @@ -73,6 +104,36 @@ void onlyWhileTest() {
}
}

@Test
void onlyWhileOrderTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
AtomicBoolean firstHasRun = new AtomicBoolean(false);
AtomicBoolean firstWasPolled = new AtomicBoolean(false);

Command first =
new FunctionalCommand(
() -> {},
() -> firstHasRun.set(true),
interrupted -> {},
() -> {
firstWasPolled.set(true);
return true;
});
Command command =
first.onlyWhile(
() -> {
assertAll(
() -> assertTrue(firstHasRun.get()), () -> assertTrue(firstWasPolled.get()));
return false;
});

scheduler.schedule(command);
scheduler.run();

assertAll(() -> assertTrue(firstHasRun.get()), () -> assertTrue(firstWasPolled.get()));
}
}

@Test
void ignoringDisableTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
Expand Down Expand Up @@ -162,6 +223,37 @@ void deadlineWithTest() {
}
}

@Test
void deadlineForOrderTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
AtomicBoolean dictatorHasRun = new AtomicBoolean(false);
AtomicBoolean dictatorWasPolled = new AtomicBoolean(false);

Command dictator =
new FunctionalCommand(
() -> {},
() -> dictatorHasRun.set(true),
interrupted -> {},
() -> {
dictatorWasPolled.set(true);
return true;
});
Command other =
new RunCommand(
() ->
assertAll(
() -> assertTrue(dictatorHasRun.get()),
() -> assertTrue(dictatorWasPolled.get())));

Command group = dictator.deadlineFor(other);

scheduler.schedule(group);
scheduler.run();

assertAll(() -> assertTrue(dictatorHasRun.get()), () -> assertTrue(dictatorWasPolled.get()));
}
}

@Test
void alongWithTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
Expand All @@ -185,6 +277,36 @@ void alongWithTest() {
}
}

@Test
void alongWithOrderTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
AtomicBoolean firstHasRun = new AtomicBoolean(false);
AtomicBoolean firstWasPolled = new AtomicBoolean(false);

Command command1 =
new FunctionalCommand(
() -> {},
() -> firstHasRun.set(true),
interrupted -> {},
() -> {
firstWasPolled.set(true);
return true;
});
Command command2 =
new RunCommand(
() ->
assertAll(
() -> assertTrue(firstHasRun.get()), () -> assertTrue(firstWasPolled.get())));

Command group = command1.alongWith(command2);

scheduler.schedule(group);
scheduler.run();

assertAll(() -> assertTrue(firstHasRun.get()), () -> assertTrue(firstWasPolled.get()));
}
}

@Test
void raceWithTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
Expand All @@ -200,6 +322,37 @@ void raceWithTest() {
}
}

@Test
void raceWithOrderTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
AtomicBoolean firstHasRun = new AtomicBoolean(false);
AtomicBoolean firstWasPolled = new AtomicBoolean(false);

Command command1 =
new FunctionalCommand(
() -> {},
() -> firstHasRun.set(true),
interrupted -> {},
() -> {
firstWasPolled.set(true);
return true;
});
Command command2 =
new RunCommand(
() -> {
assertTrue(firstHasRun.get());
assertTrue(firstWasPolled.get());
});

Command group = command1.raceWith(command2);

scheduler.schedule(group);
scheduler.run();

assertAll(() -> assertTrue(firstHasRun.get()), () -> assertTrue(firstWasPolled.get()));
}
}

@Test
void unlessTest() {
try (CommandScheduler scheduler = new CommandScheduler()) {
Expand Down
Loading
Loading