MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Engine.hpp
Go to the documentation of this file.
1#pragma once
2
4
9
11class Stochastic;
12}
13
14namespace MayaFlux::Vruta {
15class EventManager;
16}
17
18namespace MayaFlux::IO {
19class IOManager;
20}
21
22namespace MayaFlux::Core {
23
24class WindowManager;
25class InputManager;
26
27/**
28 * @class Engine
29 * @brief Central lifecycle manager and component orchestrator for the MayaFlux processing system
30 *
31 * The Engine serves as the primary entry point and lifecycle coordinator for MayaFlux, acting as:
32 * - **Lifecycle Manager**: Controls initialization, startup, pause/resume, and shutdown sequences
33 * - **Component Initializer**: Creates and configures core system components with proper dependencies
34 * - **Access Router**: Provides centralized access to all major subsystems and managers
35 * - **Reference Holder**: Maintains shared ownership of core components to ensure proper lifetime management
36 *
37 * **Core Responsibilities:**
38 * 1. **System Initialization**: Orchestrates the creation and configuration of all core components
39 * 2. **Lifecycle Control**: Manages the start/stop/pause/resume cycle of the entire processing system
40 * 3. **Component Access**: Provides unified access to subsystems (audio, scheduling, node graph, buffers)
41 * 4. **Resource Management**: Ensures proper construction/destruction order and shared ownership
42 *
43 * **Architecture Philosophy:**
44 * The Engine follows a "batteries included but replaceable" approach:
45 * - Provides sensible defaults and automatic component wiring for ease of use
46 * - Allows advanced users to access individual components directly for custom workflows
47 * - Enables completely custom component instantiation when needed
48 *
49 * **Usage Patterns:**
50 *
51 * *Simple Usage (Recommended):*
52 * ```cpp
53 * Engine engine;
54 * engine.Init(48000, 512, 2, 0); // 48kHz, 512 samples, stereo out
55 * engine.Start();
56 * // Use engine.get_scheduler(), engine.get_node_graph_manager(), etc.
57 * ```
58 *
59 * *Advanced Usage:*
60 * ```cpp
61 * Engine engine;
62 * auto custom_scheduler = std::make_shared<CustomScheduler>();
63 * engine.Init(stream_info);
64 * // Replace default scheduler with custom implementation
65 * engine.get_scheduler() = custom_scheduler;
66 * ```
67 *
68 * *Offline Processing:*
69 * ```cpp
70 * // Engine components can be used without hardware I/O
71 * auto scheduler = engine.get_scheduler();
72 * auto node_graph = engine.get_node_graph_manager();
73 * // Process manually without Start()
74 * ```
75 *
76 * The Engine does not perform direct signal processing or scheduling - it delegates these
77 * responsibilities to specialized subsystems while ensuring they work together coherently.
78 */
79class MAYAFLUX_API Engine {
80public:
81 //-------------------------------------------------------------------------
82 // Initialization and Lifecycle
83 //-------------------------------------------------------------------------
84
85 /**
86 * @brief Constructs a new Engine instance
87 * @param type The type of audio backend to use (default: RtAudio)
88 *
89 * Creates a new Engine instance with the specified audio backend.
90 * The backend type determines the underlying audio API used for device management
91 * and stream processing.
92 */
93 Engine();
94
95 /**
96 * @brief Destroys the Engine instance and cleans up resources
97 *
98 * Stops and closes any active streams and frees allocated resources.
99 */
100 ~Engine();
101
102 Engine(const Engine&) = delete;
103 Engine& operator=(const Engine&) = delete;
104
105 /**
106 * @brief Move constructor
107 * @param other Engine instance to move from
108 */
109 Engine(Engine&& other) noexcept;
110
111 /**
112 * @brief Move assignment operator
113 * @param other Engine instance to move from
114 * @return Reference to this Engine
115 */
116 Engine& operator=(Engine&& other) noexcept;
117
118 /**
119 * @brief Initializes all system components and prepares for processing
120 *
121 * Orchestrates the initialization sequence for all core components:
122 * - Creates and configures the task scheduler with the specified sample rate
123 * - Initializes the node graph manager and buffer manager
124 * - Sets up subsystem managers and audio backend
125 * - Establishes proper component interconnections
126 *
127 * This method must be called before Start().
128 */
129 void Init();
130
131 /**
132 * @brief Initializes the processing engine with a custom stream configuration
133 * @param streamInfo Configuration for sample rate, buffer size, and channels
134 *
135 * Configures the processing engine with the specified stream information.
136 * This method must be called before starting the engine.
137 */
138 void Init(const GlobalStreamInfo& streamInfo);
139
140 /**
141 * @brief Initializes the processing engine with custom stream and graphics configurations
142 * @param streamInfo Configuration for sample rate, buffer size, and channels
143 * @param graphics_config Configuration for graphics/windowing backend
144 * @param input_config Configuration for input handling
145 *
146 * Configures the processing engine with the specified stream and graphics information.
147 * This method must be called before starting the engine.
148 */
149 void Init(const GlobalStreamInfo& streamInfo, const GlobalGraphicsConfig& graphics_config, const GlobalInputConfig& input_config);
150
151 /**
152 * @brief Starts the coordinated processing of all subsystems
153 *
154 * Initiates the processing lifecycle by:
155 * - Starting the audio backend and opening streams
156 * - Beginning task scheduler execution
157 * - Activating node graph processing
158 * - Enabling real-time audio I/O
159 *
160 * Init() must be called first to prepare all components.
161 */
162 void Start();
163
164 /**
165 * @brief Pauses all processing while maintaining system state
166 *
167 * Temporarily halts processing activities:
168 * - Pauses the audio stream
169 * - Suspends task scheduler execution
170 * - Maintains all component state for later resumption
171 */
172 void Pause();
173
174 /**
175 * @brief Resumes processing from paused state
176 *
177 * Restarts all processing activities:
178 * - Resumes the audio stream
179 * - Reactivates task scheduler
180 * - Continues from the exact state when paused
181 */
182 void Resume();
183
184 /**
185 * @brief Stops all processing and performs clean shutdown
186 *
187 * Orchestrates the shutdown sequence:
188 * - Terminates all active tasks and coroutines
189 * - Stops and closes audio streams
190 * - Releases all resources and buffers
191 * - Resets components to uninitialized state
192 */
193 void End();
194
195 /**
196 * @brief Checks if the coordinated processing system is currently active
197 * @return true if all subsystems are running and processing, false otherwise
198 *
199 * This reflects the overall system state - true only when the audio stream
200 * is active, schedulers are running, and the system is processing data.
201 */
202 bool is_running() const;
203
204 //-------------------------------------------------------------------------
205 // Configuration Access
206 //-------------------------------------------------------------------------
207
208 /**
209 * @brief Gets the current stream configuration
210 * @return Reference to the GlobalStreamInfo struct
211 */
212 inline GlobalStreamInfo& get_stream_info() { return m_stream_info; }
213
214 /**
215 * @brief Gets the current graphics configuration
216 * @return Reference to the GlobalGraphicsConfig struct
217 */
218 inline GlobalGraphicsConfig& get_graphics_config() { return m_graphics_config; }
219
220 /**
221 * @brief Gets the current input configuration
222 * @return Reference to the GlobalInputConfig struct
223 */
224 inline GlobalInputConfig& get_input_config() { return m_input_config; }
225
226 /**
227 * @brief Gets the current node processing configuration
228 * @return Reference to the Nodes::NodeConfig struct
229 */
230 Nodes::NodeConfig& get_node_config();
231
232 /**
233 * @brief Sets the node processing configuration
234 * @param config The new node configuration to apply
235 */
236 void set_node_config(const Nodes::NodeConfig& config);
237
238 //-------------------------------------------------------------------------
239 // Component Access - Engine acts as access router to all subsystems
240 //-------------------------------------------------------------------------
241
242 /**
243 * @brief Gets the node graph manager
244 * @return Shared pointer to the NodeGraphManager for node-based processing
245 *
246 * The NodeGraphManager handles the computational graph of processing nodes.
247 * Access through Engine ensures proper initialization and lifetime management.
248 */
249 inline std::shared_ptr<Nodes::NodeGraphManager> get_node_graph_manager() { return m_node_graph_manager; }
250
251 /**
252 * @brief Gets the task scheduler
253 * @return Shared pointer to the TaskScheduler for coroutine-based timing
254 *
255 * The TaskScheduler manages sample-accurate timing and coroutine execution.
256 * Access through Engine ensures proper clock synchronization with audio.
257 */
258 inline std::shared_ptr<Vruta::TaskScheduler> get_scheduler() { return m_scheduler; }
259
260 /**
261 * @brief Gets the buffer manager
262 * @return Shared pointer to the BufferManager for memory management
263 *
264 * The BufferManager handles efficient allocation and reuse of audio buffers.
265 * Access through Engine ensures buffers are sized correctly for the stream.
266 */
267 inline std::shared_ptr<Buffers::BufferManager> get_buffer_manager() { return m_buffer_manager; }
268
269 /**
270 * @brief Gets the window manager
271 * @return Shared pointer to the WindowManager for windowing operations
272 *
273 * The WindowManager handles creation and management of application windows.
274 * Access through Engine ensures proper graphics backend initialization.
275 */
276 inline std::shared_ptr<WindowManager> get_window_manager() { return m_window_manager; }
277
278 /**
279 * @brief Gets the event manager
280 * @return Shared pointer to the EventManager for input/event handling
281 *
282 * The EventManager processes input events (keyboard, mouse, etc.).
283 * Access through Engine ensures events are routed correctly to windows.
284 */
285 inline std::shared_ptr<Vruta::EventManager> get_event_manager() { return m_event_manager; }
286
287 /**
288 * @brief Gets the input manager
289 * @return Shared pointer to the InputManager for handling user input
290 *
291 * The InputManager manages various input devices (HID, MIDI, etc.).
292 * Access through Engine ensures proper device initialization and event routing.
293 */
294 inline std::shared_ptr<InputManager> get_input_manager() { return m_input_manager; }
295
296 /**
297 * @brief Gets the IO manager
298 * @return Shared pointer to the IOManager for media loading and dispatch
299 *
300 * The IOManager provides high-level functions for loading video/audio files
301 * and manages the dispatch of decode requests to background threads.
302 * Access through Engine ensures proper initialization and integration with buffers.
303 */
304 inline std::shared_ptr<IO::IOManager> get_io_manager() { return m_io_manager; }
305
306 /**
307 * @brief Gets the stochastic signal generator engine
308 * @return Pointer to the Stochastic engine for random/procedural generation
309 *
310 * The Stochastic engine provides a unified interface for generating random values
311 * and procedural signals across all domains. Access through Engine ensures a
312 * single shared instance is used throughout the system for consistent behavior and state management.
313 */
314 inline Kinesis::Stochastic::Stochastic* get_stochastic_engine() { return m_stochastic_engine.get(); }
315
316 /**
317 * @brief Gets the subsystem manager for advanced component access
318 * @return Shared pointer to SubsystemManager for subsystem coordination
319 *
320 * The SubsystemManager provides access to specialized subsystems like
321 * audio backends, graphics systems, and custom processing domains.
322 */
323 inline std::shared_ptr<SubsystemManager> get_subsystem_manager() { return m_subsystem_manager; }
324
325 /**
326 * @brief Get typed access to a specific subsystem
327 * @tparam SubsystemType Expected type of the subsystem
328 * @param tokens Token configuration identifying the subsystem
329 * @return Shared pointer to subsystem or nullptr if not found
330 */
331 std::shared_ptr<ISubsystem> get_subsystem(SubsystemType type)
332 {
333 return m_subsystem_manager->get_subsystem(type);
334 }
335
336 /**
337 * @brief Blocks until shutdown is requested (main thread event loop)
338 *
339 * Pumps platform-specific events on the main thread and waits for shutdown.
340 * On macOS: Runs CFRunLoop to process dispatch queue (required for GLFW)
341 * On other platforms: Simple blocking wait for user input
342 *
343 * Should be called on the main thread after Start().
344 */
345 void await_shutdown();
346
347 /**
348 * @brief Request shutdown from any thread
349 *
350 * Signals the event loop to exit. Thread-safe.
351 * Call this to gracefully terminate await_shutdown().
352 */
353 void request_shutdown();
354
355 /**
356 * @brief Check if shutdown has been requested
357 * @return true if shutdown was requested
358 */
359 bool is_shutdown_requested() const;
360
361private:
362 //-------------------------------------------------------------------------
363 // System Components
364 //-------------------------------------------------------------------------
365
366 GlobalStreamInfo m_stream_info {}; ///< Stream configuration
367 GlobalGraphicsConfig m_graphics_config {}; ///< Graphics/windowing configuration
368 GlobalInputConfig m_input_config {}; ///< Input configuration
369 Nodes::NodeConfig m_node_config {}; ///< Node processing configuration
370
371 bool m_is_paused {}; ///< Pause state flag
372 bool m_is_initialized {};
373
374 std::atomic<bool> m_should_shutdown { false };
375
376 //-------------------------------------------------------------------------
377 // Core Components
378 //-------------------------------------------------------------------------
379
380 std::shared_ptr<Vruta::TaskScheduler> m_scheduler; ///< Task scheduler
381 std::shared_ptr<Nodes::NodeGraphManager> m_node_graph_manager; ///< Node graph manager
382 std::shared_ptr<Buffers::BufferManager> m_buffer_manager; ///< Buffer manager
383 std::shared_ptr<SubsystemManager> m_subsystem_manager;
384 std::shared_ptr<WindowManager> m_window_manager; ///< Window manager (Windowing subsystem)
385 std::shared_ptr<Vruta::EventManager> m_event_manager; ///< Event manager (currently only glfw events)
386 std::shared_ptr<InputManager> m_input_manager; ///< Input manager (HID/MIDI/etc.)
387 std::shared_ptr<IO::IOManager> m_io_manager; ///< IO manager for video/audio loading and dispatch
388 std::unique_ptr<Kinesis::Stochastic::Stochastic> m_stochastic_engine; ///< Core stochastic engine for random generation
389
390#ifdef MAYAFLUX_PLATFORM_MACOS
391 void run_macos_event_loop();
392#endif
393
394#ifdef MAYAFLUX_PLATFORM_WINDOWS
395 void run_windows_event_loop();
396#endif
397};
398
399} // namespace MayaFlux::Core
GlobalStreamInfo & get_stream_info()
Gets the current stream configuration.
Definition Engine.hpp:212
std::shared_ptr< SubsystemManager > m_subsystem_manager
Definition Engine.hpp:383
std::shared_ptr< WindowManager > get_window_manager()
Gets the window manager.
Definition Engine.hpp:276
std::shared_ptr< Nodes::NodeGraphManager > get_node_graph_manager()
Gets the node graph manager.
Definition Engine.hpp:249
std::shared_ptr< IO::IOManager > m_io_manager
IO manager for video/audio loading and dispatch.
Definition Engine.hpp:387
std::shared_ptr< Vruta::EventManager > m_event_manager
Event manager (currently only glfw events)
Definition Engine.hpp:385
Engine(const Engine &)=delete
std::shared_ptr< Buffers::BufferManager > m_buffer_manager
Buffer manager.
Definition Engine.hpp:382
std::shared_ptr< ISubsystem > get_subsystem(SubsystemType type)
Get typed access to a specific subsystem.
Definition Engine.hpp:331
std::shared_ptr< InputManager > get_input_manager()
Gets the input manager.
Definition Engine.hpp:294
std::shared_ptr< SubsystemManager > get_subsystem_manager()
Gets the subsystem manager for advanced component access.
Definition Engine.hpp:323
GlobalInputConfig & get_input_config()
Gets the current input configuration.
Definition Engine.hpp:224
std::unique_ptr< Kinesis::Stochastic::Stochastic > m_stochastic_engine
Core stochastic engine for random generation.
Definition Engine.hpp:388
GlobalGraphicsConfig & get_graphics_config()
Gets the current graphics configuration.
Definition Engine.hpp:218
std::shared_ptr< WindowManager > m_window_manager
Window manager (Windowing subsystem)
Definition Engine.hpp:384
std::shared_ptr< Vruta::EventManager > get_event_manager()
Gets the event manager.
Definition Engine.hpp:285
std::shared_ptr< Vruta::TaskScheduler > m_scheduler
Task scheduler.
Definition Engine.hpp:380
std::shared_ptr< InputManager > m_input_manager
Input manager (HID/MIDI/etc.)
Definition Engine.hpp:386
std::shared_ptr< IO::IOManager > get_io_manager()
Gets the IO manager.
Definition Engine.hpp:304
std::shared_ptr< Vruta::TaskScheduler > get_scheduler()
Gets the task scheduler.
Definition Engine.hpp:258
std::shared_ptr< Buffers::BufferManager > get_buffer_manager()
Gets the buffer manager.
Definition Engine.hpp:267
std::shared_ptr< Nodes::NodeGraphManager > m_node_graph_manager
Node graph manager.
Definition Engine.hpp:381
Engine & operator=(const Engine &)=delete
Kinesis::Stochastic::Stochastic * get_stochastic_engine()
Gets the stochastic signal generator engine.
Definition Engine.hpp:314
Central lifecycle manager and component orchestrator for the MayaFlux processing system.
Definition Engine.hpp:79
Unified generative infrastructure for stochastic and procedural algorithms.
void Resume()
Resumes audio processing on the default engine.
Definition Core.cpp:122
void Start()
Starts audio processing on the default engine.
Definition Core.cpp:110
void Pause()
Pauses audio processing on the default engine.
Definition Core.cpp:115
void Init()
Initializes the default engine with default settings.
Definition Core.cpp:86
void End()
Stops and cleans up the default engine.
Definition Core.cpp:136
Configuration for the InputSubsystem.
Comprehensive configuration for digital audio stream processing.
Configuration settings for individual audio nodes.
Definition NodeSpec.hpp:29