1 #ifndef ENTT_PROCESS_PROCESS_HPP
2 #define ENTT_PROCESS_PROCESS_HPP
7 #include "../config/config.h"
72 template<
typename Derived,
typename Delta>
74 enum class state: unsigned int {
85 template<
typename Target = Derived>
86 auto next(std::integral_constant<state, state::UNINITIALIZED>)
87 -> decltype(std::declval<Target>().init(),
void()) {
88 static_cast<Target *
>(
this)->init();
91 template<
typename Target = Derived>
92 auto next(std::integral_constant<state, state::RUNNING>, Delta delta,
void *data)
93 -> decltype(std::declval<Target>().update(delta, data),
void()) {
94 static_cast<Target *
>(
this)->update(delta, data);
97 template<
typename Target = Derived>
98 auto next(std::integral_constant<state, state::SUCCEEDED>)
99 -> decltype(std::declval<Target>().succeeded(),
void()) {
100 static_cast<Target *
>(
this)->succeeded();
103 template<
typename Target = Derived>
104 auto next(std::integral_constant<state, state::FAILED>)
105 -> decltype(std::declval<Target>().failed(),
void()) {
106 static_cast<Target *
>(
this)->failed();
109 template<
typename Target = Derived>
110 auto next(std::integral_constant<state, state::ABORTED>)
111 -> decltype(std::declval<Target>().aborted(),
void()) {
112 static_cast<Target *
>(
this)->aborted();
115 void next(...)
const ENTT_NOEXCEPT {}
126 current = state::SUCCEEDED;
138 current = state::FAILED;
149 if(current == state::RUNNING) {
150 current = state::PAUSED;
161 if(current == state::PAUSED) {
162 current = state::RUNNING;
172 static_assert(std::is_base_of_v<process, Derived>,
"Incorrect use of the class template");
183 void abort(
const bool immediately =
false) {
185 current = state::ABORTED;
197 [[nodiscard]]
bool alive() const ENTT_NOEXCEPT {
198 return current == state::RUNNING || current == state::PAUSED;
205 [[nodiscard]]
bool finished() const ENTT_NOEXCEPT {
206 return current == state::FINISHED;
213 [[nodiscard]]
bool paused() const ENTT_NOEXCEPT {
214 return current == state::PAUSED;
221 [[nodiscard]]
bool rejected() const ENTT_NOEXCEPT {
222 return current == state::REJECTED;
230 void tick(
const Delta delta,
void *data =
nullptr) {
232 case state::UNINITIALIZED:
233 next(std::integral_constant<state, state::UNINITIALIZED>{});
234 current = state::RUNNING;
237 next(std::integral_constant<state, state::RUNNING>{}, delta, data);
246 case state::SUCCEEDED:
247 next(std::integral_constant<state, state::SUCCEEDED>{});
248 current = state::FINISHED;
251 next(std::integral_constant<state, state::FAILED>{});
252 current = state::REJECTED;
255 next(std::integral_constant<state, state::ABORTED>{});
256 current = state::REJECTED;
265 state current{state::UNINITIALIZED};
308 template<
typename Func,
typename Delta>
315 template<
typename... Args>
317 : Func{std::forward<Args>(args)...}
325 void update(
const Delta delta,
void *data) {
326 Func::operator()(delta, data, [
this]() { this->
succeed(); }, [
this]() { this->
fail(); });
Base class for processes.
bool alive() const
Returns true if a process is either running or paused.
virtual ~process()
Default destructor.
void succeed()
Terminates a process with success if it's still alive.
void fail()
Terminates a process with errors if it's still alive.
void pause()
Stops a process if it's in a running state.
bool finished() const
Returns true if a process is already terminated.
Delta delta_type
Type used to provide elapsed time.
bool paused() const
Returns true if a process is currently paused.
void unpause()
Restarts a process if it's paused.
bool rejected() const
Returns true if a process terminated with errors.
void tick(const Delta delta, void *data=nullptr)
Updates a process and its internal state if required.
void abort(const bool immediately=false)
Aborts a process if it's still alive.
Adaptor for lambdas and functors to turn them into processes.
void update(const Delta delta, void *data)
Updates a process and its internal state if required.
process_adaptor(Args &&... args)
Constructs a process adaptor from a lambda or a functor.