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