Browse Source

added optional data to scheduler/process

Michele Caini 8 years ago
parent
commit
41c77720bb

+ 9 - 7
src/entt/process/process.hpp

@@ -90,9 +90,9 @@ class Process: private BaseProcess {
     }
     }
 
 
     template<typename Target = Derived>
     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>
     template<typename Target = Derived>
@@ -227,15 +227,16 @@ public:
     /**
     /**
      * @brief Updates a process and its internal state if required.
      * @brief Updates a process and its internal state if required.
      * @param delta Elapsed time.
      * @param delta Elapsed time.
+     * @param data Optional data.
      */
      */
-    void tick(Delta delta) {
+    void tick(Delta delta, void *data = nullptr) {
         switch (current) {
         switch (current) {
         case State::UNINITIALIZED:
         case State::UNINITIALIZED:
             tick(0, tag<State::UNINITIALIZED>{});
             tick(0, tag<State::UNINITIALIZED>{});
             current = State::RUNNING;
             current = State::RUNNING;
             // no break on purpose, tasks are executed immediately
             // no break on purpose, tasks are executed immediately
         case State::RUNNING:
         case State::RUNNING:
-            tick(0, tag<State::RUNNING>{}, delta);
+            tick(0, tag<State::RUNNING>{}, delta, data);
         default:
         default:
             // suppress warnings
             // suppress warnings
             break;
             break;
@@ -322,9 +323,10 @@ struct ProcessAdaptor: Process<ProcessAdaptor<Func, Delta>, Delta>, private Func
     /**
     /**
      * @brief Updates a process and its internal state if required.
      * @brief Updates a process and its internal state if required.
      * @param delta Elapsed time.
      * @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(); });
     }
     }
 };
 };
 
 

+ 7 - 6
src/entt/process/scheduler.hpp

@@ -47,7 +47,7 @@ class Scheduler final {
 
 
     struct ProcessHandler final {
     struct ProcessHandler final {
         using instance_type = std::unique_ptr<void, void(*)(void *)>;
         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 abort_type = void(*)(ProcessHandler &, bool);
         using next_type = std::unique_ptr<ProcessHandler>;
         using next_type = std::unique_ptr<ProcessHandler>;
 
 
@@ -81,16 +81,16 @@ class Scheduler final {
     };
     };
 
 
     template<typename Proc>
     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());
         auto *process = static_cast<Proc *>(handler.instance.get());
-        process->tick(delta);
+        process->tick(delta, data);
 
 
         auto dead = process->dead();
         auto dead = process->dead();
 
 
         if(dead) {
         if(dead) {
             if(handler.next && !process->rejected()) {
             if(handler.next && !process->rejected()) {
                 handler = std::move(*handler.next);
                 handler = std::move(*handler.next);
-                dead = handler.update(handler, delta);
+                dead = handler.update(handler, delta, data);
             } else {
             } else {
                 handler.instance.reset();
                 handler.instance.reset();
             }
             }
@@ -269,13 +269,14 @@ public:
      * with its child.
      * with its child.
      *
      *
      * @param delta Elapsed time.
      * @param delta Elapsed time.
+     * @param data Optional data.
      */
      */
-    void update(Delta delta) {
+    void update(Delta delta, void *data = nullptr) {
         bool clean = false;
         bool clean = false;
 
 
         for(auto pos = handlers.size(); pos > 0; --pos) {
         for(auto pos = handlers.size(); pos > 0; --pos) {
             auto &handler = handlers[pos-1];
             auto &handler = handlers[pos-1];
-            const bool dead = handler.update(handler, delta);
+            const bool dead = handler.update(handler, delta, data);
             clean = clean || dead;
             clean = clean || dead;
         }
         }
 
 

+ 46 - 3
test/entt/process/process.cpp

@@ -11,11 +11,18 @@ struct FakeProcess: entt::Process<FakeProcess, int> {
     void unpause() noexcept { process_type::unpause(); }
     void unpause() noexcept { process_type::unpause(); }
 
 
     void init() { initInvoked = true; }
     void init() { initInvoked = true; }
-    void update(delta_type) { updateInvoked = true; }
     void succeeded() { succeededInvoked = true; }
     void succeeded() { succeededInvoked = true; }
     void failed() { failedInvoked = true; }
     void failed() { failedInvoked = true; }
     void aborted() { abortedInvoked = true; }
     void aborted() { abortedInvoked = true; }
 
 
+    void update(delta_type, void *data) {
+        if(data) {
+            (*static_cast<int *>(data))++;
+        }
+
+        updateInvoked = true;
+    }
+
     bool initInvoked{false};
     bool initInvoked{false};
     bool updateInvoked{false};
     bool updateInvoked{false};
     bool succeededInvoked{false};
     bool succeededInvoked{false};
@@ -95,6 +102,26 @@ TEST(Process, Fail) {
     ASSERT_FALSE(process.abortedInvoked);
     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) {
 TEST(Process, AbortNextTick) {
     FakeProcess process;
     FakeProcess process;
 
 
@@ -132,7 +159,7 @@ TEST(Process, AbortImmediately) {
 
 
 TEST(ProcessAdaptor, Resolved) {
 TEST(ProcessAdaptor, Resolved) {
     bool updated = false;
     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);
         ASSERT_FALSE(updated);
         updated = true;
         updated = true;
         resolve();
         resolve();
@@ -148,7 +175,7 @@ TEST(ProcessAdaptor, Resolved) {
 
 
 TEST(ProcessAdaptor, Rejected) {
 TEST(ProcessAdaptor, Rejected) {
     bool updated = false;
     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);
         ASSERT_FALSE(updated);
         updated = true;
         updated = true;
         rejected();
         rejected();
@@ -161,3 +188,19 @@ TEST(ProcessAdaptor, Rejected) {
     ASSERT_TRUE(process.rejected());
     ASSERT_TRUE(process.rejected());
     ASSERT_TRUE(updated);
     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);
+}

+ 5 - 5
test/entt/process/scheduler.cpp

@@ -8,7 +8,7 @@ struct FooProcess: entt::Process<FooProcess, int> {
         : onUpdate{onUpdate}, onAborted{onAborted}
         : onUpdate{onUpdate}, onAborted{onAborted}
     {}
     {}
 
 
-    void update(delta_type) { onUpdate(); }
+    void update(delta_type, void *) { onUpdate(); }
     void aborted() { onAborted(); }
     void aborted() { onAborted(); }
 
 
     std::function<void()> onUpdate;
     std::function<void()> onUpdate;
@@ -16,7 +16,7 @@ struct FooProcess: entt::Process<FooProcess, int> {
 };
 };
 
 
 struct SucceededProcess: entt::Process<SucceededProcess, int> {
 struct SucceededProcess: entt::Process<SucceededProcess, int> {
-    void update(delta_type) {
+    void update(delta_type, void *) {
         ASSERT_FALSE(updated);
         ASSERT_FALSE(updated);
         updated = true;
         updated = true;
         ++invoked;
         ++invoked;
@@ -30,7 +30,7 @@ struct SucceededProcess: entt::Process<SucceededProcess, int> {
 unsigned int SucceededProcess::invoked = 0;
 unsigned int SucceededProcess::invoked = 0;
 
 
 struct FailedProcess: entt::Process<FailedProcess, int> {
 struct FailedProcess: entt::Process<FailedProcess, int> {
-    void update(delta_type) {
+    void update(delta_type, void *) {
         ASSERT_FALSE(updated);
         ASSERT_FALSE(updated);
         updated = true;
         updated = true;
         fail();
         fail();
@@ -92,11 +92,11 @@ TEST(Scheduler, Functor) {
     bool firstFunctor = false;
     bool firstFunctor = false;
     bool secondFunctor = false;
     bool secondFunctor = false;
 
 
-    scheduler.attach([&firstFunctor](auto, auto resolve, auto){
+    scheduler.attach([&firstFunctor](auto, void *, auto resolve, auto){
         ASSERT_FALSE(firstFunctor);
         ASSERT_FALSE(firstFunctor);
         firstFunctor = true;
         firstFunctor = true;
         resolve();
         resolve();
-    }).then([&secondFunctor](auto, auto, auto reject){
+    }).then([&secondFunctor](auto, void *, auto, auto reject){
         ASSERT_FALSE(secondFunctor);
         ASSERT_FALSE(secondFunctor);
         secondFunctor = true;
         secondFunctor = true;
         reject();
         reject();