MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Timers.hpp
Go to the documentation of this file.
1#pragma once
2
4#include "Tasks.hpp"
5
6namespace MayaFlux::Nodes {
7class Node;
8class NodeGraphManager;
9namespace Network {
10 class NodeNetwork;
11}
12}
13
14namespace MayaFlux::Buffers {
15class Buffer;
16class BufferManager;
17}
18
19namespace MayaFlux::Kriya {
20
21/**
22 * @class Timer
23 * @brief High-level utility for scheduling one-shot timed callbacks
24 *
25 * The Timer class provides a convenient way to schedule a function to execute
26 * after a specified delay. It wraps the lower-level computational routine system in a
27 * simple interface that's easier to use for common timing scenarios.
28 *
29 * Unlike traditional timers which can drift due to system load, Timer uses
30 * the engine's sample-accurate clock to ensure precise, deterministic timing
31 * that's perfectly synchronized with the processing pipeline.
32 *
33 * Example usage:
34 * ```cpp
35 * // Create a timer
36 * Timer timer(*scheduler);
37 *
38 * // Schedule a callback to execute after 2 seconds
39 * timer.schedule(2.0, []() {
40 * std::cout << "Two seconds have passed!" << std::endl;
41 * });
42 * ```
43 *
44 * Only one callback can be scheduled at a time; scheduling a new callback
45 * cancels any previously scheduled callback.
46 */
47class MAYAFLUX_API Timer {
48public:
49 /**
50 * @brief Constructs a Timer with the specified scheduler
51 * @param scheduler The TaskScheduler that will manage this timer
52 *
53 * Creates a new Timer that will use the provided scheduler for
54 * timing operations. The scheduler provides the sample clock and
55 * task management infrastructure needed for precise timing.
56 */
57 Timer(Vruta::TaskScheduler& scheduler);
58 ~Timer() = default;
59
60 /**
61 * @brief Schedules a callback to execute after a delay
62 * @param delay_seconds Time to wait before executing the callback (in seconds)
63 * @param callback Function to execute after the delay
64 *
65 * This method schedules the provided callback to execute after exactly
66 * the specified delay. If a callback is already scheduled, it is cancelled
67 * and replaced with the new one.
68 *
69 * The timing is sample-accurate, ensuring that the callback executes at
70 * precisely the right moment in the processing timeline.
71 */
72 void schedule(double delay_seconds, std::function<void()> callback);
73
74 /**
75 * @brief Cancels any scheduled callback
76 *
77 * This method cancels any currently scheduled callback, preventing it
78 * from executing. If no callback is scheduled, this method has no effect.
79 */
80 void cancel();
81
82 /**
83 * @brief Checks if a callback is currently scheduled
84 * @return True if a callback is scheduled, false otherwise
85 *
86 * This method returns true if the timer has an active callback scheduled
87 * to execute in the future, and false otherwise.
88 */
89 [[nodiscard]] inline bool is_active() const { return m_active; }
90
91private:
92 /**
93 * @brief Reference to the scheduler that manages this timer
94 *
95 * The scheduler provides the timing infrastructure needed to
96 * execute callbacks at precise sample positions.
97 */
99
100 /**
101 * @brief The underlying computational routine that implements the timer
102 *
103 * This coroutine handles the actual timing and callback execution.
104 * It's created when schedule() is called and destroyed when the
105 * callback executes or cancel() is called.
106 */
107 std::shared_ptr<Vruta::SoundRoutine> m_routine;
108
109 /**
110 * @brief Flag indicating whether a callback is currently scheduled
111 *
112 * This flag is set to true when schedule() is called and reset to
113 * false when the callback executes or cancel() is called.
114 */
116
117 /**
118 * @brief The callback function to execute when the timer fires
119 *
120 * This function is stored when schedule() is called and executed
121 * when the timer fires. It's cleared when cancel() is called.
122 */
123 std::function<void()> m_callback;
124};
125
126/**
127 * @class TimedAction
128 * @brief Utility for executing actions with a start and end function over a duration
129 *
130 * The TimedAction class provides a way to execute a pair of functions with a
131 * specified time interval between them. This is useful for operations that need
132 * to start and then automatically stop after a duration, such as activating a process,
133 * applying a transformation, or implementing any time-bounded state change.
134 *
135 * Example usage:
136 * ```cpp
137 * // Create a timed action
138 * TimedAction action(*scheduler);
139 *
140 * // Execute an action that lasts for 3 seconds
141 * action.execute(
142 * []() { std::cout << "Starting action" << std::endl; },
143 * []() { std::cout << "Ending action" << std::endl; },
144 * 3.0
145 * );
146 * ```
147 *
148 * Only one action can be active at a time; executing a new action cancels
149 * any previously active action.
150 */
151class MAYAFLUX_API TimedAction {
152public:
153 /**
154 * @brief Constructs a TimedAction with the specified scheduler
155 * @param scheduler The TaskScheduler that will manage this action
156 *
157 * Creates a new TimedAction that will use the provided scheduler for
158 * timing operations. The scheduler provides the sample clock and
159 * task management infrastructure needed for precise timing.
160 */
162 ~TimedAction() = default;
163
164 /**
165 * @brief Executes a pair of functions with a time interval between them
166 * @param start_func Function to execute immediately
167 * @param end_func Function to execute after the duration
168 * @param duration_seconds Time between start_func and end_func (in seconds)
169 *
170 * This method executes start_func immediately, then schedules end_func
171 * to execute after the specified duration. This creates a timed action
172 * that starts now and automatically ends after the duration.
173 *
174 * If an action is already in progress, it is cancelled before starting
175 * the new one.
176 */
177 void execute(const std::function<void()>& start_func, const std::function<void()>& end_func, double duration_seconds);
178
179 /**
180 * @brief Cancels any active action
181 *
182 * This method cancels any currently active action, preventing the end
183 * function from executing. If no action is active, this method has no effect.
184 */
185 void cancel();
186
187 /**
188 * @brief Checks if an action is currently in progress
189 * @return True if an action is in progress, false otherwise
190 *
191 * This method returns true if an action has been started but not yet
192 * completed or cancelled, and false otherwise.
193 */
194 [[nodiscard]] bool is_pending() const;
195
196private:
197 /**
198 * @brief Reference to the scheduler that manages this action
199 *
200 * The scheduler provides the timing infrastructure needed to
201 * execute the end function at the right time.
202 */
204
205 /**
206 * @brief The timer used to schedule the end function
207 *
208 * This timer is used to execute the end function after the
209 * specified duration has elapsed.
210 */
212};
213
214/**
215 * @class TemporalActivation
216 * @brief Specialized timer for controlling computational nodes, buffers, and networks
217 *
218 * The TemporalActivation class provides a high-level interface for activating
219 * nodes, buffers, or entire networks for a specified duration. It manages the
220 * lifecycle of the activated entity, ensuring that it is properly connected to
221 * the processing graph when activated and cleanly disconnected when the timer expires.
222 *
223 * Usage example:
224 * ```cpp
225 * // Create a temporal activation
226 * TemporalActivation activation(*scheduler, node_graph_manager, buffer_manager);
227 *
228 * // Activate a node for 5 seconds on channels 0 and 1
229 * activation.activate_node(my_node, my_token, 5.0, {0, 1});
230 * ```
231 */
232class MAYAFLUX_API TemporalActivation {
233public:
234 /**
235 * @brief Constructs a TemporalActivation with the specified scheduler and manager
236 * @param scheduler The TaskScheduler that will manage this timer
237 * @param graph_manager The NodeGraphManager that will manage the processing nodes
238 * @param buffer_manager The BufferManager that will manage any buffers needed for processing
239 *
240 * Creates a new NodeTimer that will use the provided scheduler and
241 * graph manager for timing and node management operations.
242 */
244 Vruta::TaskScheduler& scheduler,
245 Nodes::NodeGraphManager& graph_manager,
246 Buffers::BufferManager& buffer_manager);
247
249
250 /**
251 * @brief Activates a node for a specified duration
252 * @param node The node to activate
253 * @param token The processing token associated with the node
254 * @param duration_seconds The duration to keep the node active (in seconds)
255 * @param channels Optional list of output channels to connect the node to (default is all channels)
256 *
257 * This method activates the specified node by connecting it to the output channels or graphics sync,
258 * and starts a timer for the specified duration. When the timer expires, the node is automatically
259 * disconnected from the output channels, effectively deactivating it.
260 *
261 * If another node, network, or buffer is already active, it will be cancelled before activating the new one.
262 */
263 void activate_node(const std::shared_ptr<Nodes::Node>& node,
264 double duration_seconds,
265 Nodes::ProcessingToken token = Nodes::ProcessingToken::AUDIO_RATE,
266 const std::vector<uint32_t>& channels = {});
267
268 /**
269 * @brief Activates a node network for a specified duration
270 * @param network The node network to activate
271 * @param token The processing token associated with the network
272 * @param duration_seconds The duration to keep the network active (in seconds)
273 * @param channels Optional list of output channels to connect the network to (default is all channels)
274 *
275 * This method activates the specified node network by connecting it to the output channels or graphics sync,
276 * and starts a timer for the specified duration. When the timer expires, the network is automatically
277 * disconnected from the output channels, effectively deactivating it.
278 *
279 * If another node, network, or buffer is already active, it will be cancelled before activating the new one.
280 */
281 void activate_network(const std::shared_ptr<Nodes::Network::NodeNetwork>& network,
282 double duration_seconds,
283 Nodes::ProcessingToken token = Nodes::ProcessingToken::AUDIO_RATE,
284 const std::vector<uint32_t>& channels = {});
285
286 /**
287 * @brief Activates a buffer for a specified duration
288 * @param buffer The buffer to activate
289 * @param token The processing token associated with the buffer
290 * @param duration_seconds The duration to keep the buffer active (in seconds)
291 * @param channel Optional output channel to connect the buffer to (default is 0)
292 * This method activates the specified buffer by connecting it to the output channel,
293 * and starts a timer for the specified duration. When the timer expires, the buffer is automatically
294 * disconnected from the output channel, effectively deactivating it.
295 *
296 * If another node, network, or buffer is already active, it will be cancelled before activating the new one.
297 */
298 void activate_buffer(const std::shared_ptr<Buffers::Buffer>& buffer,
299 double duration_seconds,
300 Buffers::ProcessingToken token = Buffers::ProcessingToken::AUDIO_BACKEND,
301 uint32_t channel = 0);
302
303 /**
304 * @brief Cancels any currently active node
305 *
306 * This method deactivates any currently active node, nodenetowrk or buffer, disconnecting it from
307 * the output channel. If no node is active, this method has no effect.
308 */
309 void cancel();
310
311 /**
312 * @brief Checks if a node is currently active
313 * @return True if a node is active, false otherwise
314 *
315 * This method returns true if the timer has an active entity that's
316 * currently processing, and false otherwise.
317 */
318 [[nodiscard]] inline bool is_active() const { return m_timer.is_active(); }
319
320private:
321 /**
322 * @brief Reference to the scheduler that manages this timer
323 *
324 * The scheduler provides the timing infrastructure needed for
325 * precise control of entity activation durations.
326 */
328
329 /**
330 * @brief Cleans up the current operation, disconnecting the entity and resetting state
331 *
332 * This method is called when the timer completes its specified duration.
333 * It disconnects the currently active node/nodenetwork/buffer from the
334 * output channels or graphics syc, or active and
335 * resets internal state to allow new operations to be started.
336 */
337 void cleanup_current_operation();
338
339 /**
340 * @brief Reference to the graph manager that manages processing nodes
341 *
342 * The graph manager provides the infrastructure for connecting
343 * and disconnecting nodes from the processing graph.
344 */
346
347 /**
348 * @brief Reference to the buffer manager that manages processing buffers
349 *
350 * The buffer manager provides the infrastructure for managing any buffers
351 * needed for processing nodes during their active duration.
352 */
354
355 /**
356 * @brief The timer used to schedule processing duration
357 *
358 * This timer is used to disconnect the entity after the
359 * specified duration has elapsed.
360 */
362
363 /**
364 * @brief The currently active node being played
365 *
366 * This pointer holds the node that is currently being played.
367 * It is set when play_for() or play_with_processing() is called
368 * and reset when the node finishes playing or is cancelled.
369 */
370 std::shared_ptr<Nodes::Node> m_current_node;
371
372 /**
373 * @brief The currently active network being played
374 *
375 * This pointer holds the network that is currently being played.
376 * It is set when play_for() or play_with_processing() is called
377 * and reset when the network finishes playing or is cancelled.
378 */
379 std::shared_ptr<Nodes::Network::NodeNetwork> m_current_network;
380
381 /**
382 * @brief The currently active buffer being played
383 *
384 * This pointer holds the buffer that is currently being played.
385 * It is set when play_for() or play_with_processing() is called
386 * and reset when the buffer finishes playing or is cancelled.
387 */
388 std::shared_ptr<Buffers::Buffer> m_current_buffer;
389
390 /**
391 * @brief The processing token associated with the currently active node or buffer
392 *
393 * This token is used to identify the processing context for the active node or buffer.
394 * It is set when play_for() or play_with_processing() is called and reset when the
395 * node or buffer finishes playing or is cancelled.
396 */
398
399 /**
400 * @brief The processing token associated with the currently active buffer
401 *
402 * This token is used to identify the processing context for the active buffer.
403 * It is set when play_for() or play_with_processing() is called and reset when the
404 * buffer finishes playing or is cancelled.
405 */
407
408 /**
409 * @brief The output channels the current node is connected to
410 *
411 * This vector stores the output channel numbers that the current
412 * node is connected to. It is set when play_for() or play_with_processing()
413 * is called and reset when the node finishes playing or is cancelled.
414 */
415 std::vector<uint32_t> m_channels;
416
417 enum class ActiveType : uint8_t { NONE,
418 NODE,
419 BUFFER,
420 NETWORK };
421
422 ActiveType m_active_type = ActiveType::NONE;
423};
424
425}
Token-based multimodal buffer management system for unified data stream processing.
Buffers::ProcessingToken m_buffer_token
The processing token associated with the currently active buffer.
Definition Timers.hpp:406
std::vector< uint32_t > m_channels
The output channels the current node is connected to.
Definition Timers.hpp:415
Nodes::ProcessingToken m_node_token
The processing token associated with the currently active node or buffer.
Definition Timers.hpp:397
std::shared_ptr< Buffers::Buffer > m_current_buffer
The currently active buffer being played.
Definition Timers.hpp:388
std::shared_ptr< Nodes::Network::NodeNetwork > m_current_network
The currently active network being played.
Definition Timers.hpp:379
bool is_active() const
Checks if a node is currently active.
Definition Timers.hpp:318
Nodes::NodeGraphManager & m_node_graph_manager
Reference to the graph manager that manages processing nodes.
Definition Timers.hpp:345
std::shared_ptr< Nodes::Node > m_current_node
The currently active node being played.
Definition Timers.hpp:370
Buffers::BufferManager & m_buffer_manager
Reference to the buffer manager that manages processing buffers.
Definition Timers.hpp:353
Timer m_timer
The timer used to schedule processing duration.
Definition Timers.hpp:361
Vruta::TaskScheduler & m_scheduler
Reference to the scheduler that manages this timer.
Definition Timers.hpp:327
Specialized timer for controlling computational nodes, buffers, and networks.
Definition Timers.hpp:232
Vruta::TaskScheduler & m_Scheduler
Reference to the scheduler that manages this action.
Definition Timers.hpp:203
Timer m_timer
The timer used to schedule the end function.
Definition Timers.hpp:211
Utility for executing actions with a start and end function over a duration.
Definition Timers.hpp:151
bool m_active
Flag indicating whether a callback is currently scheduled.
Definition Timers.hpp:115
bool is_active() const
Checks if a callback is currently scheduled.
Definition Timers.hpp:89
std::function< void()> m_callback
The callback function to execute when the timer fires.
Definition Timers.hpp:123
Vruta::TaskScheduler & m_Scheduler
Reference to the scheduler that manages this timer.
Definition Timers.hpp:98
std::shared_ptr< Vruta::SoundRoutine > m_routine
The underlying computational routine that implements the timer.
Definition Timers.hpp:107
High-level utility for scheduling one-shot timed callbacks.
Definition Timers.hpp:47
Central manager for the computational processing node graph.
Token-based multimodal task scheduling system for unified coroutine processing.
Definition Scheduler.hpp:51
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
ProcessingToken
Enumerates the different processing domains for nodes.
Contains the node-based computational processing system components.
Definition Chronie.hpp:11