-
Notifications
You must be signed in to change notification settings - Fork 612
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] Add DeferredCommand #5566
Conversation
6272673
to
e27188f
Compare
I think you've done it already. Most commands like explicit RunCommand(std::function<void()> toRun, std::span<Subsystem* const> requirements = {}); which I think is used when requirements aren't specified. You haven't specified any default arguments for requirements. so a compilation error should happen if requirements aren't specified. At the minimum, teams would need to pass
I think creating new commands is already standard practice. Constructors that take a |
wpilibNewCommands/src/main/native/cpp/frc2/command/DeferredCommand.cpp
Outdated
Show resolved
Hide resolved
This comment was marked as outdated.
This comment was marked as outdated.
wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/Commands.java
Show resolved
Hide resolved
wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/DeferredCommand.java
Show resolved
Hide resolved
wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/DeferredCommand.java
Outdated
Show resolved
Hide resolved
wpilibNewCommands/src/main/java/edu/wpi/first/wpilibj2/command/DeferredCommand.java
Outdated
Show resolved
Hide resolved
wpilibNewCommands/src/main/native/cpp/frc2/command/DeferredCommand.cpp
Outdated
Show resolved
Hide resolved
wpilibNewCommands/src/main/native/include/frc2/command/DeferredCommand.h
Outdated
Show resolved
Hide resolved
wpilibNewCommands/src/main/native/include/frc2/command/SelectCommand.h
Outdated
Show resolved
Hide resolved
Perhaps add a note in documentation that for selecting one of a preallocated set of commands, Also, deprecate the deferring ProxyCommand overload, with a note pointing to |
Couldn't we mark the commands as not composed after we're done with them via CommandScheduler.removeComposedCommand() or Command.SetComposed(false)? |
Not sure about this. Let me think. @Starlight220 any thoughts?
I'm not sure about this. Combining them would result in the same behavior, but combining the need for requirements to be explicitly specified for DeferredCommand combined with the confusion with ProxyCommand requirements seems like a recipe for even more confusion. |
|
8ce7a33
to
3452803
Compare
Unmarking commands isn't something we've done before, and I think it would just cause even more confusion due to race conditions. On the other hand, we usually also don't make commands this late into runtime. |
Just found a somewhat serious issue with this, as well as with the command library in general. If you add a command to a composition after that command has been scheduled directly with the scheduler, there will be no errors thrown and the command will happily be run by both the composition and the command scheduler. (This of course ignores requirements, but that's a separate issue. We haven't run into this because typically commands are constructed prior to runtime, but that isn't requirement. This should be fixed for the library as a whole- we can check if the command is scheduled with the scheduler as part of the pre-composition check. Test demonstrating the issue: @Test
void testScheduleThenCompose() {
assert DriverStation.isEnabled();
AtomicInteger i = new AtomicInteger();
Command command = Commands.run(() -> {
System.out.println(i.incrementAndGet());
});
command.schedule();
Command command2 = new SequentialCommandGroup(command); // This line should throw
command2.schedule();
CommandScheduler.getInstance().run();
assertEquals(i, 1);
} |
I like Ryan's suggestion to check if a command is already scheduled in Also, should discussion continue in a new issue? |
Opened #5581 to fix |
9006f64
to
3d36d91
Compare
wpilibNewCommands/src/test/native/cpp/frc2/command/DeferredCommandTest.cpp
Outdated
Show resolved
Hide resolved
wpilibNewCommands/src/main/native/include/frc2/command/SelectCommand.h
Outdated
Show resolved
Hide resolved
wpilibNewCommands/src/main/native/include/frc2/command/DeferredCommand.h
Show resolved
Hide resolved
wpilibNewCommands/src/test/native/cpp/frc2/command/DeferredCommandTest.cpp
Outdated
Show resolved
Hide resolved
a119038
to
ac8907f
Compare
858860d
to
a49cae8
Compare
Command* constructors have been removed. The null handling has also been removed, since CommandPtr cannot hold null. |
207bcc9
to
d12a010
Compare
CommandPtrs can still be invalid / hold null as a result of a use-after-move, or if they're initialized with a null |
CommandPtr handles this by throwing an exception, and this is bad behavior anyway
This ends up being handled with the same checking as above- I can't even unwrap the CommandPtr to check if the pointer is valid, the unwrap function triggers CommandPtr's null check TLDR; CommandPtr cannot hold a null pointer and be used at all. |
Is there any example code of how a DeferCommand can be used in C++? A google search has terminated with me ending up here. |
Here's an example of a command factory that prints the game data fetched when the command is scheduled. CommandPtr PrintGameData() {
return frc2::cmd::Defer([] { return frc2::cmd::Print(frc::DriverStation::GetGameData()); });
} I hope this helps. |
Closes #5150
Allows commands to be constructed at runtime without proxying.
Requirements must be specified explicitly, even if there are no requirements. Java uses a
Set<Subsystem>
. Not sure how to accomplish this in c++. The reason for this is that requirements must be known before runtime (and therefore before the contained command is constructed, and users will likely forget to include the proper requirements.The other potential tripping point is that the supplier must create a new command each time it's called, because this is considered a command composition, so we don't want the supplied commands being used for other compositions or being scheduled directly.
Still needs c++ tests, will finish those up this weekend.