1#ifndef ENTT_PROCESS_SCHEDULER_HPP 
    2#define ENTT_PROCESS_SCHEDULER_HPP 
    9#include "../config/config.h" 
   10#include "../core/compressed_pair.hpp" 
   19template<
typename Delta>
 
   20struct basic_process_handler {
 
   21    virtual ~basic_process_handler() = 
default;
 
   23    virtual bool update(Delta, 
void *) = 0;
 
   24    virtual void abort(
bool) = 0;
 
   27    std::shared_ptr<basic_process_handler> next;
 
   30template<
typename Delta, 
typename Type>
 
   31struct process_handler final: basic_process_handler<Delta> {
 
   32    template<
typename... Args>
 
   33    process_handler(Args &&...args)
 
   34        : process{std::forward<Args>(args)...} {}
 
   36    bool update(
const Delta delta, 
void *data)
 override {
 
   37        if(process.tick(delta, data); process.rejected()) {
 
   41        return (process.rejected() || process.finished());
 
   44    void abort(
const bool immediate)
 override {
 
   45        process.abort(immediate);
 
   81template<
typename Delta, 
typename Allocator>
 
   83    template<
typename Type>
 
   84    using handler_type = internal::process_handler<Delta, Type>;
 
   87    using process_type = std::shared_ptr<internal::basic_process_handler<Delta>>;
 
   89    using alloc_traits = std::allocator_traits<Allocator>;
 
   90    using container_allocator = 
typename alloc_traits::template rebind_alloc<process_type>;
 
   91    using container_type = std::vector<process_type, container_allocator>;
 
  110        : handlers{allocator, allocator} {}
 
 
  120        : handlers{std::move(other.handlers)} {}
 
 
  128        : handlers{container_type{std::move(other.handlers.first()), allocator}, allocator} {
 
  129        ENTT_ASSERT(alloc_traits::is_always_equal::value || 
get_allocator() == other.get_allocator(), 
"Copying a scheduler is not allowed");
 
 
  147        ENTT_ASSERT(alloc_traits::is_always_equal::value || 
get_allocator() == other.get_allocator(), 
"Copying a scheduler is not allowed");
 
 
  158        swap(handlers, other.handlers);
 
 
  166        return handlers.second();
 
 
  174        return handlers.first().size();
 
 
  181    [[nodiscard]] 
bool empty() const noexcept {
 
  182        return handlers.first().empty();
 
 
  192        handlers.first().clear();
 
 
  220    template<
typename Proc, 
typename... Args>
 
  222        static_assert(std::is_base_of_v<process<Proc, Delta>, Proc>, 
"Invalid process type");
 
  223        auto &
ref = handlers.first().emplace_back(std::allocate_shared<handler_type<Proc>>(handlers.second(), std::forward<Args>(args)...));
 
  225        ref->update({}, 
nullptr);
 
 
  280    template<
typename Func>
 
  293    template<
typename Proc, 
typename... Args>
 
  295        static_assert(std::is_base_of_v<process<Proc, Delta>, Proc>, 
"Invalid process type");
 
  296        ENTT_ASSERT(!handlers.first().empty(), 
"Process not available");
 
  297        auto *curr = handlers.first().back().get();
 
  298        for(; curr->next; curr = curr->next.get()) {}
 
  299        curr->next = std::allocate_shared<handler_type<Proc>>(handlers.second(), std::forward<Args>(args)...);
 
 
  309    template<
typename Func>
 
  327        for(
auto next = handlers.first().size(); next; --next) {
 
  328            if(
const auto pos = next - 1u; handlers.first()[pos]->
update(delta, data)) {
 
  330                if(
auto &curr = handlers.first()[pos]; curr->next) {
 
  331                    curr = std::move(curr->next);
 
  333                    curr->update({}, 
nullptr);
 
  335                    curr = std::move(handlers.first().back());
 
  336                    handlers.first().pop_back();
 
 
  352    void abort(
const bool immediate = 
false) {
 
  353        for(
auto &&curr: handlers.first()) {
 
  354            curr->abort(immediate);
 
 
 
bool empty() const noexcept
Returns true if at least a process is currently scheduled.
 
basic_scheduler(const basic_scheduler &)=delete
Default copy constructor, deleted on purpose.
 
basic_scheduler()
Default constructor.
 
size_type size() const noexcept
Number of processes currently scheduled.
 
basic_scheduler & operator=(const basic_scheduler &)=delete
Default copy assignment operator, deleted on purpose.
 
basic_scheduler(basic_scheduler &&other) noexcept
Move constructor.
 
basic_scheduler & then(Func &&func)
Sets a process as a continuation of the last scheduled process.
 
basic_scheduler(const allocator_type &allocator)
Constructs a scheduler with a given allocator.
 
~basic_scheduler()=default
Default destructor.
 
basic_scheduler & operator=(basic_scheduler &&other) noexcept
Move assignment operator.
 
basic_scheduler & then(Args &&...args)
Sets a process as a continuation of the last scheduled process.
 
void update(const delta_type delta, void *data=nullptr)
Updates all scheduled processes.
 
basic_scheduler(basic_scheduler &&other, const allocator_type &allocator)
Allocator-extended move constructor.
 
void abort(const bool immediate=false)
Aborts all scheduled processes.
 
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
 
basic_scheduler & attach(Func &&func)
Schedules a process for the next tick.
 
void swap(basic_scheduler &other) noexcept
Exchanges the contents with those of a given scheduler.
 
void clear()
Discards all scheduled processes.
 
basic_scheduler & attach(Args &&...args)
Schedules a process for the next tick.
 
@ ref
Aliasing mode, the object points to a non-const element.
 
Adaptor for lambdas and functors to turn them into processes.