From 61e5bcef2629e2d68b805a956a96fff264d4f74d Mon Sep 17 00:00:00 2001 From: untodesu Date: Sat, 28 Jun 2025 01:59:49 +0500 Subject: Restructure dependencies and update to C++20 - Nuked static_assert from almost everywhere in the project - Nuked binary dependency support. Might add one later though - Separated dependency headers into a separate include subdirectory - Grafted a thirdpartylegalnotices.txt generator from RITEG - Pushed development snapshot version to 2126 (26th week of 2025) --- deps/include/entt/process/scheduler.hpp | 364 -------------------------------- 1 file changed, 364 deletions(-) delete mode 100644 deps/include/entt/process/scheduler.hpp (limited to 'deps/include/entt/process/scheduler.hpp') diff --git a/deps/include/entt/process/scheduler.hpp b/deps/include/entt/process/scheduler.hpp deleted file mode 100644 index 6cd27db..0000000 --- a/deps/include/entt/process/scheduler.hpp +++ /dev/null @@ -1,364 +0,0 @@ -#ifndef ENTT_PROCESS_SCHEDULER_HPP -#define ENTT_PROCESS_SCHEDULER_HPP - -#include -#include -#include -#include -#include -#include "../config/config.h" -#include "../core/compressed_pair.hpp" -#include "fwd.hpp" -#include "process.hpp" - -namespace entt { - -/*! @cond TURN_OFF_DOXYGEN */ -namespace internal { - -template -struct basic_process_handler { - virtual ~basic_process_handler() noexcept = default; - - virtual bool update(const Delta, void *) = 0; - virtual void abort(const bool) = 0; - - // std::shared_ptr because of its type erased allocator which is useful here - std::shared_ptr next; -}; - -template -struct process_handler final: basic_process_handler { - template - process_handler(Args &&...args) - : process{std::forward(args)...} {} - - bool update(const Delta delta, void *data) override { - if(process.tick(delta, data); process.rejected()) { - this->next.reset(); - } - - return (process.rejected() || process.finished()); - } - - void abort(const bool immediate) override { - process.abort(immediate); - } - - Type process; -}; - -} // namespace internal -/*! @endcond */ - -/** - * @brief Cooperative scheduler for processes. - * - * A cooperative scheduler runs processes and helps managing their life cycles. - * - * Each process is invoked once per tick. If a process terminates, it's - * removed automatically from the scheduler and it's never invoked again.
- * A process can also have a child. In this case, the process is replaced with - * its child when it terminates if it returns with success. In case of errors, - * both the process and its child are discarded. - * - * Example of use (pseudocode): - * - * @code{.cpp} - * scheduler.attach([](auto delta, void *, auto succeed, auto fail) { - * // code - * }).then(arguments...); - * @endcode - * - * In order to invoke all scheduled processes, call the `update` member function - * passing it the elapsed time to forward to the tasks. - * - * @sa process - * - * @tparam Delta Type to use to provide elapsed time. - * @tparam Allocator Type of allocator used to manage memory and elements. - */ -template -class basic_scheduler { - template - using handler_type = internal::process_handler; - - // std::shared_ptr because of its type erased allocator which is useful here - using process_type = std::shared_ptr>; - - using alloc_traits = std::allocator_traits; - using container_allocator = typename alloc_traits::template rebind_alloc; - using container_type = std::vector; - -public: - /*! @brief Allocator type. */ - using allocator_type = Allocator; - /*! @brief Unsigned integer type. */ - using size_type = std::size_t; - /*! @brief Unsigned integer type. */ - using delta_type = Delta; - - /*! @brief Default constructor. */ - basic_scheduler() - : basic_scheduler{allocator_type{}} {} - - /** - * @brief Constructs a scheduler with a given allocator. - * @param allocator The allocator to use. - */ - explicit basic_scheduler(const allocator_type &allocator) - : handlers{allocator, allocator} {} - - /*! @brief Default copy constructor, deleted on purpose. */ - basic_scheduler(const basic_scheduler &) = delete; - - /** - * @brief Move constructor. - * @param other The instance to move from. - */ - basic_scheduler(basic_scheduler &&other) noexcept - : handlers{std::move(other.handlers)} {} - - /** - * @brief Allocator-extended move constructor. - * @param other The instance to move from. - * @param allocator The allocator to use. - */ - basic_scheduler(basic_scheduler &&other, const allocator_type &allocator) - : handlers{container_type{std::move(other.handlers.first()), allocator}, allocator} { - ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a scheduler is not allowed"); - } - - /*! @brief Default destructor. */ - ~basic_scheduler() noexcept = default; - - /** - * @brief Default copy assignment operator, deleted on purpose. - * @return This process scheduler. - */ - basic_scheduler &operator=(const basic_scheduler &) = delete; - - /** - * @brief Move assignment operator. - * @param other The instance to move from. - * @return This process scheduler. - */ - basic_scheduler &operator=(basic_scheduler &&other) noexcept { - ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a scheduler is not allowed"); - handlers = std::move(other.handlers); - return *this; - } - - /** - * @brief Exchanges the contents with those of a given scheduler. - * @param other Scheduler to exchange the content with. - */ - void swap(basic_scheduler &other) { - using std::swap; - swap(handlers, other.handlers); - } - - /** - * @brief Returns the associated allocator. - * @return The associated allocator. - */ - [[nodiscard]] constexpr allocator_type get_allocator() const noexcept { - return handlers.second(); - } - - /** - * @brief Number of processes currently scheduled. - * @return Number of processes currently scheduled. - */ - [[nodiscard]] size_type size() const noexcept { - return handlers.first().size(); - } - - /** - * @brief Returns true if at least a process is currently scheduled. - * @return True if there are scheduled processes, false otherwise. - */ - [[nodiscard]] bool empty() const noexcept { - return handlers.first().empty(); - } - - /** - * @brief Discards all scheduled processes. - * - * Processes aren't aborted. They are discarded along with their children - * and never executed again. - */ - void clear() { - handlers.first().clear(); - } - - /** - * @brief Schedules a process for the next tick. - * - * Returned value can be used to attach a continuation for the last process. - * The continutation is scheduled automatically when the process terminates - * and only if the process returns with success. - * - * Example of use (pseudocode): - * - * @code{.cpp} - * // schedules a task in the form of a process class - * scheduler.attach(arguments...) - * // appends a child in the form of a lambda function - * .then([](auto delta, void *, auto succeed, auto fail) { - * // code - * }) - * // appends a child in the form of another process class - * .then(); - * @endcode - * - * @tparam Proc Type of process to schedule. - * @tparam Args Types of arguments to use to initialize the process. - * @param args Parameters to use to initialize the process. - * @return This process scheduler. - */ - template - basic_scheduler &attach(Args &&...args) { - static_assert(std::is_base_of_v, Proc>, "Invalid process type"); - auto &ref = handlers.first().emplace_back(std::allocate_shared>(handlers.second(), std::forward(args)...)); - // forces the process to exit the uninitialized state - ref->update({}, nullptr); - return *this; - } - - /** - * @brief Schedules a process for the next tick. - * - * A process can be either a lambda or a functor. The scheduler wraps both - * of them in a process adaptor internally.
- * The signature of the function call operator should be equivalent to the - * following: - * - * @code{.cpp} - * void(Delta delta, void *data, auto succeed, auto fail); - * @endcode - * - * Where: - * - * * `delta` is the elapsed time. - * * `data` is an opaque pointer to user data if any, `nullptr` otherwise. - * * `succeed` is a function to call when a process terminates with success. - * * `fail` is a function to call when a process terminates with errors. - * - * The signature of the function call operator of both `succeed` and `fail` - * is equivalent to the following: - * - * @code{.cpp} - * void(); - * @endcode - * - * Returned value can be used to attach a continuation for the last process. - * The continutation is scheduled automatically when the process terminates - * and only if the process returns with success. - * - * Example of use (pseudocode): - * - * @code{.cpp} - * // schedules a task in the form of a lambda function - * scheduler.attach([](auto delta, void *, auto succeed, auto fail) { - * // code - * }) - * // appends a child in the form of another lambda function - * .then([](auto delta, void *, auto succeed, auto fail) { - * // code - * }) - * // appends a child in the form of a process class - * .then(arguments...); - * @endcode - * - * @sa process_adaptor - * - * @tparam Func Type of process to schedule. - * @param func Either a lambda or a functor to use as a process. - * @return This process scheduler. - */ - template - basic_scheduler &attach(Func &&func) { - using Proc = process_adaptor, Delta>; - return attach(std::forward(func)); - } - - /** - * @brief Sets a process as a continuation of the last scheduled process. - * @tparam Proc Type of process to use as a continuation. - * @tparam Args Types of arguments to use to initialize the process. - * @param args Parameters to use to initialize the process. - * @return This process scheduler. - */ - template - basic_scheduler &then(Args &&...args) { - static_assert(std::is_base_of_v, Proc>, "Invalid process type"); - ENTT_ASSERT(!handlers.first().empty(), "Process not available"); - auto *curr = handlers.first().back().get(); - for(; curr->next; curr = curr->next.get()) {} - curr->next = std::allocate_shared>(handlers.second(), std::forward(args)...); - return *this; - } - - /** - * @brief Sets a process as a continuation of the last scheduled process. - * @tparam Func Type of process to use as a continuation. - * @param func Either a lambda or a functor to use as a process. - * @return This process scheduler. - */ - template - basic_scheduler &then(Func &&func) { - using Proc = process_adaptor, Delta>; - return then(std::forward(func)); - } - - /** - * @brief Updates all scheduled processes. - * - * All scheduled processes are executed in no specific order.
- * If a process terminates with success, it's replaced with its child, if - * any. Otherwise, if a process terminates with an error, it's removed along - * with its child. - * - * @param delta Elapsed time. - * @param data Optional data. - */ - void update(const delta_type delta, void *data = nullptr) { - for(auto next = handlers.first().size(); next; --next) { - if(const auto pos = next - 1u; handlers.first()[pos]->update(delta, data)) { - // updating might spawn/reallocate, cannot hold refs until here - if(auto &curr = handlers.first()[pos]; curr->next) { - curr = std::move(curr->next); - // forces the process to exit the uninitialized state - curr->update({}, nullptr); - } else { - curr = std::move(handlers.first().back()); - handlers.first().pop_back(); - } - } - } - } - - /** - * @brief Aborts all scheduled processes. - * - * Unless an immediate operation is requested, the abort is scheduled for - * the next tick. Processes won't be executed anymore in any case.
- * Once a process is fully aborted and thus finished, it's discarded along - * with its child, if any. - * - * @param immediate Requests an immediate operation. - */ - void abort(const bool immediate = false) { - for(auto &&curr: handlers.first()) { - curr->abort(immediate); - } - } - -private: - compressed_pair handlers; -}; - -} // namespace entt - -#endif -- cgit