MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Chain.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace MayaFlux::Vruta {
6class TaskScheduler;
7class Routine;
8}
9
10namespace MayaFlux::Kriya {
11
12/**
13 * @class EventChain
14 * @brief A sequential chain of timed events with precise temporal control
15 *
16 * The EventChain class provides a way to schedule a sequence of events to occur
17 * at specific time intervals. It's designed for creating temporal sequences of
18 * actions with sample-accurate timing, which is essential for deterministic computational flows.
19 *
20 * This approach is inspired by reactive programming and temporal logic systems
21 * where precise sequencing of operations is critical. It allows for creating complex
22 * temporal behaviors with a simple, declarative API.
23 *
24 * Example usage:
25 * ```cpp
26 * // Create an event chain
27 * EventChain chain(*scheduler);
28 *
29 * // Add events with specific delays
30 * chain.then([]() { process_initial_state(); }) // Immediate
31 * .then([]() { transform_data(); }, 0.5) // After 0.5 seconds
32 * .then([]() { apply_filter(); }, 0.25) // After another 0.25 seconds
33 * .then([]() { finalize_output(); }, 0.25); // After another 0.25 seconds
34 *
35 * // Start the chain
36 * chain.start();
37 * ```
38 *
39 * The EventChain is particularly useful for creating precisely timed computational sequences,
40 * state transitions, or any series of time-based events that need to occur in a specific
41 * order with deterministic timing.
42 */
43class MAYAFLUX_API EventChain {
44public:
45 /**
46 * @brief Constructs an EventChain with an explicit scheduler
47 * @param scheduler The TaskScheduler to use for timing
48 * @param name Optional name for the event chain (useful for debugging)
49 * @param token Processing token to determine which scheduler rate to use
50 *
51 * Creates a new EventChain that will use the provided scheduler for timing
52 * operations. This allows for more control over which scheduler is used,
53 * which is useful in contexts where multiple processing engines might exist.
54 */
55 EventChain(Vruta::TaskScheduler& scheduler, std::string name = "", Vruta::ProcessingToken token = Vruta::ProcessingToken::SAMPLE_ACCURATE);
56
57 /**
58 * @brief Adds an event to the chain with a specified delay
59 * @param action Function to execute when the event occurs
60 * @param delay_seconds Time to wait before executing this event (in seconds)
61 * @return Reference to this EventChain for method chaining
62 *
63 * This method adds an event to the chain, to be executed after the specified
64 * delay from the previous event. The first event's delay is measured from
65 * when start() is called.
66 *
67 * The method returns a reference to the EventChain itself, allowing for a
68 * fluent, declarative API style.
69 */
70 EventChain& then(std::function<void()> action, double delay_seconds = 0.F);
71
72 /**
73 * @brief Repeat the last event N times
74 * @param count Number of times to repeat
75 * @return Reference to this EventChain for method chaining
76 */
77 EventChain& repeat(size_t count);
78
79 /**
80 * @brief Repeat entire chain N times
81 * @param count Number of times to repeat the entire sequence
82 * @return Reference to this EventChain for method chaining
83 */
84 EventChain& times(size_t count);
85
86 /**
87 * @brief Add a wait/delay without an action
88 * @param delay_seconds Time to wait in seconds
89 * @return Reference to this EventChain for method chaining
90 */
91 EventChain& wait(double delay_seconds);
92
93 /**
94 * @brief Convenience method for repeating an action at regular intervals
95 * @param interval_seconds Time between each execution
96 * @param action Function to execute
97 * @return Reference to this EventChain for method chaining
98 */
99 EventChain& every(double interval_seconds, std::function<void()> action);
100
101 /**
102 * @brief Starts executing the event chain
103 *
104 * This method begins the execution of the event chain, scheduling each event
105 * to occur at its specified time. The events are executed in the order they
106 * were added, with the specified delays between them.
107 *
108 * The timing is sample-accurate, ensuring that each event occurs at precisely
109 * the right moment in the computational timeline.
110 */
111 void start();
112
113 /**
114 * @brief Cancels the event chain if it's currently executing
115 *
116 * Terminates the underlying coroutine, preventing any remaining
117 * events from executing. Safe to call even if chain has completed.
118 */
119 void cancel();
120
121 /**
122 * @brief Checks if the event chain is currently active
123 * @return True if chain is executing, false if completed or not started
124 */
125 [[nodiscard]] bool is_active() const;
126
127 /**
128 * @brief Sets a callback to execute when the chain stops executing
129 * @param callback Function to call after chain completes or is cancelled
130 *
131 * The callback fires regardless of how the chain stops:
132 * - After final event completes normally
133 * - After cancel() is called
134 * - After an exception in an action (action exceptions are caught)
135 *
136 * Use this for cleanup that must happen regardless of completion reason.
137 * For actions that should only run on successful completion, use .then()
138 */
139 EventChain& on_complete(std::function<void()> callback);
140
141 /**
142 * @brief Gets the name of the event chain
143 * @return Name of the event chain
144 *
145 * The name can be used for debugging or management purposes, especially when
146 * multiple chains are active. If no name was set, this will return an empty string.
147 */
148 [[nodiscard]] const std::string& name() const { return m_name; }
149
150 /**
151 * @brief Gets the number of events in the chain
152 * @return Number of events
153 */
154 [[nodiscard]] size_t event_count() const { return m_events.size(); }
155
156 /**
157 * @brief Gets the repeat count for the entire chain
158 * @return Number of times the chain will repeat
159 */
160 [[nodiscard]] size_t repeat_count() const { return m_repeat_count; }
161
162private:
163 /**
164 * @brief Structure representing a timed event in the chain
165 *
166 * This structure encapsulates an action to perform and the delay before
167 * performing it, relative to the previous event in the chain.
168 */
169 struct TimedEvent {
170 std::function<void()> action; ///< Function to execute
171 double delay_seconds; ///< Delay before execution
172 };
173
174 /**
175 * @brief Collection of events in this chain
176 *
177 * This vector contains all the events that have been added to the chain,
178 * in the order they will be executed.
179 */
180 std::vector<TimedEvent> m_events;
181
182 /**
183 * @brief Reference to the scheduler that manages timing
184 *
185 * The scheduler provides the timing infrastructure needed for
186 * precise execution of events in the chain.
187 */
189
190 /**
191 * @brief Processing token to determine which scheduler rate to use
192 *
193 * This token indicates which processing engine's timing should be used
194 * for the events in this chain. It allows the EventChain to be flexible
195 * and work with different types of processing timelines.
196 */
198
199 /**
200 * @brief The underlying computational routine that implements the chain
201 *
202 * This coroutine handles the actual timing and execution of events
203 * in the chain. It's created when start() is called.
204 */
205 std::shared_ptr<Vruta::Routine> m_routine;
206
207 /**
208 * @brief Optional callback to execute when the chain completes
209 *
210 * This function is called after the final event in the chain has executed.
211 * It can be used for cleanup, triggering subsequent actions, or any other
212 * behavior that should occur after the chain finishes.
213 */
214 std::function<void()> m_on_complete;
215
216 /**
217 * @brief Optional name for the event chain
218 *
219 * This name can be used for debugging or management purposes, especially when
220 * multiple chains are active. If no name is provided, it will be an empty string.
221 */
222 std::string m_name;
223
224 bool m_on_complete_fired {}; ///< Flag to ensure on_complete is only fired once
225
226 /**
227 * @brief Internal method to safely fire the on_complete callback
228 */
229 void fire_on_complete();
230
231 size_t m_repeat_count { 1 }; ///< Number of times to repeat the entire chain
232
233 uint64_t m_default_rate { 48000 };
234};
235
236}
size_t count
Vruta::TaskScheduler & m_Scheduler
Reference to the scheduler that manages timing.
Definition Chain.hpp:188
const std::string & name() const
Gets the name of the event chain.
Definition Chain.hpp:148
std::function< void()> m_on_complete
Optional callback to execute when the chain completes.
Definition Chain.hpp:214
std::vector< TimedEvent > m_events
Collection of events in this chain.
Definition Chain.hpp:180
Vruta::ProcessingToken m_token
Processing token to determine which scheduler rate to use.
Definition Chain.hpp:197
std::shared_ptr< Vruta::Routine > m_routine
The underlying computational routine that implements the chain.
Definition Chain.hpp:205
size_t repeat_count() const
Gets the repeat count for the entire chain.
Definition Chain.hpp:160
std::string m_name
Optional name for the event chain.
Definition Chain.hpp:222
size_t event_count() const
Gets the number of events in the chain.
Definition Chain.hpp:154
A sequential chain of timed events with precise temporal control.
Definition Chain.hpp:43
Token-based multimodal task scheduling system for unified coroutine processing.
Definition Scheduler.hpp:51
double delay_seconds
Delay before execution.
Definition Chain.hpp:171
std::function< void()> action
Function to execute.
Definition Chain.hpp:170
Structure representing a timed event in the chain.
Definition Chain.hpp:169