MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Event.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Promise.hpp"
4
5namespace MayaFlux::Vruta {
6
7/**
8 * @class Event
9 * @brief Coroutine type for event-driven suspension
10 *
11 * Events suspend on EventAwaiter (window events, custom signals, etc.)
12 * and are resumed directly by EventSource when events occur.
13 *
14 * Unlike AudioRoutine/GraphicsRoutine, there is no periodic processing.
15 * Events are "fire-and-forget" - they run until completion or
16 * explicit cancellation.
17 *
18 * Usage:
19 * auto handler = [](Window* w) -> Event {
20 * while (true) {
21 * auto event = co_await w->get_event_source().next_event();
22 * // Handle event
23 * }
24 * };
25 */
26class MAYAFLUX_API Event {
27public:
29
30 /**
31 * @brief Constructs a Event from a coroutine handle
32 * @param h Handle to the coroutine
33 *
34 * Creates a Event that wraps and manages the given coroutine.
35 * This is typically called by the compiler-generated code when a
36 * coroutine function returns a Event.
37 */
38 Event(std::coroutine_handle<promise_type> h);
39
40 /**
41 * @brief Copy constructor
42 * @param other Event to copy
43 *
44 * Creates a new Event that shares ownership of the same
45 * underlying coroutine. This allows multiple schedulers or containers
46 * to reference the same task.
47 */
48 Event(const Event& other);
49
50 /**
51 * @brief Copy assignment operator
52 * @param other Event to copy
53 * @return Reference to this Event
54 *
55 * Assigns this Event to share ownership of the same
56 * underlying coroutine as the other Event.
57 */
58 Event& operator=(const Event& other);
59
60 /**
61 * @brief Move constructor
62 * @param other Event to move from
63 *
64 * Transfers ownership of the coroutine from other to this Event.
65 * After the move, other no longer references any coroutine.
66 */
67 Event(Event&& other) noexcept;
68
69 /**
70 * @brief Move assignment operator
71 * @param other Event to move from
72 * @return Reference to this Event
73 *
74 * Transfers ownership of the coroutine from other to this Event.
75 * After the move, other no longer references any coroutine.
76 */
77 Event& operator=(Event&& other) noexcept;
78
79 /**
80 * @brief Destructor
81 *
82 * Destroys the Event routine and releases its reference to the
83 * underlying coroutine. If this is the last reference, the
84 * coroutine frame is destroyed.
85 */
86 virtual ~Event();
87
88 /**
89 * @brief Get the processing token that determines how this routine should be scheduled
90 * @return The processing token indicating the scheduling domain
91 */
92 [[nodiscard]] virtual ProcessingToken get_processing_token() const;
93
94 /**
95 * @brief Checks if the coroutine is still active
96 * @return True if the coroutine is active, false if it's completed or invalid
97 *
98 * An active coroutine has not yet completed its execution and can
99 * be resumed. Inactive coroutines have either completed or were
100 * never properly initialized.
101 */
102 [[nodiscard]] virtual bool is_active() const;
103
104 void resume();
105
106 [[nodiscard]] bool done() const;
107
108 [[nodiscard]] std::coroutine_handle<promise_type> get_handle() const;
109
110 /**
111 * @brief Get should_terminate flag from promise
112 * @return True if coroutine should be terminated
113 */
114 [[nodiscard]] virtual bool get_should_terminate() const
115 {
116 return m_handle.promise().should_terminate;
117 }
118
119 /**
120 * @brief Set should_terminate flag in promise
121 * @param should_terminate Whether the coroutine should be terminated
122 */
123 virtual void set_should_terminate(bool should_terminate)
124 {
125 m_handle.promise().should_terminate = should_terminate;
126 }
127
128 /**
129 * @brief Updates multiple named parameters in the coroutine's state
130 * @param args Variable number of key-value pairs to update
131 *
132 * Provides a convenient way to update multiple state values at once.
133 * This is useful for configuring a coroutine before or during execution.
134 *
135 * Example:
136 * ```cpp
137 * routine.update_params("duration", 2.0f, "amplitude", 0.8f);
138 * ```
139 */
140 template <typename... Args>
141 inline void update_params(Args... args)
142 {
143 update_params_impl(std::forward<Args>(args)...);
144 }
145
146 /**
147 * @brief Sets a named state value in the coroutine
148 * @param key Name of the state value
149 * @param value Value to store
150 *
151 * Stores a value in the coroutine's state dictionary under the given key.
152 * This allows the coroutine to maintain state between suspensions and
153 * enables external code to influence the coroutine's behavior.
154 */
155 template <typename T>
156 inline void set_state(const std::string& key, T value)
157 {
158 set_state_impl(key, std::move(value));
159 }
160
161 /**
162 * @brief Gets a named state value from the coroutine
163 * @param key Name of the state value to retrieve
164 * @return Pointer to the stored value, or nullptr if not found
165 *
166 * Retrieves a previously stored value from the coroutine's state
167 * dictionary. Returns nullptr if the key doesn't exist or the
168 * stored type doesn't match the requested type.
169 */
170 template <typename T>
171 inline T* get_state(const std::string& key)
172 {
173 return get_state_impl<T>(key);
174 }
175
176protected:
177 virtual void set_state_impl(const std::string& key, std::any value);
178
179 virtual void* get_state_impl_raw(const std::string& key);
180
181 /**
182 * @brief Implementation helper for get_state
183 * @param key Name of the state value to retrieve
184 * @return Pointer to the stored value, or nullptr if not found or type mismatch
185 */
186 template <typename T>
187 T* get_state_impl(const std::string& key)
188 {
189 void* raw_ptr = get_state_impl_raw(key);
190 if (!raw_ptr)
191 return nullptr;
192
193 try {
194 return std::any_cast<T>(static_cast<std::any*>(raw_ptr));
195 } catch (const std::bad_any_cast&) {
196 return nullptr;
197 }
198 }
199
200 /**
201 * brief Implementation helper for update_params
202 */
203 virtual void update_params_impl() { }
204
205 /**
206 * @brief Implementation helper for update_params
207 * @param promise The promise object to update
208 * @param key Name of the state value
209 * @param value Value to store
210 * @param args Remaining key-value pairs to process
211 *
212 * Recursive template function that processes each key-value pair
213 * in the update_params variadic argument list.
214 */
215 template <typename T, typename... Args>
216 void update_params_impl(const std::string& key, T value, Args... args)
217 {
218 set_state(key, std::move(value));
219 if constexpr (sizeof...(args) > 0) {
220 update_params_impl(std::forward<Args>(args)...);
221 }
222 }
223
224private:
225 std::coroutine_handle<promise_type> m_handle;
226};
227
228}
T * get_state_impl(const std::string &key)
Implementation helper for get_state.
Definition Event.hpp:187
void set_state(const std::string &key, T value)
Sets a named state value in the coroutine.
Definition Event.hpp:156
std::coroutine_handle< promise_type > m_handle
Definition Event.hpp:225
virtual void set_should_terminate(bool should_terminate)
Set should_terminate flag in promise.
Definition Event.hpp:123
virtual bool get_should_terminate() const
Get should_terminate flag from promise.
Definition Event.hpp:114
void update_params_impl(const std::string &key, T value, Args... args)
Implementation helper for update_params.
Definition Event.hpp:216
T * get_state(const std::string &key)
Gets a named state value from the coroutine.
Definition Event.hpp:171
void update_params(Args... args)
Updates multiple named parameters in the coroutine's state.
Definition Event.hpp:141
virtual void update_params_impl()
brief Implementation helper for update_params
Definition Event.hpp:203
Coroutine type for event-driven suspension.
Definition Event.hpp:26