MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
SubsystemManager.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include "MayaFlux/Utils.hpp"
6
7namespace MayaFlux::Core {
8
9class WindowManager;
10class AudioSubsystem;
12struct GlobalStreamInfo;
13struct GlobalGraphicsConfig;
14
15/**
16 * @class SubsystemManager
17 * @brief Central coordinator for all subsystems in the MayaFlux processing architecture
18 *
19 * Manages subsystem lifecycle, provides token-scoped processing handles, and coordinates
20 * cross-subsystem operations. Each subsystem receives a dedicated processing handle that
21 * ensures proper isolation and thread safety within its designated processing domain.
22 *
23 * Key responsibilities:
24 * - Subsystem registration and lifecycle management
25 * - Processing handle creation and distribution
26 * - Cross-subsystem data access control
27 * - Coordinated startup and shutdown sequences
28 */
29class MAYAFLUX_API SubsystemManager {
30public:
31 /**
32 * @brief Constructs SubsystemManager with required processing managers
33 * @param node_graph_manager Shared node graph manager for all subsystems
34 * @param buffer_manager Shared buffer manager for all subsystems
35 * @param task_scheduler Shared task scheduler for all subsystems
36 * @param window_manager Optional shared window manager for graphics subsystems
37 *
38 * Initializes the manager with references to the core processing systems.
39 * These managers are shared across all subsystems but accessed through
40 * token-scoped handles for proper isolation.
41 */
43 std::shared_ptr<Nodes::NodeGraphManager> node_graph_manager,
44 std::shared_ptr<Buffers::BufferManager> buffer_manager,
45 std::shared_ptr<Vruta::TaskScheduler> task_scheduler,
46 std::shared_ptr<Core::WindowManager> window_manager = nullptr);
47
48 /**
49 * @brief Internal template method for type-safe subsystem creation
50 * @tparam SType Type of subsystem to create
51 * @tparam Args Constructor argument types
52 * @param type SubsystemType enum value identifying the subsystem category
53 * @param args Constructor arguments for the subsystem
54 *
55 * Creates a subsystem instance and registers it with the manager.
56 * Used internally by specific subsystem creation methods.
57 */
58 template <typename SType, typename... Args>
59 void create_subsystem_internal(SubsystemType type, Args&&... args)
60 {
61 auto subsystem = std::make_shared<SType>(std::forward<Args>(args)...);
62 add_subsystem(type, std::move(subsystem));
63 }
64
65 /**
66 * @brief Create and register the audio subsystem
67 * @tparam Args Constructor argument types
68 * @param args Constructor arguments for AudioSubsystem
69 *
70 * Specialized creation method for AudioSubsystem. Only one audio subsystem
71 * is allowed per manager instance.
72 */
73 void create_audio_subsystem(GlobalStreamInfo& stream_info, Utils::AudioBackendType backend_type);
74
75 /**
76 * @brief Create and register the graphics subsystem
77 * @param graphics_config Global graphics configuration
78 *
79 * Specialized creation method for GraphicsSubsystem. Only one graphics
80 * subsystem is allowed per manager instance.
81 */
82 void create_graphics_subsystem(const GlobalGraphicsConfig& graphics_config);
83
84 /** @brief Start all registered subsystems in coordination */
85 void start_all_subsystems();
86
87 /** @brief Pause all subsystems */
88 void pause_all_subsystems();
89
90 /** @brief Resume all paused subsystems */
91 void resume_all_subsystems();
92
93 /**
94 * @brief Get access to a specific subsystem by type
95 * @param type SubsystemType enum value identifying the subsystem
96 * @return Shared pointer to subsystem or nullptr if not found
97 *
98 * Provides access to registered subsystems for direct interaction.
99 * Returns nullptr if subsystem of specified type doesn't exist.
100 */
101 std::shared_ptr<ISubsystem> get_subsystem(SubsystemType type);
102
103 /**
104 * @brief Get typed access to the audio subsystem
105 * @return Shared pointer to AudioSubsystem or nullptr if not created
106 *
107 * Convenience method that automatically casts to AudioSubsystem type.
108 * Equivalent to dynamic_cast on get_subsystem(SubsystemType::AUDIO).
109 */
110 std::shared_ptr<AudioSubsystem> get_audio_subsystem();
111
112 /**
113 * @brief Get typed access to the graphics subsystem
114 * @return Shared pointer to GraphicsSubsystem or nullptr if not created
115 *
116 * Convenience method that automatically casts to GraphicsSubsystem type.
117 * Equivalent to dynamic_cast on get_subsystem(SubsystemType::GRAPHICS).
118 */
119 std::shared_ptr<GraphicsSubsystem> get_graphics_subsystem();
120
121 /**
122 * @brief Check if a subsystem type exists
123 * @param type SubsystemType to check for existence
124 * @return True if subsystem of this type is registered
125 *
126 * Fast existence check without retrieving the subsystem instance.
127 */
128 inline bool has_subsystem(SubsystemType type) const { return m_subsystems.count(type) > 0; }
129
130 /**
131 * @brief Get all currently active subsystem types
132 * @return Vector of SubsystemType values for all registered subsystems
133 *
134 * Returns the types of all subsystems currently managed by this instance.
135 */
136 std::vector<SubsystemType> get_active_subsystem_types() const;
137
138 /**
139 * @brief Register a subsystem instance with the manager
140 * @param type SubsystemType enum value identifying the subsystem category
141 * @param subsystem Shared pointer to the subsystem instance
142 *
143 * Registers a pre-constructed subsystem with the manager and creates
144 * its processing handle. The subsystem is initialized but not started.
145 */
146 void add_subsystem(SubsystemType type, const std::shared_ptr<ISubsystem>& subsystem);
147
148 /**
149 * @brief Remove and shutdown a subsystem
150 * @param type SubsystemType enum value identifying the subsystem to remove
151 *
152 * Stops, shuts down, and removes the specified subsystem from management.
153 * Cleans up associated processing handles and resources.
154 */
155 void remove_subsystem(SubsystemType type);
156
157 /**
158 * @brief Query operational status of all subsystems
159 * @return Map of SubsystemType to boolean indicating ready/running status
160 *
161 * Returns the current operational status of all managed subsystems.
162 * Status reflects whether each subsystem is ready for operation.
163 */
164 std::unordered_map<SubsystemType, std::pair<bool, bool>> query_subsystem_status() const;
165
166 /**
167 * @brief Execute an operation with temporary elevated permissions
168 * @tparam Func Function type for the operation
169 * @param primary_tokens Primary subsystem tokens
170 * @param secondary_tokens Secondary subsystem tokens for cross-domain access
171 * @param operation Function to execute with combined access
172 *
173 * For special cross-domain operations (e.g., audio-reactive visuals).
174 * Creates a temporary handle with combined token access for controlled
175 * cross-subsystem operations.
176 */
177 template <typename Func>
179 SubsystemTokens primary_tokens,
180 SubsystemTokens /*secondary_tokens*/,
181 Func operation)
182 {
183 SubsystemTokens combined_tokens {
184 .Buffer = primary_tokens.Buffer,
185 .Node = primary_tokens.Node,
186 .Task = primary_tokens.Task
187 };
188
189 SubsystemProcessingHandle temp_handle(
190 m_buffer_manager,
191 m_node_graph_manager,
192 m_task_scheduler,
193 combined_tokens);
194
195 operation(temp_handle);
196 }
197
198 /** @brief Shutdown all subsystems in proper order */
199 void shutdown();
200
201 /**
202 * @brief Configure cross-subsystem data access permissions
203 * @param from SubsystemType that requests access
204 * @param to SubsystemType that provides data
205 *
206 * Establishes permission for one subsystem to read data from another.
207 * Required for cross-subsystem operations like audio-reactive visuals.
208 */
209 void allow_cross_access(SubsystemType from, SubsystemType to);
210
211 /**
212 * @brief Read data from another subsystem's buffers
213 * @param requesting_type SubsystemType making the data request
214 * @param target_type SubsystemType providing the data
215 * @param channel Channel index to read from
216 * @return Read-only span if access allowed, nullopt otherwise
217 *
218 * Enables controlled cross-subsystem data sharing with permission checking.
219 * Used for scenarios where one subsystem needs processed data from another.
220 */
221 std::optional<std::span<const double>> read_cross_subsystem_buffer(
222 SubsystemType requesting_type,
223 SubsystemType target_type,
224 uint32_t channel);
225
226 /**
227 * @brief Register a processing hook for a specific subsystem
228 * @param type SubsystemType to attach the hook to
229 * @param name Unique identifier for the hook
230 * @param hook Callback function to execute
231 * @param position When to execute the hook (PRE_PROCESS or POST_PROCESS)
232 *
233 * Process hooks allow custom code execution at specific points in the
234 * processing cycle. Used for monitoring, debugging, or additional processing.
235 */
236 void register_process_hook(SubsystemType type, const std::string& name, ProcessHook hook, HookPosition position = HookPosition::POST_PROCESS);
237
238 /**
239 * @brief Remove a previously registered processing hook
240 * @param type SubsystemType the hook is attached to
241 * @param name Unique identifier of the hook to remove
242 *
243 * Removes the named hook from the specified subsystem's processing cycle.
244 */
245 void unregister_process_hook(SubsystemType type, const std::string& name);
246
247 /**
248 * @brief Check if a processing hook exists
249 * @param type SubsystemType to check
250 * @param name Hook identifier to look for
251 * @return True if hook exists (in either pre or post position)
252 *
253 * Checks both pre-process and post-process hook collections for the named hook.
254 */
255 bool has_process_hook(SubsystemType type, const std::string& name);
256
257 /**
258 * @brief Get processing handle with validation
259 * @param type Subsystem type
260 * @return Valid handle or nullptr if validation fails
261 */
262 SubsystemProcessingHandle* get_validated_handle(SubsystemType type) const;
263
264private:
265 bool is_cross_access_allowed(SubsystemType from, SubsystemType to) const;
266
268
269 std::shared_ptr<Nodes::NodeGraphManager> m_node_graph_manager;
270 std::shared_ptr<Buffers::BufferManager> m_buffer_manager;
271 std::shared_ptr<Vruta::TaskScheduler> m_task_scheduler;
272 std::shared_ptr<Core::WindowManager> m_window_manager;
273
274 std::unordered_map<SubsystemType, std::shared_ptr<ISubsystem>> m_subsystems;
275 std::unordered_map<SubsystemType, std::unique_ptr<SubsystemProcessingHandle>> m_handles;
276 std::unordered_map<SubsystemType, std::unordered_set<SubsystemType>> m_cross_access_permissions;
277
278 mutable std::shared_mutex m_mutex; ///< Thread safety for subsystem operations
279};
280
281}
std::shared_ptr< Buffers::BufferManager > m_buffer_manager
std::shared_ptr< Nodes::NodeGraphManager > m_node_graph_manager
std::shared_ptr< Vruta::TaskScheduler > m_task_scheduler
SubsystemTokens get_tokens_for_type(SubsystemType type) const
std::unordered_map< SubsystemType, std::unordered_set< SubsystemType > > m_cross_access_permissions
bool has_subsystem(SubsystemType type) const
Check if a subsystem type exists.
void execute_with_combined_tokens(SubsystemTokens primary_tokens, SubsystemTokens, Func operation)
Execute an operation with temporary elevated permissions.
std::shared_ptr< Core::WindowManager > m_window_manager
std::unordered_map< SubsystemType, std::unique_ptr< SubsystemProcessingHandle > > m_handles
void create_subsystem_internal(SubsystemType type, Args &&... args)
Internal template method for type-safe subsystem creation.
std::vector< SubsystemType > get_active_subsystem_types() const
Get all currently active subsystem types.
std::unordered_map< SubsystemType, std::shared_ptr< ISubsystem > > m_subsystems
std::shared_mutex m_mutex
Thread safety for subsystem operations.
Central coordinator for all subsystems in the MayaFlux processing architecture.
Unified interface combining buffer and node processing for subsystems.
std::function< void(unsigned int num_frames)> ProcessHook
Function type for process hooks that can be registered with the engine.
HookPosition
Defines the position in the processing cycle where a hook should be executed.
@ AudioSubsystem
Audio subsystem operations (backend, device, stream management)
@ GraphicsSubsystem
Graphics subsystem operations (Vulkan, rendering pipeline)
Comprehensive configuration for digital audio stream processing.
MayaFlux::Vruta::ProcessingToken Task
Processing token for task scheduling operations.
MayaFlux::Buffers::ProcessingToken Buffer
Processing token for buffer operations.
MayaFlux::Nodes::ProcessingToken Node
Processing token for node graph operations.
Processing token configuration for subsystem operation.