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