added optional data to scheduler/process
This commit is contained in:
@@ -90,9 +90,9 @@ class Process: private BaseProcess {
|
||||
}
|
||||
|
||||
template<typename Target = Derived>
|
||||
auto tick(int, tag<State::RUNNING>, Delta delta)
|
||||
-> decltype(std::declval<Target>().update(delta)) {
|
||||
static_cast<Target *>(this)->update(delta);
|
||||
auto tick(int, tag<State::RUNNING>, Delta delta, void *data)
|
||||
-> decltype(std::declval<Target>().update(delta, data)) {
|
||||
static_cast<Target *>(this)->update(delta, data);
|
||||
}
|
||||
|
||||
template<typename Target = Derived>
|
||||
@@ -227,15 +227,16 @@ public:
|
||||
/**
|
||||
* @brief Updates a process and its internal state if required.
|
||||
* @param delta Elapsed time.
|
||||
* @param data Optional data.
|
||||
*/
|
||||
void tick(Delta delta) {
|
||||
void tick(Delta delta, void *data = nullptr) {
|
||||
switch (current) {
|
||||
case State::UNINITIALIZED:
|
||||
tick(0, tag<State::UNINITIALIZED>{});
|
||||
current = State::RUNNING;
|
||||
// no break on purpose, tasks are executed immediately
|
||||
case State::RUNNING:
|
||||
tick(0, tag<State::RUNNING>{}, delta);
|
||||
tick(0, tag<State::RUNNING>{}, delta, data);
|
||||
default:
|
||||
// suppress warnings
|
||||
break;
|
||||
@@ -322,9 +323,10 @@ struct ProcessAdaptor: Process<ProcessAdaptor<Func, Delta>, Delta>, private Func
|
||||
/**
|
||||
* @brief Updates a process and its internal state if required.
|
||||
* @param delta Elapsed time.
|
||||
* @param data Optional data.
|
||||
*/
|
||||
void update(Delta delta) {
|
||||
Func::operator()(delta, [this](){ this->succeed(); }, [this](){ this->fail(); });
|
||||
void update(Delta delta, void *data) {
|
||||
Func::operator()(delta, data, [this](){ this->succeed(); }, [this](){ this->fail(); });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class Scheduler final {
|
||||
|
||||
struct ProcessHandler final {
|
||||
using instance_type = std::unique_ptr<void, void(*)(void *)>;
|
||||
using update_type = bool(*)(ProcessHandler &, Delta);
|
||||
using update_type = bool(*)(ProcessHandler &, Delta, void *);
|
||||
using abort_type = void(*)(ProcessHandler &, bool);
|
||||
using next_type = std::unique_ptr<ProcessHandler>;
|
||||
|
||||
@@ -81,16 +81,16 @@ class Scheduler final {
|
||||
};
|
||||
|
||||
template<typename Proc>
|
||||
static bool update(ProcessHandler &handler, Delta delta) {
|
||||
static bool update(ProcessHandler &handler, Delta delta, void *data) {
|
||||
auto *process = static_cast<Proc *>(handler.instance.get());
|
||||
process->tick(delta);
|
||||
process->tick(delta, data);
|
||||
|
||||
auto dead = process->dead();
|
||||
|
||||
if(dead) {
|
||||
if(handler.next && !process->rejected()) {
|
||||
handler = std::move(*handler.next);
|
||||
dead = handler.update(handler, delta);
|
||||
dead = handler.update(handler, delta, data);
|
||||
} else {
|
||||
handler.instance.reset();
|
||||
}
|
||||
@@ -269,13 +269,14 @@ public:
|
||||
* with its child.
|
||||
*
|
||||
* @param delta Elapsed time.
|
||||
* @param data Optional data.
|
||||
*/
|
||||
void update(Delta delta) {
|
||||
void update(Delta delta, void *data = nullptr) {
|
||||
bool clean = false;
|
||||
|
||||
for(auto pos = handlers.size(); pos > 0; --pos) {
|
||||
auto &handler = handlers[pos-1];
|
||||
const bool dead = handler.update(handler, delta);
|
||||
const bool dead = handler.update(handler, delta, data);
|
||||
clean = clean || dead;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,18 @@ struct FakeProcess: entt::Process<FakeProcess, int> {
|
||||
void unpause() noexcept { process_type::unpause(); }
|
||||
|
||||
void init() { initInvoked = true; }
|
||||
void update(delta_type) { updateInvoked = true; }
|
||||
void succeeded() { succeededInvoked = true; }
|
||||
void failed() { failedInvoked = true; }
|
||||
void aborted() { abortedInvoked = true; }
|
||||
|
||||
void update(delta_type, void *data) {
|
||||
if(data) {
|
||||
(*static_cast<int *>(data))++;
|
||||
}
|
||||
|
||||
updateInvoked = true;
|
||||
}
|
||||
|
||||
bool initInvoked{false};
|
||||
bool updateInvoked{false};
|
||||
bool succeededInvoked{false};
|
||||
@@ -95,6 +102,26 @@ TEST(Process, Fail) {
|
||||
ASSERT_FALSE(process.abortedInvoked);
|
||||
}
|
||||
|
||||
TEST(Process, Data) {
|
||||
FakeProcess process;
|
||||
int value = 0;
|
||||
|
||||
process.tick(0, &value);
|
||||
process.succeed();
|
||||
process.tick(0, &value);
|
||||
|
||||
ASSERT_FALSE(process.alive());
|
||||
ASSERT_TRUE(process.dead());
|
||||
ASSERT_FALSE(process.paused());
|
||||
|
||||
ASSERT_EQ(value, 1);
|
||||
ASSERT_TRUE(process.initInvoked);
|
||||
ASSERT_TRUE(process.updateInvoked);
|
||||
ASSERT_TRUE(process.succeededInvoked);
|
||||
ASSERT_FALSE(process.failedInvoked);
|
||||
ASSERT_FALSE(process.abortedInvoked);
|
||||
}
|
||||
|
||||
TEST(Process, AbortNextTick) {
|
||||
FakeProcess process;
|
||||
|
||||
@@ -132,7 +159,7 @@ TEST(Process, AbortImmediately) {
|
||||
|
||||
TEST(ProcessAdaptor, Resolved) {
|
||||
bool updated = false;
|
||||
auto lambda = [&updated](std::uint64_t, auto resolve, auto) {
|
||||
auto lambda = [&updated](std::uint64_t, void *, auto resolve, auto) {
|
||||
ASSERT_FALSE(updated);
|
||||
updated = true;
|
||||
resolve();
|
||||
@@ -148,7 +175,7 @@ TEST(ProcessAdaptor, Resolved) {
|
||||
|
||||
TEST(ProcessAdaptor, Rejected) {
|
||||
bool updated = false;
|
||||
auto lambda = [&updated](std::uint64_t, auto, auto rejected) {
|
||||
auto lambda = [&updated](std::uint64_t, void *, auto, auto rejected) {
|
||||
ASSERT_FALSE(updated);
|
||||
updated = true;
|
||||
rejected();
|
||||
@@ -161,3 +188,19 @@ TEST(ProcessAdaptor, Rejected) {
|
||||
ASSERT_TRUE(process.rejected());
|
||||
ASSERT_TRUE(updated);
|
||||
}
|
||||
|
||||
TEST(ProcessAdaptor, Data) {
|
||||
int value = 0;
|
||||
|
||||
auto lambda = [](std::uint64_t, void *data, auto resolve, auto) {
|
||||
*static_cast<int *>(data) = 42;
|
||||
resolve();
|
||||
};
|
||||
|
||||
auto process = entt::ProcessAdaptor<decltype(lambda), std::uint64_t>{lambda};
|
||||
|
||||
process.tick(0, &value);
|
||||
|
||||
ASSERT_TRUE(process.dead());
|
||||
ASSERT_EQ(value, 42);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ struct FooProcess: entt::Process<FooProcess, int> {
|
||||
: onUpdate{onUpdate}, onAborted{onAborted}
|
||||
{}
|
||||
|
||||
void update(delta_type) { onUpdate(); }
|
||||
void update(delta_type, void *) { onUpdate(); }
|
||||
void aborted() { onAborted(); }
|
||||
|
||||
std::function<void()> onUpdate;
|
||||
@@ -16,7 +16,7 @@ struct FooProcess: entt::Process<FooProcess, int> {
|
||||
};
|
||||
|
||||
struct SucceededProcess: entt::Process<SucceededProcess, int> {
|
||||
void update(delta_type) {
|
||||
void update(delta_type, void *) {
|
||||
ASSERT_FALSE(updated);
|
||||
updated = true;
|
||||
++invoked;
|
||||
@@ -30,7 +30,7 @@ struct SucceededProcess: entt::Process<SucceededProcess, int> {
|
||||
unsigned int SucceededProcess::invoked = 0;
|
||||
|
||||
struct FailedProcess: entt::Process<FailedProcess, int> {
|
||||
void update(delta_type) {
|
||||
void update(delta_type, void *) {
|
||||
ASSERT_FALSE(updated);
|
||||
updated = true;
|
||||
fail();
|
||||
@@ -92,11 +92,11 @@ TEST(Scheduler, Functor) {
|
||||
bool firstFunctor = false;
|
||||
bool secondFunctor = false;
|
||||
|
||||
scheduler.attach([&firstFunctor](auto, auto resolve, auto){
|
||||
scheduler.attach([&firstFunctor](auto, void *, auto resolve, auto){
|
||||
ASSERT_FALSE(firstFunctor);
|
||||
firstFunctor = true;
|
||||
resolve();
|
||||
}).then([&secondFunctor](auto, auto, auto reject){
|
||||
}).then([&secondFunctor](auto, void *, auto, auto reject){
|
||||
ASSERT_FALSE(secondFunctor);
|
||||
secondFunctor = true;
|
||||
reject();
|
||||
|
||||
Reference in New Issue
Block a user