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