EnTT  3.3.2
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 
9 
10 namespace entt {
11 
12 
72 template<typename Derived, typename Delta>
73 class process {
74  enum class state: unsigned int {
75  UNINITIALIZED = 0,
76  RUNNING,
77  PAUSED,
78  SUCCEEDED,
79  FAILED,
80  ABORTED,
81  FINISHED
82  };
83 
84  template<state value>
85  using state_value_t = std::integral_constant<state, value>;
86 
87  template<typename Target = Derived>
88  auto tick(int, state_value_t<state::UNINITIALIZED>)
89  -> decltype(std::declval<Target>().init()) {
90  static_cast<Target *>(this)->init();
91  }
92 
93  template<typename Target = Derived>
94  auto tick(int, state_value_t<state::RUNNING>, Delta delta, void *data)
95  -> decltype(std::declval<Target>().update(delta, data)) {
96  static_cast<Target *>(this)->update(delta, data);
97  }
98 
99  template<typename Target = Derived>
100  auto tick(int, state_value_t<state::SUCCEEDED>)
101  -> decltype(std::declval<Target>().succeeded()) {
102  static_cast<Target *>(this)->succeeded();
103  }
104 
105  template<typename Target = Derived>
106  auto tick(int, state_value_t<state::FAILED>)
107  -> decltype(std::declval<Target>().failed()) {
108  static_cast<Target *>(this)->failed();
109  }
110 
111  template<typename Target = Derived>
112  auto tick(int, state_value_t<state::ABORTED>)
113  -> decltype(std::declval<Target>().aborted()) {
114  static_cast<Target *>(this)->aborted();
115  }
116 
117  template<state value, typename... Args>
118  void tick(char, state_value_t<value>, Args &&...) const ENTT_NOEXCEPT {}
119 
120 protected:
127  void succeed() ENTT_NOEXCEPT {
128  if(alive()) {
129  current = state::SUCCEEDED;
130  }
131  }
132 
139  void fail() ENTT_NOEXCEPT {
140  if(alive()) {
141  current = state::FAILED;
142  }
143  }
144 
151  void pause() ENTT_NOEXCEPT {
152  if(current == state::RUNNING) {
153  current = state::PAUSED;
154  }
155  }
156 
163  void unpause() ENTT_NOEXCEPT {
164  if(current == state::PAUSED) {
165  current = state::RUNNING;
166  }
167  }
168 
169 public:
171  using delta_type = Delta;
172 
174  virtual ~process() {
175  static_assert(std::is_base_of_v<process, Derived>);
176  }
177 
186  void abort(const bool immediately = false) {
187  if(alive()) {
188  current = state::ABORTED;
189 
190  if(immediately) {
191  tick({});
192  }
193  }
194  }
195 
200  bool alive() const ENTT_NOEXCEPT {
201  return current == state::RUNNING || current == state::PAUSED;
202  }
203 
208  bool dead() const ENTT_NOEXCEPT {
209  return current == state::FINISHED;
210  }
211 
216  bool paused() const ENTT_NOEXCEPT {
217  return current == state::PAUSED;
218  }
219 
224  bool rejected() const ENTT_NOEXCEPT {
225  return stopped;
226  }
227 
233  void tick(const Delta delta, void *data = nullptr) {
234  switch (current) {
235  case state::UNINITIALIZED:
236  tick(0, state_value_t<state::UNINITIALIZED>{});
237  current = state::RUNNING;
238  break;
239  case state::RUNNING:
240  tick(0, state_value_t<state::RUNNING>{}, delta, data);
241  break;
242  default:
243  // suppress warnings
244  break;
245  }
246 
247  // if it's dead, it must be notified and removed immediately
248  switch(current) {
249  case state::SUCCEEDED:
250  tick(0, state_value_t<state::SUCCEEDED>{});
251  current = state::FINISHED;
252  break;
253  case state::FAILED:
254  tick(0, state_value_t<state::FAILED>{});
255  current = state::FINISHED;
256  stopped = true;
257  break;
258  case state::ABORTED:
259  tick(0, state_value_t<state::ABORTED>{});
260  current = state::FINISHED;
261  stopped = true;
262  break;
263  default:
264  // suppress warnings
265  break;
266  }
267  }
268 
269 private:
270  state current{state::UNINITIALIZED};
271  bool stopped{false};
272 };
273 
274 
314 template<typename Func, typename Delta>
315 struct process_adaptor: process<process_adaptor<Func, Delta>, Delta>, private Func {
321  template<typename... Args>
322  process_adaptor(Args &&... args)
323  : Func{std::forward<Args>(args)...}
324  {}
325 
331  void update(const Delta delta, void *data) {
332  Func::operator()(delta, data, [this]() { this->succeed(); }, [this]() { this->fail(); });
333  }
334 };
335 
336 
337 }
338 
339 
340 #endif
entt::process::rejected
bool rejected() const ENTT_NOEXCEPT
Returns true if a process terminated with errors.
Definition: process.hpp:224
entt::process::pause
void pause() ENTT_NOEXCEPT
Stops a process if it's in a running state.
Definition: process.hpp:151
entt::process< process_adaptor< Func, Delta >, Delta >::delta_type
Delta delta_type
Type used to provide elapsed time.
Definition: process.hpp:171
entt::process::dead
bool dead() const ENTT_NOEXCEPT
Returns true if a process is already terminated.
Definition: process.hpp:208
entt::process::alive
bool alive() const ENTT_NOEXCEPT
Returns true if a process is either running or paused.
Definition: process.hpp:200
entt::process::paused
bool paused() const ENTT_NOEXCEPT
Returns true if a process is currently paused.
Definition: process.hpp:216
entt::process
Base class for processes.
Definition: process.hpp:73
entt::process_adaptor::process_adaptor
process_adaptor(Args &&... args)
Constructs a process adaptor from a lambda or a functor.
Definition: process.hpp:322
entt::process::fail
void fail() ENTT_NOEXCEPT
Terminates a process with errors if it's still alive.
Definition: process.hpp:139
entt
EnTT default namespace.
Definition: algorithm.hpp:13
entt::process::abort
void abort(const bool immediately=false)
Aborts a process if it's still alive.
Definition: process.hpp:186
entt::process_adaptor
Adaptor for lambdas and functors to turn them into processes.
Definition: process.hpp:315
entt::process_adaptor::update
void update(const Delta delta, void *data)
Updates a process and its internal state if required.
Definition: process.hpp:331
entt::process::tick
void tick(const Delta delta, void *data=nullptr)
Updates a process and its internal state if required.
Definition: process.hpp:233
entt::process::~process
virtual ~process()
Default destructor.
Definition: process.hpp:174
entt::process::succeed
void succeed() ENTT_NOEXCEPT
Terminates a process with success if it's still alive.
Definition: process.hpp:127
entt::process::unpause
void unpause() ENTT_NOEXCEPT
Restarts a process if it's paused.
Definition: process.hpp:163