1#ifndef ENTT_PROCESS_PROCESS_HPP
2#define ENTT_PROCESS_PROCESS_HPP
8#include "../core/compressed_pair.hpp"
9#include "../core/type_traits.hpp"
17template<
typename,
typename,
typename>
18struct process_adaptor;
71template<
typename Delta,
typename Allocator>
72class basic_process:
public std::enable_shared_from_this<basic_process<Delta, Allocator>> {
73 enum class state : std::uint8_t {
84 virtual void update(
const Delta,
void *) {
88 virtual void succeeded() {}
89 virtual void failed() {}
90 virtual void aborted() {}
109 : next{nullptr, allocator},
110 current{state::idle} {}
138 return next.second();
144 current = state::aborted;
154 current = state::succeeded;
164 current = state::failed;
171 current = state::paused;
178 current = state::running;
186 [[nodiscard]]
bool alive() const noexcept {
187 return current == state::running || current == state::paused;
195 return current == state::finished;
202 [[nodiscard]]
bool paused() const noexcept {
203 return current == state::paused;
211 return current == state::rejected;
221 template<
typename Type,
typename... Args>
223 const auto &allocator = next.second();
224 return *(next.first() = std::allocate_shared<Type>(allocator, allocator, std::forward<Args>(args)...));
233 template<
typename Func>
235 const auto &allocator = next.second();
236 using process_type = internal::process_adaptor<delta_type, Func, allocator_type>;
237 return *(next.first() = std::allocate_shared<process_type>(allocator, allocator, std::move(func)));
253 void tick(
const Delta delta,
void *data =
nullptr) {
257 current = state::running;
267 case state::succeeded:
269 current = state::finished;
273 current = state::rejected;
277 current = state::rejected;
293template<
typename Delta,
typename Func,
typename Allocator>
294struct process_adaptor:
public basic_process<Delta, Allocator> {
295 using allocator_type = Allocator;
296 using base_type = basic_process<Delta, Allocator>;
297 using delta_type =
typename base_type::delta_type;
299 process_adaptor(
const allocator_type &allocator, Func proc)
300 : base_type{allocator},
301 func{std::move(proc)} {}
303 void update(
const delta_type delta,
void *data)
override {
304 func(*
this, delta, data);
handle_type peek()
Returns the child process without releasing ownership, if any.
bool finished() const noexcept
Returns true if a process is already terminated.
void unpause() noexcept
Restarts a process if it's paused, otherwise does nothing.
basic_process(basic_process &&)=delete
Default move constructor, deleted on purpose.
basic_process & operator=(const basic_process &)=delete
Default copy assignment operator, deleted on purpose.
basic_process(const basic_process &)=delete
Default copy constructor, deleted on purpose.
bool alive() const noexcept
Returns true if a process is either running or paused.
basic_process()
Default constructor.
basic_process & then(Func func)
Assigns a child process to run in case of success.
std::shared_ptr< basic_process > handle_type
void fail() noexcept
Terminates a process with errors if it's still alive, otherwise does nothing.
virtual ~basic_process()=default
Default destructor.
basic_process & then(Args &&...args)
Assigns a child process to run in case of success.
void abort()
Aborts a process if it's still alive, otherwise does nothing.
bool rejected() const noexcept
Returns true if a process terminated with errors.
basic_process & operator=(basic_process &&)=delete
Default move assignment operator, deleted on purpose.
void pause() noexcept
Stops a process if it's running, otherwise does nothing.
bool paused() const noexcept
Returns true if a process is currently paused.
void tick(const Delta delta, void *data=nullptr)
Updates a process and its internal state, if required.
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
basic_process(const allocator_type &allocator)
Constructs a scheduler with a given allocator.
void succeed() noexcept
Terminates a process with success if it's still alive, otherwise does nothing.