EnTT  3.5.0
process.hpp
1 #ifndef ENTT_PROCESS_PROCESS_HPP
2 #define ENTT_PROCESS_PROCESS_HPP
3 
4 
5 #include <utility>
6 #include <type_traits>
7 #include "../config/config.h"
8 #include "../core/type_traits.hpp"
9 
10 
11 namespace entt {
12 
13 
73 template<typename Derived, typename Delta>
74 class process {
75  enum class state: unsigned int {
76  UNINITIALIZED = 0,
77  RUNNING,
78  PAUSED,
79  SUCCEEDED,
80  FAILED,
81  ABORTED,
82  FINISHED
83  };
84 
85  template<typename Target = Derived>
87  -> decltype(std::declval<Target>().init(), void()) {
88  static_cast<Target *>(this)->init();
89  }
90 
91  template<typename Target = Derived>
92  auto next(integral_constant<state::RUNNING>, Delta delta, void *data)
93  -> decltype(std::declval<Target>().update(delta, data), void()) {
94  static_cast<Target *>(this)->update(delta, data);
95  }
96 
97  template<typename Target = Derived>
99  -> decltype(std::declval<Target>().succeeded(), void()) {
100  static_cast<Target *>(this)->succeeded();
101  }
102 
103  template<typename Target = Derived>
105  -> decltype(std::declval<Target>().failed(), void()) {
106  static_cast<Target *>(this)->failed();
107  }
108 
109  template<typename Target = Derived>
111  -> decltype(std::declval<Target>().aborted(), void()) {
112  static_cast<Target *>(this)->aborted();
113  }
114 
115  void next(...) const ENTT_NOEXCEPT {}
116 
117 protected:
124  void succeed() ENTT_NOEXCEPT {
125  if(alive()) {
126  current = state::SUCCEEDED;
127  }
128  }
129 
136  void fail() ENTT_NOEXCEPT {
137  if(alive()) {
138  current = state::FAILED;
139  }
140  }
141 
148  void pause() ENTT_NOEXCEPT {
149  if(current == state::RUNNING) {
150  current = state::PAUSED;
151  }
152  }
153 
160  void unpause() ENTT_NOEXCEPT {
161  if(current == state::PAUSED) {
162  current = state::RUNNING;
163  }
164  }
165 
166 public:
168  using delta_type = Delta;
169 
171  virtual ~process() {
172  static_assert(std::is_base_of_v<process, Derived>, "Incorrect use of the class template");
173  }
174 
183  void abort(const bool immediately = false) {
184  if(alive()) {
185  current = state::ABORTED;
186 
187  if(immediately) {
188  tick({});
189  }
190  }
191  }
192 
197  [[nodiscard]] bool alive() const ENTT_NOEXCEPT {
198  return current == state::RUNNING || current == state::PAUSED;
199  }
200 
205  [[nodiscard]] bool dead() const ENTT_NOEXCEPT {
206  return current == state::FINISHED;
207  }
208 
213  [[nodiscard]] bool paused() const ENTT_NOEXCEPT {
214  return current == state::PAUSED;
215  }
216 
221  [[nodiscard]] bool rejected() const ENTT_NOEXCEPT {
222  return stopped;
223  }
224 
230  void tick(const Delta delta, void *data = nullptr) {
231  switch (current) {
232  case state::UNINITIALIZED:
234  current = state::RUNNING;
235  break;
236  case state::RUNNING:
237  next(integral_constant<state::RUNNING>{}, delta, data);
238  break;
239  default:
240  // suppress warnings
241  break;
242  }
243 
244  // if it's dead, it must be notified and removed immediately
245  switch(current) {
246  case state::SUCCEEDED:
248  current = state::FINISHED;
249  break;
250  case state::FAILED:
252  current = state::FINISHED;
253  stopped = true;
254  break;
255  case state::ABORTED:
257  current = state::FINISHED;
258  stopped = true;
259  break;
260  default:
261  // suppress warnings
262  break;
263  }
264  }
265 
266 private:
267  state current{state::UNINITIALIZED};
268  bool stopped{false};
269 };
270 
271 
311 template<typename Func, typename Delta>
312 struct process_adaptor: process<process_adaptor<Func, Delta>, Delta>, private Func {
318  template<typename... Args>
319  process_adaptor(Args &&... args)
320  : Func{std::forward<Args>(args)...}
321  {}
322 
328  void update(const Delta delta, void *data) {
329  Func::operator()(delta, data, [this]() { this->succeed(); }, [this]() { this->fail(); });
330  }
331 };
332 
333 
334 }
335 
336 
337 #endif
entt::process::rejected
bool rejected() const noexcept
Returns true if a process terminated with errors.
Definition: process.hpp:221
entt::process::pause
void pause() noexcept
Stops a process if it's in a running state.
Definition: process.hpp:148
entt::process::fail
void fail() noexcept
Terminates a process with errors if it's still alive.
Definition: process.hpp:136
entt::process< process_adaptor< Func, Delta >, Delta >::delta_type
Delta delta_type
Type used to provide elapsed time.
Definition: process.hpp:168
entt::process::alive
bool alive() const noexcept
Returns true if a process is either running or paused.
Definition: process.hpp:197
entt::process::succeed
void succeed() noexcept
Terminates a process with success if it's still alive.
Definition: process.hpp:124
entt::integral_constant
std::integral_constant< decltype(Value), Value > integral_constant
Wraps a static constant.
Definition: type_traits.hpp:38
entt::process::unpause
void unpause() noexcept
Restarts a process if it's paused.
Definition: process.hpp:160
entt::process
Base class for processes.
Definition: process.hpp:74
entt::process_adaptor::process_adaptor
process_adaptor(Args &&... args)
Constructs a process adaptor from a lambda or a functor.
Definition: process.hpp:319
entt
EnTT default namespace.
Definition: algorithm.hpp:13
entt::process::dead
bool dead() const noexcept
Returns true if a process is already terminated.
Definition: process.hpp:205
entt::process::paused
bool paused() const noexcept
Returns true if a process is currently paused.
Definition: process.hpp:213
entt::process::abort
void abort(const bool immediately=false)
Aborts a process if it's still alive.
Definition: process.hpp:183
entt::process_adaptor
Adaptor for lambdas and functors to turn them into processes.
Definition: process.hpp:312
entt::process_adaptor::update
void update(const Delta delta, void *data)
Updates a process and its internal state if required.
Definition: process.hpp:328
entt::process::tick
void tick(const Delta delta, void *data=nullptr)
Updates a process and its internal state if required.
Definition: process.hpp:230
entt::process::~process
virtual ~process()
Default destructor.
Definition: process.hpp:171