EnTT 3.14.0
Loading...
Searching...
No Matches
process.hpp
1#ifndef ENTT_PROCESS_PROCESS_HPP
2#define ENTT_PROCESS_PROCESS_HPP
3
4#include <cstdint>
5#include <type_traits>
6#include <utility>
7#include "fwd.hpp"
8
9namespace entt {
10
70template<typename Derived, typename Delta>
71class process {
72 enum class state : std::uint8_t {
73 uninitialized = 0,
74 running,
75 paused,
76 succeeded,
77 failed,
78 aborted,
81 };
82
83 template<typename Target = Derived>
84 auto next(std::integral_constant<state, state::uninitialized>)
85 -> decltype(std::declval<Target>().init(), void()) {
86 static_cast<Target *>(this)->init();
87 }
88
89 template<typename Target = Derived>
90 auto next(std::integral_constant<state, state::running>, Delta delta, void *data)
91 -> decltype(std::declval<Target>().update(delta, data), void()) {
92 static_cast<Target *>(this)->update(delta, data);
93 }
94
95 template<typename Target = Derived>
96 auto next(std::integral_constant<state, state::succeeded>)
97 -> decltype(std::declval<Target>().succeeded(), void()) {
98 static_cast<Target *>(this)->succeeded();
99 }
100
101 template<typename Target = Derived>
102 auto next(std::integral_constant<state, state::failed>)
103 -> decltype(std::declval<Target>().failed(), void()) {
104 static_cast<Target *>(this)->failed();
105 }
106
107 template<typename Target = Derived>
108 auto next(std::integral_constant<state, state::aborted>)
109 -> decltype(std::declval<Target>().aborted(), void()) {
110 static_cast<Target *>(this)->aborted();
111 }
112
113 template<typename... Args>
114 void next(Args &&...) const noexcept {}
115
116protected:
124 if(alive()) {
125 current = state::succeeded;
126 }
127 }
128
135 void fail() noexcept {
136 if(alive()) {
137 current = state::failed;
138 }
139 }
140
148 if(current == state::running) {
149 current = state::paused;
150 }
151 }
152
160 if(current == state::paused) {
161 current = state::running;
162 }
163 }
164
165public:
168
170 constexpr process() = default;
171
173 process(const process &) = default;
174
177
183
189
192 static_assert(std::is_base_of_v<process, Derived>, "Incorrect use of the class template");
193 }
194
203 void abort(const bool immediate = false) {
204 if(alive()) {
205 current = state::aborted;
206
207 if(immediate) {
208 tick({});
209 }
210 }
211 }
212
218 return current == state::running || current == state::paused;
219 }
220
226 return current == state::finished;
227 }
228
234 return current == state::paused;
235 }
236
242 return current == state::rejected;
243 }
244
250 void tick(const Delta delta, void *data = nullptr) {
251 switch(current) {
252 case state::uninitialized:
253 next(std::integral_constant<state, state::uninitialized>{});
254 current = state::running;
255 break;
256 case state::running:
257 next(std::integral_constant<state, state::running>{}, delta, data);
258 break;
259 default:
260 // suppress warnings
261 break;
262 }
263
264 // if it's dead, it must be notified and removed immediately
265 switch(current) {
266 case state::succeeded:
267 next(std::integral_constant<state, state::succeeded>{});
268 current = state::finished;
269 break;
270 case state::failed:
271 next(std::integral_constant<state, state::failed>{});
272 current = state::rejected;
273 break;
274 case state::aborted:
275 next(std::integral_constant<state, state::aborted>{});
276 current = state::rejected;
277 break;
278 default:
279 // suppress warnings
280 break;
281 }
282 }
283
284private:
285 state current{state::uninitialized};
286};
287
327template<typename Func, typename Delta>
328struct process_adaptor: process<process_adaptor<Func, Delta>, Delta>, private Func {
334 template<typename... Args>
336 : Func{std::forward<Args>(args)...} {}
337
343 void update(const Delta delta, void *data) {
344 Func::operator()(
345 delta,
346 data,
347 [this]() { this->succeed(); },
348 [this]() { this->fail(); });
349 }
350};
351
352} // namespace entt
353
354#endif
Base class for processes.
Definition process.hpp:71
bool finished() const noexcept
Returns true if a process is already terminated.
Definition process.hpp:225
process(const process &)=default
Default copy constructor.
void pause() noexcept
Stops a process if it's in a running state.
Definition process.hpp:147
void succeed() noexcept
Terminates a process with success if it's still alive.
Definition process.hpp:123
constexpr process()=default
Default constructor.
void unpause() noexcept
Restarts a process if it's paused.
Definition process.hpp:159
process(process &&) noexcept=default
Default move constructor.
Delta delta_type
Type used to provide elapsed time.
Definition process.hpp:167
bool rejected() const noexcept
Returns true if a process terminated with errors.
Definition process.hpp:241
void fail() noexcept
Terminates a process with errors if it's still alive.
Definition process.hpp:135
bool alive() const noexcept
Returns true if a process is either running or paused.
Definition process.hpp:217
void tick(const Delta delta, void *data=nullptr)
Updates a process and its internal state if required.
Definition process.hpp:250
void abort(const bool immediate=false)
Aborts a process if it's still alive.
Definition process.hpp:203
bool paused() const noexcept
Returns true if a process is currently paused.
Definition process.hpp:233
EnTT default namespace.
Definition dense_map.hpp:22
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
Definition memory.hpp:219
Adaptor for lambdas and functors to turn them into processes.
Definition process.hpp:328
void update(const Delta delta, void *data)
Updates a process and its internal state if required.
Definition process.hpp:343
process_adaptor(Args &&...args)
Constructs a process adaptor from a lambda or a functor.
Definition process.hpp:335