From 3126b3efbf4e18c56eff44b47d58a5154102e0b1 Mon Sep 17 00:00:00 2001 From: skypjack Date: Fri, 27 Jun 2025 11:27:12 +0200 Subject: [PATCH] scheduler: review internals to use peek/release/whatever - see #1257 --- src/entt/process/scheduler.hpp | 69 ++++++++++++---------------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/src/entt/process/scheduler.hpp b/src/entt/process/scheduler.hpp index 37cb07771..d057a7569 100644 --- a/src/entt/process/scheduler.hpp +++ b/src/entt/process/scheduler.hpp @@ -13,19 +13,6 @@ namespace entt { -/*! @cond TURN_OFF_DOXYGEN */ -namespace internal { - -template -struct process_handler { - // std::shared_ptr because of its type erased allocator which is useful here - std::shared_ptr next{}; - std::shared_ptr task{}; -}; - -} // namespace internal -/*! @endcond */ - /** * @brief Cooperative scheduler for processes. * @@ -55,23 +42,9 @@ struct process_handler { */ template class basic_scheduler { - using process_type = basic_process; using alloc_traits = std::allocator_traits; - using handler_type = internal::process_handler; - using container_allocator = typename alloc_traits::template rebind_alloc; - using container_type = std::vector; - - 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>>; + using container_type = std::vector>, container_allocator>; public: /*! @brief Allocator type. */ @@ -202,7 +175,7 @@ public: */ template basic_scheduler &attach(Args &&...args) { - handlers.first().emplace_back().task = std::allocate_shared(handlers.second(), std::forward(args)...); + handlers.first().emplace_back(std::allocate_shared(handlers.second(), std::forward(args)...)); return *this; } @@ -273,10 +246,13 @@ public: template basic_scheduler &then(Args &&...args) { 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(handlers.second()); - curr->next->task = std::allocate_shared(handlers.second(), std::forward(args)...); + auto curr = handlers.first().back(); + + for(auto child = curr->peek(); child; child = curr->peek()) { + curr = child; + } + + curr->then(std::allocate_shared(handlers.second(), std::forward(args)...)); return *this; } @@ -305,15 +281,18 @@ public: */ void update(const delta_type delta, void *data = nullptr) { 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) { for(auto &&curr: handlers.first()) { - curr.task->abort(); + curr->abort(); if(immediate) { - curr.task->tick({}); + curr->tick({}); } } }