Browse Source

scheduler: review internals to use peek/release/whatever - see #1257

skypjack 9 months ago
parent
commit
3126b3efbf
1 changed files with 24 additions and 45 deletions
  1. 24 45
      src/entt/process/scheduler.hpp

+ 24 - 45
src/entt/process/scheduler.hpp

@@ -13,19 +13,6 @@
 
 
 namespace entt {
 namespace entt {
 
 
-/*! @cond TURN_OFF_DOXYGEN */
-namespace internal {
-
-template<typename Type>
-struct process_handler {
-    // std::shared_ptr because of its type erased allocator which is useful here
-    std::shared_ptr<process_handler> next{};
-    std::shared_ptr<Type> task{};
-};
-
-} // namespace internal
-/*! @endcond */
-
 /**
 /**
  * @brief Cooperative scheduler for processes.
  * @brief Cooperative scheduler for processes.
  *
  *
@@ -55,23 +42,9 @@ struct process_handler {
  */
  */
 template<typename Delta, typename Allocator>
 template<typename Delta, typename Allocator>
 class basic_scheduler {
 class basic_scheduler {
-    using process_type = basic_process<Delta>;
     using alloc_traits = std::allocator_traits<Allocator>;
     using alloc_traits = std::allocator_traits<Allocator>;
-    using handler_type = internal::process_handler<process_type>;
-    using container_allocator = typename alloc_traits::template rebind_alloc<handler_type>;
-    using container_type = std::vector<handler_type, container_allocator>;
-
-    bool update(const std::size_t pos, const Delta delta, void *data) {
-        handlers.first()[pos].task->tick(delta, data);
-        // callbacks can insert or erase tasks, invalidating the reference
-        auto &elem = handlers.first()[pos];
-
-        if(elem.task->rejected()) {
-            elem.next.reset();
-        }
-
-        return (elem.task->rejected() || elem.task->finished());
-    }
+    using container_allocator = typename alloc_traits::template rebind_alloc<std::shared_ptr<basic_process<Delta>>>;
+    using container_type = std::vector<std::shared_ptr<basic_process<Delta>>, container_allocator>;
 
 
 public:
 public:
     /*! @brief Allocator type. */
     /*! @brief Allocator type. */
@@ -202,7 +175,7 @@ public:
      */
      */
     template<typename Proc, typename... Args>
     template<typename Proc, typename... Args>
     basic_scheduler &attach(Args &&...args) {
     basic_scheduler &attach(Args &&...args) {
-        handlers.first().emplace_back().task = std::allocate_shared<Proc>(handlers.second(), std::forward<Args>(args)...);
+        handlers.first().emplace_back(std::allocate_shared<Proc>(handlers.second(), std::forward<Args>(args)...));
         return *this;
         return *this;
     }
     }
 
 
@@ -273,10 +246,13 @@ public:
     template<typename Proc, typename... Args>
     template<typename Proc, typename... Args>
     basic_scheduler &then(Args &&...args) {
     basic_scheduler &then(Args &&...args) {
         ENTT_ASSERT(!handlers.first().empty(), "Process not available");
         ENTT_ASSERT(!handlers.first().empty(), "Process not available");
-        auto *curr = &handlers.first().back();
-        for(; curr->next; curr = curr->next.get()) {}
-        curr->next = std::allocate_shared<handler_type>(handlers.second());
-        curr->next->task = std::allocate_shared<Proc>(handlers.second(), std::forward<Args>(args)...);
+        auto curr = handlers.first().back();
+
+        for(auto child = curr->peek(); child; child = curr->peek()) {
+            curr = child;
+        }
+
+        curr->then(std::allocate_shared<Proc>(handlers.second(), std::forward<Args>(args)...));
         return *this;
         return *this;
     }
     }
 
 
@@ -305,15 +281,18 @@ public:
      */
      */
     void update(const delta_type delta, void *data = nullptr) {
     void update(const delta_type delta, void *data = nullptr) {
         for(auto next = handlers.first().size(); next; --next) {
         for(auto next = handlers.first().size(); next; --next) {
-            if(const auto pos = next - 1u; update(pos, delta, data)) {
-                // updating might spawn/reallocate, cannot hold refs until here
-                if(auto &curr = handlers.first()[pos]; curr.next) {
-                    auto elem = curr.next;
-                    curr = std::move(*elem);
-                } else {
-                    curr = std::move(handlers.first().back());
-                    handlers.first().pop_back();
-                }
+            const auto pos = next - 1u;
+            handlers.first()[pos]->tick(delta, data);
+            // updating might spawn/reallocate, cannot hold refs until here
+            auto &elem = handlers.first()[pos];
+
+            if(elem->finished()) {
+                elem = std::move(elem->release());
+            }
+
+            if(!elem || elem->rejected()) {
+                elem = std::move(handlers.first().back());
+                handlers.first().pop_back();
             }
             }
         }
         }
     }
     }
@@ -330,10 +309,10 @@ public:
      */
      */
     void abort(const bool immediate = false) {
     void abort(const bool immediate = false) {
         for(auto &&curr: handlers.first()) {
         for(auto &&curr: handlers.first()) {
-            curr.task->abort();
+            curr->abort();
 
 
             if(immediate) {
             if(immediate) {
-                curr.task->tick({});
+                curr->tick({});
             }
             }
         }
         }
     }
     }