EnTT 3.16.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 <memory>
6#include <type_traits>
7#include <utility>
8#include "../core/compressed_pair.hpp"
9#include "../core/type_traits.hpp"
10#include "fwd.hpp"
11
12namespace entt {
13
15namespace internal {
16
17template<typename, typename, typename>
18struct process_adaptor;
19
20} // namespace internal
22
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 {
74 idle = 0,
75 running,
76 paused,
77 succeeded,
78 failed,
79 aborted,
82 };
83
84 virtual void update(const Delta, void *) {
85 abort();
86 }
87
88 virtual void succeeded() {}
89 virtual void failed() {}
90 virtual void aborted() {}
91
92public:
94 using allocator_type = Allocator;
96 using delta_type = Delta;
98 using handle_type = std::shared_ptr<basic_process>;
99
103
108 explicit basic_process(const allocator_type &allocator)
109 : next{nullptr, allocator},
110 current{state::idle} {}
111
113 basic_process(const basic_process &) = delete;
114
117
119 virtual ~basic_process() = default;
120
126
132
137 [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
138 return next.second();
139 }
140
142 void abort() {
143 if(alive()) {
144 current = state::aborted;
145 }
146 }
147
152 void succeed() noexcept {
153 if(alive()) {
154 current = state::succeeded;
155 }
156 }
157
162 void fail() noexcept {
163 if(alive()) {
164 current = state::failed;
165 }
166 }
167
169 void pause() noexcept {
170 if(alive()) {
171 current = state::paused;
172 }
173 }
174
176 void unpause() noexcept {
177 if(alive()) {
178 current = state::running;
179 }
180 }
181
186 [[nodiscard]] bool alive() const noexcept {
187 return current == state::running || current == state::paused;
188 }
189
194 [[nodiscard]] bool finished() const noexcept {
195 return current == state::finished;
196 }
197
202 [[nodiscard]] bool paused() const noexcept {
203 return current == state::paused;
204 }
205
210 [[nodiscard]] bool rejected() const noexcept {
211 return current == state::rejected;
212 }
213
221 template<typename Type, typename... Args>
222 basic_process &then(Args &&...args) {
223 const auto &allocator = next.second();
224 return *(next.first() = std::allocate_shared<Type>(allocator, allocator, std::forward<Args>(args)...));
225 }
226
233 template<typename Func>
234 basic_process &then(Func 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)));
238 }
239
245 return next.first();
246 }
247
253 void tick(const Delta delta, void *data = nullptr) {
254 switch(current) {
255 case state::idle:
256 case state::running:
257 current = state::running;
258 update(delta, data);
259 break;
260 default:
261 // suppress warnings
262 break;
263 }
264
265 // if it's dead, it must be notified and removed immediately
266 switch(current) {
267 case state::succeeded:
268 succeeded();
269 current = state::finished;
270 break;
271 case state::failed:
272 failed();
273 current = state::rejected;
274 break;
275 case state::aborted:
276 aborted();
277 current = state::rejected;
278 break;
279 default:
280 // suppress warnings
281 break;
282 }
283 }
284
285private:
287 state current;
288};
289
291namespace internal {
292
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;
298
299 process_adaptor(const allocator_type &allocator, Func proc)
300 : base_type{allocator},
301 func{std::move(proc)} {}
302
303 void update(const delta_type delta, void *data) override {
304 func(*this, delta, data);
305 }
306
307private:
308 Func func;
309};
310
311} // namespace internal
313
314} // namespace entt
315
316#endif
handle_type peek()
Returns the child process without releasing ownership, if any.
Definition process.hpp:244
bool finished() const noexcept
Returns true if a process is already terminated.
Definition process.hpp:194
void unpause() noexcept
Restarts a process if it's paused, otherwise does nothing.
Definition process.hpp:176
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.
Definition process.hpp:186
basic_process()
Default constructor.
Definition process.hpp:101
basic_process & then(Func func)
Assigns a child process to run in case of success.
Definition process.hpp:234
std::shared_ptr< basic_process > handle_type
Definition process.hpp:98
void fail() noexcept
Terminates a process with errors if it's still alive, otherwise does nothing.
Definition process.hpp:162
virtual ~basic_process()=default
Default destructor.
basic_process & then(Args &&...args)
Assigns a child process to run in case of success.
Definition process.hpp:222
void abort()
Aborts a process if it's still alive, otherwise does nothing.
Definition process.hpp:142
bool rejected() const noexcept
Returns true if a process terminated with errors.
Definition process.hpp:210
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.
Definition process.hpp:169
bool paused() const noexcept
Returns true if a process is currently paused.
Definition process.hpp:202
void tick(const Delta delta, void *data=nullptr)
Updates a process and its internal state, if required.
Definition process.hpp:253
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
Definition process.hpp:137
basic_process(const allocator_type &allocator)
Constructs a scheduler with a given allocator.
Definition process.hpp:108
void succeed() noexcept
Terminates a process with success if it's still alive, otherwise does nothing.
Definition process.hpp:152
A compressed pair.
EnTT default namespace.
Definition dense_map.hpp:22