Line data Source code
1 : #pragma once
2 :
3 : #include <jage/engine/no_op.hpp>
4 : #include <jage/engine/scheduled_action_status.hpp>
5 :
6 : #include <chrono>
7 : #include <utility>
8 :
9 : namespace jage::engine {
10 : template <class TAction = no_op> class scheduled_action {
11 : scheduled_action_status scheduled_action_status_ =
12 : scheduled_action_status::active;
13 : std::chrono::nanoseconds nanoseconds_to_wait_{};
14 : TAction action_;
15 :
16 : public:
17 21 : scheduled_action() = default;
18 13 : scheduled_action(const std::chrono::nanoseconds nanoseconds_to_wait)
19 13 : : nanoseconds_to_wait_(nanoseconds_to_wait) {}
20 5 : scheduled_action(const std::chrono::nanoseconds nanoseconds_to_wait,
21 : TAction &&action)
22 5 : : nanoseconds_to_wait_(nanoseconds_to_wait), action_(action) {}
23 :
24 : [[gnu::pure, nodiscard]] auto
25 68 : status() const noexcept -> const scheduled_action_status & {
26 68 : return scheduled_action_status_;
27 : }
28 :
29 6 : auto pause() noexcept -> void {
30 6 : if (scheduled_action_status_ != scheduled_action_status::canceled) {
31 5 : scheduled_action_status_ = scheduled_action_status::paused;
32 : }
33 6 : }
34 :
35 3 : auto resume() noexcept -> void {
36 3 : if (scheduled_action_status_ != scheduled_action_status::canceled) {
37 2 : scheduled_action_status_ = scheduled_action_status::active;
38 : }
39 3 : }
40 :
41 6 : auto cancel() noexcept -> void {
42 6 : if (scheduled_action_status_ != scheduled_action_status::complete) {
43 5 : scheduled_action_status_ = scheduled_action_status::canceled;
44 : }
45 6 : }
46 :
47 5 : auto reset(const auto nanoseconds_to_wait) noexcept -> void {
48 5 : scheduled_action_status_ = scheduled_action_status::active;
49 5 : nanoseconds_to_wait_ = nanoseconds_to_wait;
50 5 : }
51 :
52 2 : auto extend(const auto additional_nanoseconds) noexcept -> void {
53 2 : nanoseconds_to_wait_ += additional_nanoseconds;
54 2 : }
55 :
56 24 : auto update(const auto nanoseconds_elapsed) {
57 : using namespace std::chrono_literals;
58 24 : if (is_complete() or scheduled_action_status::paused == status()) {
59 2 : return;
60 : }
61 22 : if (nanoseconds_to_wait_ < nanoseconds_elapsed) {
62 1 : nanoseconds_to_wait_ = 0ns;
63 : } else {
64 21 : nanoseconds_to_wait_ -= nanoseconds_elapsed;
65 : }
66 :
67 22 : if (nanoseconds_to_wait_ == 0ns) {
68 13 : scheduled_action_status_ = scheduled_action_status::complete;
69 13 : action_();
70 : }
71 : }
72 :
73 28 : [[gnu::pure, nodiscard]] auto is_complete() const noexcept -> bool {
74 28 : switch (status()) {
75 3 : case scheduled_action_status::complete:
76 : case scheduled_action_status::canceled:
77 3 : return true;
78 25 : case scheduled_action_status::paused:
79 : case scheduled_action_status::active:
80 25 : return false;
81 : }
82 : std::unreachable();
83 : }
84 : };
85 :
86 : template <class TAction>
87 : scheduled_action(const std::chrono::nanoseconds,
88 : TAction &&) -> scheduled_action<TAction>;
89 :
90 : } // namespace jage::engine
|