mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-21 01:01:43 +00:00
[commands] C++: Allow CommandPtrs to be owned by the scheduler (#7310)
Previously users would have to keep track of dynamically created CommandPtrs. This adds an ownership-taking version of schedule which places the command in a temporary store in the scheduler. The command will be freed when the command's lifecycle ends.
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "CommandTestBase.h"
|
||||
#include "frc2/command/InstantCommand.h"
|
||||
#include "frc2/command/RunCommand.h"
|
||||
@@ -171,3 +173,52 @@ TEST_F(SchedulerTest, ScheduleScheduledNoOp) {
|
||||
|
||||
EXPECT_EQ(counter, 1);
|
||||
}
|
||||
|
||||
class TrackDestroyCommand
|
||||
: public frc2::CommandHelper<Command, TrackDestroyCommand> {
|
||||
public:
|
||||
explicit TrackDestroyCommand(wpi::unique_function<void()> deleteFunc)
|
||||
: m_deleteFunc{std::move(deleteFunc)} {}
|
||||
TrackDestroyCommand(TrackDestroyCommand&& other)
|
||||
: m_deleteFunc{std::exchange(other.m_deleteFunc, [] {})} {}
|
||||
TrackDestroyCommand& operator=(TrackDestroyCommand&& other) {
|
||||
m_deleteFunc = std::exchange(other.m_deleteFunc, [] {});
|
||||
return *this;
|
||||
}
|
||||
~TrackDestroyCommand() override { m_deleteFunc(); }
|
||||
|
||||
private:
|
||||
wpi::unique_function<void()> m_deleteFunc;
|
||||
};
|
||||
|
||||
TEST_F(SchedulerTest, ScheduleCommandPtr) {
|
||||
CommandScheduler scheduler = GetScheduler();
|
||||
int destructionCounter = 0;
|
||||
int runCounter = 0;
|
||||
|
||||
bool finish = false;
|
||||
|
||||
{
|
||||
auto commandPtr =
|
||||
TrackDestroyCommand([&destructionCounter] { destructionCounter++; })
|
||||
.AlongWith(
|
||||
frc2::InstantCommand([&runCounter] { runCounter++; }).ToPtr())
|
||||
.Until([&finish] { return finish; });
|
||||
EXPECT_EQ(destructionCounter, 0) << "Composition should not delete command";
|
||||
|
||||
scheduler.Schedule(std::move(commandPtr));
|
||||
EXPECT_EQ(destructionCounter, 0)
|
||||
<< "Scheduling should not delete CommandPtr";
|
||||
}
|
||||
EXPECT_EQ(destructionCounter, 0)
|
||||
<< "Scheduler should own CommandPtr after scheduling";
|
||||
scheduler.Run();
|
||||
EXPECT_EQ(runCounter, 1);
|
||||
EXPECT_EQ(destructionCounter, 0) << "Scheduler should not destroy CommandPtr "
|
||||
"until command lifetime is complete";
|
||||
finish = true;
|
||||
scheduler.Run();
|
||||
EXPECT_EQ(runCounter, 1);
|
||||
EXPECT_EQ(destructionCounter, 1)
|
||||
<< "Scheduler should delete command after command completes";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user