MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Routine.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Promise.hpp"
4
5namespace MayaFlux::Vruta {
6
7/**
8 * @class Routine
9 * @brief Base class for all coroutine types in the MayaFlux engine
10 *
11 * This abstract base class provides the common interface and functionality
12 * for all types of coroutines, regardless of their processing domain.
13 * It enables polymorphic handling of different routine types while maintaining
14 * type safety through the template-based promise system.
15 */
16class MAYAFLUX_API Routine {
17public:
18 /**
19 * @brief Destructor
20 *
21 * Destroys the Routine and releases its reference to the
22 * underlying coroutine. If this is the last reference, the
23 * coroutine frame is destroyed.
24 */
25 virtual ~Routine() = default;
26
27 /**
28 * @brief Get the processing token that determines how this routine should be scheduled
29 * @return The processing token indicating the scheduling domain
30 */
31 [[nodiscard]] virtual ProcessingToken get_processing_token() const = 0;
32
33 /**
34 * @brief Initializes the coroutine's state for execution
35 * @param current_sample Current sample position in the timeline
36 * @return True if initialization succeeded, false otherwise
37 *
38 * Prepares the coroutine for execution by setting its initial
39 * sample position and other state. This should be called before
40 * the first attempt to resume the coroutine.
41 */
42 virtual bool initialize_state(uint64_t current_context = 0U) = 0;
43
44 /**
45 * @brief Checks if the coroutine is still active
46 * @return True if the coroutine is active, false if it's completed or invalid
47 *
48 * An active coroutine has not yet completed its execution and can
49 * be resumed. Inactive coroutines have either completed or were
50 * never properly initialized.
51 */
52 [[nodiscard]] virtual bool is_active() const = 0;
53
54 /**
55 * @brief Gets the sample position when this routine should next execute
56 * @return Sample position for next execution, or uint64_MAX if inactive
57 *
58 * This method is crucial for sample-accurate scheduling. It returns
59 * the exact sample position when the coroutine should be resumed next.
60 * The scheduler uses this to determine when to call try_resume().
61 */
62 [[nodiscard]] virtual inline uint64_t next_execution() const = 0;
63
64 /**
65 * @brief Attempts to resume the coroutine if it's ready to execute
66 * @param current_sample Current sample position in the timeline
67 * @return True if the coroutine was resumed, false otherwise
68 *
69 * This method checks if the current sample position has reached or
70 * passed the coroutine's next execution time. If so, it resumes
71 * the coroutine, allowing it to execute until its next suspension
72 * point or completion.
73 */
74 virtual bool try_resume(uint64_t current_context) = 0;
75
76 /**
77 * @brief Attempts to resume the coroutine with explicit temporal context
78 * @param current_value Current position in the timeline (samples, frames, cycles, etc.)
79 * @param context The temporal context being processed
80 * @return True if the coroutine was resumed, false otherwise
81 *
82 * This context-aware resume method allows different temporal mechanisms
83 * to coexist within the same processing token. For example, both sample-based
84 * and buffer-cycle-based delays can use SAMPLE_ACCURATE token without
85 * interfering with each other.
86 *
87 * The default implementation delegates to try_resume(uint64_t) for backward
88 * compatibility. Derived classes can override to implement context-specific
89 * resumption logic.
90 */
91 virtual bool try_resume_with_context(uint64_t current_value, DelayContext /*context*/)
92 {
93 return try_resume(current_value);
94 }
95
96 /**
97 * @brief Check if the routine should synchronize with a clock
98 * @return True if the routine requires clock synchronization
99 */
100 [[nodiscard]] virtual bool requires_clock_sync() const = 0;
101
102 /**
103 * @brief Restarts the coroutine from the beginning
104 * @return True if restart succeeded, false otherwise
105 *
106 * Resets the coroutine to its initial state and prepares it for
107 * execution from the beginning. This allows reusing the same
108 * coroutine logic multiple times without creating a new coroutine.
109 */
110 virtual bool restart() = 0;
111
112 /**
113 * @brief Get auto_resume flag from promise
114 * @return True if coroutine should be automatically resumed
115 */
116 [[nodiscard]] virtual bool get_auto_resume() const = 0;
117
118 /**
119 * @brief Set auto_resume flag in promise
120 * @param auto_resume Whether the coroutine should be automatically resumed
121 */
122 virtual void set_auto_resume(bool auto_resume) = 0;
123
124 /**
125 * @brief Get should_terminate flag from promise
126 * @return True if coroutine should be terminated
127 */
128 [[nodiscard]] virtual bool get_should_terminate() const = 0;
129
130 /**
131 * @brief Set should_terminate flag in promise
132 * @param should_terminate Whether the coroutine should be terminated
133 */
134 virtual void set_should_terminate(bool should_terminate) = 0;
135
136 /**
137 * @brief Get sync_to_clock flag from promise
138 * @return True if coroutine should synchronize with clock
139 */
140 [[nodiscard]] virtual bool get_sync_to_clock() const = 0;
141
142 // Domain-specific timing methods (return 0/false for unsupported domains)
143 /**
144 * @brief Get next sample execution time (audio domain)
145 * @return Sample position for next execution, or 0 if not audio domain
146 */
147 [[nodiscard]] virtual uint64_t get_next_sample() const = 0;
148
149 /**
150 * @brief Set next sample execution time (audio domain)
151 * @param next_sample Sample position for next execution
152 */
153 virtual void set_next_sample(uint64_t next_sample) = 0;
154
155 /**
156 * @brief Get next frame execution time (graphics domain)
157 * @return Frame position for next execution, or 0 if not graphics domain
158 */
159 [[nodiscard]] virtual uint64_t get_next_frame() const = 0;
160
161 /**
162 * @brief Set next frame execution time (graphics domain)
163 * @param next_frame Frame position for next execution
164 */
165 virtual void set_next_frame(uint64_t next_frame) = 0;
166
167 /**
168 * @brief Get the active delay context for this routine
169 * @return Current delay context, or NONE if not waiting
170 */
171 [[nodiscard]] virtual DelayContext get_delay_context() const { return DelayContext::NONE; }
172
173 /**
174 * @brief Set the active delay context for this routine
175 * @param context New delay context
176 */
177 virtual void set_delay_context(DelayContext /* Context */) { /* no-op in base */ }
178
179 /**
180 * @brief Updates multiple named parameters in the coroutine's state
181 * @param args Variable number of key-value pairs to update
182 *
183 * Provides a convenient way to update multiple state values at once.
184 * This is useful for configuring a coroutine before or during execution.
185 *
186 * Example:
187 * ```cpp
188 * routine.update_params("duration", 2.0f, "amplitude", 0.8f);
189 * ```
190 */
191 template <typename... Args>
192 inline void update_params(Args... args)
193 {
194 update_params_impl(std::forward<Args>(args)...);
195 }
196
197 /**
198 * @brief Sets a named state value in the coroutine
199 * @param key Name of the state value
200 * @param value Value to store
201 *
202 * Stores a value in the coroutine's state dictionary under the given key.
203 * This allows the coroutine to maintain state between suspensions and
204 * enables external code to influence the coroutine's behavior.
205 */
206 template <typename T>
207 inline void set_state(const std::string& key, T value)
208 {
209 set_state_impl(key, std::move(value));
210 }
211
212 /**
213 * @brief Gets a named state value from the coroutine
214 * @param key Name of the state value to retrieve
215 * @return Pointer to the stored value, or nullptr if not found
216 *
217 * Retrieves a previously stored value from the coroutine's state
218 * dictionary. Returns nullptr if the key doesn't exist or the
219 * stored type doesn't match the requested type.
220 */
221 template <typename T>
222 inline T* get_state(const std::string& key)
223 {
224 return get_state_impl<T>(key);
225 }
226
227protected:
228 virtual void set_state_impl(const std::string& key, std::any value) = 0;
229 virtual void* get_state_impl_raw(const std::string& key) = 0;
230
231 /**
232 * @brief Implementation helper for get_state
233 * @param key Name of the state value to retrieve
234 * @return Pointer to the stored value, or nullptr if not found or type mismatch
235 */
236 template <typename T>
237 T* get_state_impl(const std::string& key)
238 {
239 void* raw_ptr = get_state_impl_raw(key);
240 if (!raw_ptr)
241 return nullptr;
242
243 try {
244 return std::any_cast<T>(static_cast<std::any*>(raw_ptr));
245 } catch (const std::bad_any_cast&) {
246 return nullptr;
247 }
248 }
249
250 /**
251 * brief Implementation helper for update_params
252 */
253 virtual void update_params_impl() { }
254
255 /**
256 * @brief Implementation helper for update_params
257 * @param promise The promise object to update
258 * @param key Name of the state value
259 * @param value Value to store
260 * @param args Remaining key-value pairs to process
261 *
262 * Recursive template function that processes each key-value pair
263 * in the update_params variadic argument list.
264 */
265 template <typename T, typename... Args>
266 void update_params_impl(const std::string& key, T value, Args... args)
267 {
268 set_state(key, std::move(value));
269 if constexpr (sizeof...(args) > 0) {
270 update_params_impl(std::forward<Args>(args)...);
271 }
272 }
273};
274
275/**
276 * @class SoundRoutine
277 * @brief A C++20 coroutine-based audio processing task with sample-accurate timing
278 *
279 * SoundRoutine encapsulates a coroutine that can execute audio processing logic
280 * with sample-accurate timing. It provides a powerful abstraction for writing
281 * time-based audio code that appears sequential but executes asynchronously
282 * in perfect sync with the audio timeline.
283 *
284 * Key features:
285 * - Sample-accurate timing for precise audio scheduling
286 * - State persistence between suspensions and resumptions
287 * - Automatic management of coroutine lifetime
288 * - Ability to restart and reschedule tasks
289 * - Dynamic parameter updates during execution
290 * - Named state storage for flexible data management
291 *
292 * This implementation leverages C++20 coroutines to create a cooperative
293 * multitasking system specifically designed for audio processing. Each routine
294 * can suspend itself at precise sample positions and be resumed exactly when needed,
295 * enabling complex temporal behaviors without blocking the audio thread.
296 *
297 * Example usage:
298 * ```cpp
299 * auto fade_in = [](TaskScheduler& scheduler) -> SoundRoutine {
300 * float gain = 0.0f;
301 * for (int i = 0; i < 100; i++) {
302 * gain += 0.01f;
303 * set_volume(gain);
304 * co_await SampleDelay{441}; // Wait 10ms at 44.1kHz
305 * }
306 * };
307 * ```
308 */
309class MAYAFLUX_API SoundRoutine : public Routine {
310public:
311 /**
312 * @brief Promise type used by this coroutine
313 *
314 * This is the promise type that manages the coroutine state and
315 * provides the co_await, co_yield, and co_return behaviors.
316 */
318
319 /**
320 * @brief Get the processing token that determines how this routine should be scheduled
321 * @return The processing token indicating the scheduling domain
322 */
323 [[nodiscard]] ProcessingToken get_processing_token() const override;
324
325 /**
326 * @brief Constructs a SoundRoutine from a coroutine handle
327 * @param h Handle to the coroutine
328 *
329 * Creates a SoundRoutine that wraps and manages the given coroutine.
330 * This is typically called by the compiler-generated code when a
331 * coroutine function returns a SoundRoutine.
332 */
333 SoundRoutine(std::coroutine_handle<promise_type> h);
334
335 /**
336 * @brief Copy constructor
337 * @param other SoundRoutine to copy
338 *
339 * Creates a new SoundRoutine that shares ownership of the same
340 * underlying coroutine. This allows multiple schedulers or containers
341 * to reference the same task.
342 */
343 SoundRoutine(const SoundRoutine& other);
344
345 /**
346 * @brief Copy assignment operator
347 * @param other SoundRoutine to copy
348 * @return Reference to this SoundRoutine
349 *
350 * Assigns this SoundRoutine to share ownership of the same
351 * underlying coroutine as the other SoundRoutine.
352 */
353 SoundRoutine& operator=(const SoundRoutine& other);
354
355 /**
356 * @brief Move constructor
357 * @param other SoundRoutine to move from
358 *
359 * Transfers ownership of the coroutine from other to this SoundRoutine.
360 * After the move, other no longer references any coroutine.
361 */
362 SoundRoutine(SoundRoutine&& other) noexcept;
363
364 /**
365 * @brief Move assignment operator
366 * @param other SoundRoutine to move from
367 * @return Reference to this SoundRoutine
368 *
369 * Transfers ownership of the coroutine from other to this SoundRoutine.
370 * After the move, other no longer references any coroutine.
371 */
372 SoundRoutine& operator=(SoundRoutine&& other) noexcept;
373
374 ~SoundRoutine() override;
375
376 [[nodiscard]] bool is_active() const override;
377
378 bool initialize_state(uint64_t current_sample = 0U) override;
379
380 bool try_resume(uint64_t current_context) override;
381
382 bool try_resume_with_context(uint64_t current_value, DelayContext context) override;
383
384 [[nodiscard]] DelayContext get_delay_context() const override
385 {
386 return m_handle.promise().active_delay_context;
387 }
388
389 void set_delay_context(DelayContext context) override
390 {
391 m_handle.promise().active_delay_context = context;
392 }
393
394 bool restart() override;
395
396 [[nodiscard]] uint64_t next_execution() const override;
397
398 [[nodiscard]] bool requires_clock_sync() const override;
399
400 [[nodiscard]] bool get_auto_resume() const override
401 {
402 return m_handle.promise().auto_resume;
403 }
404
405 void set_auto_resume(bool auto_resume) override
406 {
407 m_handle.promise().auto_resume = auto_resume;
408 }
409
410 [[nodiscard]] bool get_should_terminate() const override
411 {
412 return m_handle.promise().should_terminate;
413 }
414
415 void set_should_terminate(bool should_terminate) override
416 {
417 m_handle.promise().should_terminate = should_terminate;
418 }
419
420 [[nodiscard]] bool get_sync_to_clock() const override
421 {
422 return m_handle.promise().sync_to_clock;
423 }
424
425 [[nodiscard]] uint64_t get_next_sample() const override
426 {
427 return m_handle.promise().next_sample;
428 }
429
430 void set_next_sample(uint64_t next_sample) override
431 {
432 m_handle.promise().next_sample = next_sample;
433 }
434
435 [[nodiscard]] uint64_t get_next_frame() const override
436 {
437 return m_handle.promise().next_buffer_cycle;
438 }
439
440 void set_next_frame(uint64_t next_cycle) override
441 {
442 m_handle.promise().next_buffer_cycle = next_cycle;
443 }
444
445 // Non-audio domain methods (return defaults for audio routines)
446 // uint64_t get_next_frame() const override { return 0; }
447 // void set_next_frame(uint64_t /*next_frame*/) override { /* no-op for audio */ }
448
449protected:
450 void set_state_impl(const std::string& key, std::any value) override;
451 void* get_state_impl_raw(const std::string& key) override;
452
453private:
454 /**
455 * @brief Handle to the underlying coroutine
456 *
457 * This handle provides access to the coroutine frame, allowing
458 * the SoundRoutine to resume, suspend, and destroy the coroutine.
459 */
460 std::coroutine_handle<promise_type> m_handle;
461};
462
463/**
464 * @class GraphicsRoutine
465 * @brief A C++20 coroutine-based graphics processing task with frame-accurate timing
466 *
467 * GraphicsRoutine encapsulates a coroutine that can execute visual processing logic
468 * with frame-accurate timing. It provides the graphics-domain equivalent to SoundRoutine,
469 * enabling time-based visual code that appears sequential but executes asynchronously
470 * in perfect sync with the frame timeline.
471 *
472 * Key architectural differences from SoundRoutine:
473 * - Timing source: FrameClock (self-driven) vs SampleClock (hardware-driven)
474 * - The routine doesn't care HOW the clock advances, only that it gets tick updates
475 * - GraphicsRoutine synchronized to frame positions, not sample positions
476 * - Works with FrameDelay awaiters instead of SampleDelay
477 *
478 * Key features:
479 * - Frame-accurate timing for precise visual scheduling
480 * - State persistence between suspensions and resumptions
481 * - Automatic management of coroutine lifetime
482 * - Ability to restart and reschedule tasks
483 * - Dynamic parameter updates during execution
484 * - Named state storage for flexible data management
485 *
486 * This implementation leverages C++20 coroutines to create a cooperative
487 * multitasking system specifically designed for visual processing. Each routine
488 * can suspend itself at precise frame positions and be resumed exactly when needed,
489 * enabling complex temporal behaviors for animations, visual effects, and
490 * data-driven visuals without blocking the graphics thread.
491 *
492 * Example usage:
493 * ```cpp
494 * auto fade_animation = [](TaskScheduler& scheduler) -> GraphicsRoutine {
495 * float opacity = 0.0f;
496 * for (int i = 0; i < 60; i++) { // 60 frames at 60fps = 1 second
497 * opacity += 1.0f / 60.0f;
498 * set_shader_opacity(opacity);
499 * co_await FrameDelay{1}; // Wait exactly 1 frame
500 * }
501 * };
502 * ```
503 */
504class MAYAFLUX_API GraphicsRoutine : public Routine {
505public:
506 /**
507 * @brief Promise type used by this coroutine
508 *
509 * This is the promise type that manages the coroutine state and
510 * provides the co_await, co_yield, and co_return behaviors for
511 * frame-based timing.
512 */
514
515 /**
516 * @brief Get the processing token that determines how this routine should be scheduled
517 * @return FRAME_ACCURATE token indicating frame-based scheduling
518 */
519 [[nodiscard]] ProcessingToken get_processing_token() const override;
520
521 /**
522 * @brief Constructs a GraphicsRoutine from a coroutine handle
523 * @param h Handle to the coroutine
524 *
525 * Creates a GraphicsRoutine that wraps and manages the given coroutine.
526 * This is typically called by the compiler-generated code when a
527 * coroutine function returns a GraphicsRoutine.
528 */
529 GraphicsRoutine(std::coroutine_handle<promise_type> h);
530
531 /**
532 * @brief Copy constructor
533 * @param other GraphicsRoutine to copy
534 *
535 * Creates a new GraphicsRoutine that shares ownership of the same
536 * underlying coroutine. This allows multiple schedulers or containers
537 * to reference the same task.
538 */
539 GraphicsRoutine(const GraphicsRoutine& other);
540
541 /**
542 * @brief Copy assignment operator
543 * @param other GraphicsRoutine to copy from
544 * @return Reference to this GraphicsRoutine
545 */
546 GraphicsRoutine& operator=(const GraphicsRoutine& other);
547
548 /**
549 * @brief Move constructor
550 * @param other GraphicsRoutine to move from
551 *
552 * Transfers ownership of the coroutine from other to this GraphicsRoutine.
553 * After the move, other no longer references any coroutine.
554 */
555 GraphicsRoutine(GraphicsRoutine&& other) noexcept;
556
557 /**
558 * @brief Move assignment operator
559 * @param other GraphicsRoutine to move from
560 * @return Reference to this GraphicsRoutine
561 *
562 * Transfers ownership of the coroutine from other to this GraphicsRoutine.
563 * After the move, other no longer references any coroutine.
564 */
565 GraphicsRoutine& operator=(GraphicsRoutine&& other) noexcept;
566
567 ~GraphicsRoutine() override;
568
569 [[nodiscard]] bool is_active() const override;
570
571 bool initialize_state(uint64_t current_frame = 0U) override;
572
573 bool try_resume(uint64_t current_context) override;
574
575 bool try_resume_with_context(uint64_t current_value, DelayContext context) override;
576
577 [[nodiscard]] DelayContext get_delay_context() const override
578 {
579 return m_handle.promise().active_delay_context;
580 }
581
582 void set_delay_context(DelayContext context) override
583 {
584 m_handle.promise().active_delay_context = context;
585 }
586
587 bool restart() override;
588
589 [[nodiscard]] uint64_t next_execution() const override;
590
591 [[nodiscard]] bool requires_clock_sync() const override;
592
593 [[nodiscard]] bool get_auto_resume() const override
594 {
595 return m_handle.promise().auto_resume;
596 }
597
598 void set_auto_resume(bool auto_resume) override
599 {
600 m_handle.promise().auto_resume = auto_resume;
601 }
602
603 [[nodiscard]] bool get_should_terminate() const override
604 {
605 return m_handle.promise().should_terminate;
606 }
607
608 void set_should_terminate(bool should_terminate) override
609 {
610 m_handle.promise().should_terminate = should_terminate;
611 }
612
613 [[nodiscard]] bool get_sync_to_clock() const override
614 {
615 return m_handle.promise().sync_to_clock;
616 }
617
618 [[nodiscard]] uint64_t get_next_frame() const override
619 {
620 return m_handle.promise().next_frame;
621 }
622
623 void set_next_frame(uint64_t next_frame) override
624 {
625 m_handle.promise().next_frame = next_frame;
626 }
627
628 // Non-graphics domain methods (return defaults for graphics routines)
629 [[nodiscard]] uint64_t get_next_sample() const override { return 0; }
630 void set_next_sample(uint64_t /*next_sample*/) override { /* no-op for graphics */ }
631
632protected:
633 void set_state_impl(const std::string& key, std::any value) override;
634 void* get_state_impl_raw(const std::string& key) override;
635
636private:
637 /**
638 * @brief Handle to the underlying coroutine
639 *
640 * This handle provides access to the coroutine frame, allowing
641 * the GraphicsRoutine to resume, suspend, and destroy the coroutine.
642 */
643 std::coroutine_handle<promise_type> m_handle;
644};
645
646/**
647 * @class ComplexRoutine
648 * @brief Multi-domain coroutine that can handle multiple processing rates
649 *
650 * ComplexRoutine is designed for coroutines that need to operate across
651 * multiple processing domains (audio + visual, for example). It automatically
652 * selects the fastest processing rate and manages cross-domain synchronization.
653 */
654class ComplexRoutine : public Routine {
655public:
656 [[nodiscard]] ProcessingToken get_processing_token() const override
657 {
659 }
660
661 [[nodiscard]] bool requires_clock_sync() const override
662 {
663 return true; // Complex routines need clock sync for coordination
664 }
665
666 // Promise state access implementations (TODO: implement when complex promise is ready)
667 [[nodiscard]] bool get_auto_resume() const override { return true; }
668 void set_auto_resume(bool /*auto_resume*/) override { /* TODO */ }
669 [[nodiscard]] bool get_should_terminate() const override { return false; }
670 void set_should_terminate(bool /*should_terminate*/) override { /* TODO */ }
671 [[nodiscard]] bool get_sync_to_clock() const override { return true; }
672
673 // Multi-domain timing implementations (supports both audio and graphics)
674 [[nodiscard]] uint64_t get_next_sample() const override { return 0; }
675 void set_next_sample(uint64_t /*next_sample*/) override { /* TODO */ }
676 [[nodiscard]] uint64_t get_next_frame() const override { return 0; }
677 void set_next_frame(uint64_t /*next_frame*/) override { /* TODO */ }
678
679 // TODO: Implement when multi-domain scheduling is ready
680 [[nodiscard]] bool is_active() const override { return false; }
681 bool initialize_state(uint64_t /*current_context*/ = 0U) override { return false; }
682 bool try_resume(uint64_t /*current_context*/) override { return false; }
683 bool restart() override { return false; }
684 [[nodiscard]] uint64_t next_execution() const override { return 0; }
685
686protected:
687 void set_state_impl(const std::string& /*key*/, std::any /*value*/) override { }
688 void* get_state_impl_raw(const std::string& /*key*/) override { return nullptr; }
689
690private:
692 std::vector<ProcessingToken> m_secondary_tokens;
693};
694}
bool restart() override
Restarts the coroutine from the beginning.
Definition Routine.hpp:683
bool initialize_state(uint64_t=0U) override
Initializes the coroutine's state for execution.
Definition Routine.hpp:681
uint64_t get_next_frame() const override
Get next frame execution time (graphics domain)
Definition Routine.hpp:676
std::vector< ProcessingToken > m_secondary_tokens
Definition Routine.hpp:692
ProcessingToken m_primary_token
Definition Routine.hpp:691
void set_state_impl(const std::string &, std::any) override
Definition Routine.hpp:687
void set_auto_resume(bool) override
Set auto_resume flag in promise.
Definition Routine.hpp:668
bool get_auto_resume() const override
Get auto_resume flag from promise.
Definition Routine.hpp:667
void set_next_frame(uint64_t) override
Set next frame execution time (graphics domain)
Definition Routine.hpp:677
void set_next_sample(uint64_t) override
Set next sample execution time (audio domain)
Definition Routine.hpp:675
bool is_active() const override
Checks if the coroutine is still active.
Definition Routine.hpp:680
uint64_t next_execution() const override
Gets the sample position when this routine should next execute.
Definition Routine.hpp:684
void set_should_terminate(bool) override
Set should_terminate flag in promise.
Definition Routine.hpp:670
bool get_sync_to_clock() const override
Get sync_to_clock flag from promise.
Definition Routine.hpp:671
bool requires_clock_sync() const override
Check if the routine should synchronize with a clock.
Definition Routine.hpp:661
bool try_resume(uint64_t) override
Attempts to resume the coroutine if it's ready to execute.
Definition Routine.hpp:682
bool get_should_terminate() const override
Get should_terminate flag from promise.
Definition Routine.hpp:669
uint64_t get_next_sample() const override
Get next sample execution time (audio domain)
Definition Routine.hpp:674
ProcessingToken get_processing_token() const override
Get the processing token that determines how this routine should be scheduled.
Definition Routine.hpp:656
void * get_state_impl_raw(const std::string &) override
Definition Routine.hpp:688
Multi-domain coroutine that can handle multiple processing rates.
Definition Routine.hpp:654
uint64_t get_next_sample() const override
Get next sample execution time (audio domain)
Definition Routine.hpp:629
void set_auto_resume(bool auto_resume) override
Set auto_resume flag in promise.
Definition Routine.hpp:598
void set_should_terminate(bool should_terminate) override
Set should_terminate flag in promise.
Definition Routine.hpp:608
bool get_should_terminate() const override
Get should_terminate flag from promise.
Definition Routine.hpp:603
void set_next_frame(uint64_t next_frame) override
Set next frame execution time (graphics domain)
Definition Routine.hpp:623
void set_next_sample(uint64_t) override
Set next sample execution time (audio domain)
Definition Routine.hpp:630
bool get_auto_resume() const override
Get auto_resume flag from promise.
Definition Routine.hpp:593
std::coroutine_handle< promise_type > m_handle
Handle to the underlying coroutine.
Definition Routine.hpp:643
uint64_t get_next_frame() const override
Get next frame execution time (graphics domain)
Definition Routine.hpp:618
DelayContext get_delay_context() const override
Get the active delay context for this routine.
Definition Routine.hpp:577
void set_delay_context(DelayContext context) override
Set the active delay context for this routine.
Definition Routine.hpp:582
bool get_sync_to_clock() const override
Get sync_to_clock flag from promise.
Definition Routine.hpp:613
A C++20 coroutine-based graphics processing task with frame-accurate timing.
Definition Routine.hpp:504
void set_state(const std::string &key, T value)
Sets a named state value in the coroutine.
Definition Routine.hpp:207
virtual void set_next_frame(uint64_t next_frame)=0
Set next frame execution time (graphics domain)
virtual uint64_t get_next_sample() const =0
Get next sample execution time (audio domain)
virtual bool try_resume_with_context(uint64_t current_value, DelayContext)
Attempts to resume the coroutine with explicit temporal context.
Definition Routine.hpp:91
virtual bool restart()=0
Restarts the coroutine from the beginning.
virtual void set_delay_context(DelayContext)
Set the active delay context for this routine.
Definition Routine.hpp:177
void update_params(Args... args)
Updates multiple named parameters in the coroutine's state.
Definition Routine.hpp:192
virtual bool is_active() const =0
Checks if the coroutine is still active.
virtual ProcessingToken get_processing_token() const =0
Get the processing token that determines how this routine should be scheduled.
virtual void set_state_impl(const std::string &key, std::any value)=0
virtual ~Routine()=default
Destructor.
virtual bool get_sync_to_clock() const =0
Get sync_to_clock flag from promise.
virtual uint64_t next_execution() const =0
Gets the sample position when this routine should next execute.
virtual void set_should_terminate(bool should_terminate)=0
Set should_terminate flag in promise.
virtual bool requires_clock_sync() const =0
Check if the routine should synchronize with a clock.
virtual void set_next_sample(uint64_t next_sample)=0
Set next sample execution time (audio domain)
virtual void set_auto_resume(bool auto_resume)=0
Set auto_resume flag in promise.
virtual void update_params_impl()
brief Implementation helper for update_params
Definition Routine.hpp:253
virtual bool get_should_terminate() const =0
Get should_terminate flag from promise.
virtual void * get_state_impl_raw(const std::string &key)=0
virtual uint64_t get_next_frame() const =0
Get next frame execution time (graphics domain)
T * get_state(const std::string &key)
Gets a named state value from the coroutine.
Definition Routine.hpp:222
void update_params_impl(const std::string &key, T value, Args... args)
Implementation helper for update_params.
Definition Routine.hpp:266
virtual DelayContext get_delay_context() const
Get the active delay context for this routine.
Definition Routine.hpp:171
virtual bool initialize_state(uint64_t current_context=0U)=0
Initializes the coroutine's state for execution.
virtual bool try_resume(uint64_t current_context)=0
Attempts to resume the coroutine if it's ready to execute.
T * get_state_impl(const std::string &key)
Implementation helper for get_state.
Definition Routine.hpp:237
virtual bool get_auto_resume() const =0
Get auto_resume flag from promise.
Base class for all coroutine types in the MayaFlux engine.
Definition Routine.hpp:16
std::coroutine_handle< promise_type > m_handle
Handle to the underlying coroutine.
Definition Routine.hpp:460
bool get_sync_to_clock() const override
Get sync_to_clock flag from promise.
Definition Routine.hpp:420
void set_auto_resume(bool auto_resume) override
Set auto_resume flag in promise.
Definition Routine.hpp:405
uint64_t get_next_sample() const override
Get next sample execution time (audio domain)
Definition Routine.hpp:425
bool get_auto_resume() const override
Get auto_resume flag from promise.
Definition Routine.hpp:400
uint64_t get_next_frame() const override
Get next frame execution time (graphics domain)
Definition Routine.hpp:435
void set_next_sample(uint64_t next_sample) override
Set next sample execution time (audio domain)
Definition Routine.hpp:430
bool get_should_terminate() const override
Get should_terminate flag from promise.
Definition Routine.hpp:410
void set_next_frame(uint64_t next_cycle) override
Set next frame execution time (graphics domain)
Definition Routine.hpp:440
void set_delay_context(DelayContext context) override
Set the active delay context for this routine.
Definition Routine.hpp:389
DelayContext get_delay_context() const override
Get the active delay context for this routine.
Definition Routine.hpp:384
void set_should_terminate(bool should_terminate) override
Set should_terminate flag in promise.
Definition Routine.hpp:415
A C++20 coroutine-based audio processing task with sample-accurate timing.
Definition Routine.hpp:309
@ MULTI_RATE
Coroutine can handle multiple sample rates. Picks the frame-accurate processing token by default.
@ SAMPLE_ACCURATE
Coroutine is sample-accurate.
DelayContext
Discriminator for different temporal delay mechanisms.
Coroutine promise type for audio processing tasks with sample-accurate timing.
Definition Promise.hpp:196
Coroutine promise type for graphics processing tasks with frame-accurate timing.
Definition Promise.hpp:259