MayaFlux 1.0.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().set_should_terminate(should_terminate);
126 }
127
128 /**
129 * @brief Register a callback fired once when the handler ends
130 * @param callback Function to invoke on completion
131 *
132 * Fires on the first of: the handler coroutine reaching its end, or a termination
133 * request (cancel, removal, replacement by name, terminate-all). It is once-only per
134 * handler, not per event. It runs on the thread that ends the handler, which for natural
135 * completion is the producer thread that resumed it (possibly the audio thread).
136 * Register before adding the event; a callback registered after completion runs immediately.
137 *
138 * The stock handlers (key, mouse, network and broadcast listeners) loop until cancelled, so for
139 * them this only reports removal. A cancelled handler whose Event is still held by the caller stays
140 * parked on its source and may run its per-event callback once more on the next matching input.
141 */
142 void on_complete(std::function<void()> callback)
143 {
144 m_handle.promise().on_complete(std::move(callback));
145 }
146
147 /**
148 * @brief Updates multiple named parameters in the coroutine's state
149 * @param args Variable number of key-value pairs to update
150 *
151 * Provides a convenient way to update multiple state values at once.
152 * This is useful for configuring a coroutine before or during execution.
153 *
154 * Example:
155 * ```cpp
156 * routine.update_params("duration", 2.0f, "amplitude", 0.8f);
157 * ```
158 */
159 template <typename... Args>
160 inline void update_params(Args... args)
161 {
162 update_params_impl(std::forward<Args>(args)...);
163 }
164
165 /**
166 * @brief Sets a named state value in the coroutine
167 * @param key Name of the state value
168 * @param value Value to store
169 *
170 * Stores a value in the coroutine's state dictionary under the given key.
171 * This allows the coroutine to maintain state between suspensions and
172 * enables external code to influence the coroutine's behavior.
173 */
174 template <typename T>
175 inline void set_state(const std::string& key, T value)
176 {
177 set_state_impl(key, std::move(value));
178 }
179
180 /**
181 * @brief Gets a named state value from the coroutine
182 * @param key Name of the state value to retrieve
183 * @return Pointer to the stored value, or nullptr if not found
184 *
185 * Retrieves a previously stored value from the coroutine's state
186 * dictionary. Returns nullptr if the key doesn't exist or the
187 * stored type doesn't match the requested type.
188 */
189 template <typename T>
190 inline T* get_state(const std::string& key)
191 {
192 return get_state_impl<T>(key);
193 }
194
195protected:
196 virtual void set_state_impl(const std::string& key, std::any value);
197
198 virtual void* get_state_impl_raw(const std::string& key);
199
200 /**
201 * @brief Implementation helper for get_state
202 * @param key Name of the state value to retrieve
203 * @return Pointer to the stored value, or nullptr if not found or type mismatch
204 */
205 template <typename T>
206 T* get_state_impl(const std::string& key)
207 {
208 void* raw_ptr = get_state_impl_raw(key);
209 if (!raw_ptr)
210 return nullptr;
211
212 try {
213 return std::any_cast<T>(static_cast<std::any*>(raw_ptr));
214 } catch (const std::bad_any_cast&) {
215 return nullptr;
216 }
217 }
218
219 /**
220 * brief Implementation helper for update_params
221 */
222 virtual void update_params_impl() { }
223
224 /**
225 * @brief Implementation helper for update_params
226 * @param promise The promise object to update
227 * @param key Name of the state value
228 * @param value Value to store
229 * @param args Remaining key-value pairs to process
230 *
231 * Recursive template function that processes each key-value pair
232 * in the update_params variadic argument list.
233 */
234 template <typename T, typename... Args>
235 void update_params_impl(const std::string& key, T value, Args... args)
236 {
237 set_state(key, std::move(value));
238 if constexpr (sizeof...(args) > 0) {
239 update_params_impl(std::forward<Args>(args)...);
240 }
241 }
242
243private:
244 std::coroutine_handle<promise_type> m_handle;
245};
246
247}
uint32_t h
Definition InkPress.cpp:29
bool done
Definition Picker.cpp:24
PickCallback callback
Definition Picker.cpp:22
glm::vec3 value
T * get_state_impl(const std::string &key)
Implementation helper for get_state.
Definition Event.hpp:206
void set_state(const std::string &key, T value)
Sets a named state value in the coroutine.
Definition Event.hpp:175
std::coroutine_handle< promise_type > m_handle
Definition Event.hpp:244
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 on_complete(std::function< void()> callback)
Register a callback fired once when the handler ends.
Definition Event.hpp:142
void update_params_impl(const std::string &key, T value, Args... args)
Implementation helper for update_params.
Definition Event.hpp:235
T * get_state(const std::string &key)
Gets a named state value from the coroutine.
Definition Event.hpp:190
void update_params(Args... args)
Updates multiple named parameters in the coroutine's state.
Definition Event.hpp:160
virtual void update_params_impl()
brief Implementation helper for update_params
Definition Event.hpp:222
Coroutine type for event-driven suspension.
Definition Event.hpp:26