MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NodeGraphManager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "NodeSpec.hpp"
4#include "RootNode.hpp"
5
6namespace MayaFlux::Nodes {
7
8using TokenChannelProcessor = std::function<std::vector<double>(RootNode*, uint32_t)>;
9using TokenSampleProcessor = std::function<double(RootNode*, uint32_t)>;
10
11namespace Network {
12 class NodeNetwork;
13} // namespace Network
14
15/**
16 * @class NodeGraphManager
17 * @brief Central manager for the computational processing node graph
18 *
19 * The NodeGraphManager is the primary interface for creating, connecting, and managing
20 * processing nodes in the MayaFlux engine. It serves as a registry for all nodes
21 * and maintains the root nodes for each processing channel and processing domain (token).
22 *
23 * Features:
24 * - Multi-modal (token-based) processing: Supports multiple independent processing domains
25 * (e.g., AUDIO_RATE, VISUAL_RATE, CUSTOM_RATE), each with its own set of channels and root nodes.
26 * - Per-channel root nodes: Each processing domain can have multiple channels, each with its own RootNode.
27 * - Node registry: Nodes are registered by string identifier for easy lookup and connection.
28 * - Flexible connection: Nodes can be connected by reference or by identifier, supporting both direct and named graph construction.
29 * - Subsystem token processors: Allows registration of custom processing functions for each token, enabling efficient backend-specific processing.
30 *
31 * This class provides methods to:
32 * - Create nodes of any type with automatic registration
33 * - Connect nodes to form processing chains
34 * - Add nodes to channel root nodes for output
35 * - Look up nodes by their string identifiers
36 *
37 * The NodeGraphManager maintains separate root nodes for each processing channel.
38 * Channels are local to a specific processing domain.
39 * This allows for independent transformation chains per channel while sharing nodes
40 * between channels when needed.
41 */
42class MAYAFLUX_API NodeGraphManager {
43public:
44 /**
45 * @brief Creates a new NodeGraphManager
46 * @param sample_rate Sample rate for audio processing (default: 48000 Hz)
47 * @param block_size Block size for audio processing (default: 512 samples)
48 *
49 * Initializes the manager with a root node for channel 0 (the default channel)
50 * in the AUDIO_RATE domain. Additional root nodes for other tokens and channels
51 * are created on demand when accessed.
52 */
53 NodeGraphManager(uint32_t sample_rate = 48000, uint32_t block_size = 512);
54
55 /**
56 * @brief Destroys the NodeGraphManager
57 *
58 * Cleans up all registered nodes and networks.
59 */
61
62 // NodeGraphManager is non-copyable and non-moveable due to internal atomic state
67
68 /**
69 * @brief Add node to specific processing token and channel
70 * @param node Node to add
71 * @param token Processing domain (AUDIO_RATE, VISUAL_RATE, etc.)
72 * @param channel Channel within that domain
73 *
74 * Registers the node with the specified processing domain and channel.
75 * The node's output will contribute to that token/channel's output.
76 * If the node is not already globally registered, it will be registered automatically.
77 */
78 void add_to_root(const std::shared_ptr<Node>& node, ProcessingToken token, unsigned int channel = 0);
79
80 /**
81 * @brief Remove node from a specific processing token and channel
82 * @param node Node to remove
83 * @param token Processing domain (AUDIO_RATE, VISUAL_RATE, etc.)
84 * @param channel Channel within that domain
85 *
86 * Removes the specified node from the root node of the given processing domain and channel.
87 * If the node is not found in that root, no action is taken.
88 */
89 void remove_from_root(const std::shared_ptr<Node>& node, ProcessingToken token, unsigned int channel = 0);
90
91 /**
92 * @brief Adds a node to a channel's root node by its identifier
93 * @param node_id Identifier of the node to add
94 @ param token Processing domain to add the node to (default is AUDIO_RATE)
95 * @param channel Channel index to add the node to (AUDIO_RATE domain)
96 *
97 * Looks up the node by its identifier and adds it to the specified
98 * channel's root node in the specified processing domain (default is AUDIO_RATE).
99 * Throws an exception if the node identifier is not found.
100 */
101 inline void add_to_root(const std::string& node_id, ProcessingToken token = ProcessingToken::AUDIO_RATE, unsigned int channel = 0)
102 {
103 auto node = get_node(node_id);
104 if (node) {
105 add_to_root(node, token, channel);
106 }
107 }
108
109 /**
110 * @brief Register subsystem processor for a specific token
111 * @param token Processing domain to handle (e.g., AUDIO_RATE, VISUAL_RATE)
112 * @param processor Function that receives a span of root nodes for that token
113 *
114 * Registers a custom processing function for a given processing domain (token).
115 * When process_token() is called for that token, the registered processor will
116 * be invoked with a span of all root nodes for that domain, enabling efficient
117 * backend-specific or multi-channel processing.
118 */
119 void register_token_processor(ProcessingToken token,
120 std::function<void(std::span<RootNode*>)> processor);
121
122 /**
123 * @brief Gets all channel root nodes for the AUDIO_RATE domain
124 * @param token Processing domain to get the root nodes for (default is AUDIO_RATE)
125 * @return Constant reference to the map of channel indices to root nodes
126 *
127 * This provides access to all channel root nodes of the specified domain that have been created.
128 * Useful for processing all channels or inspecting the node graph structure.
129 * For multi-modal access, use get_token_roots().
130 */
131 const std::unordered_map<unsigned int, std::shared_ptr<RootNode>>& get_all_channel_root_nodes(ProcessingToken token = ProcessingToken::AUDIO_RATE) const;
132
133 /**
134 * @brief Creates and registers a new node of the specified type
135 * @tparam NodeType The type of node to create (must derive from Node)
136 * @tparam Args Parameter types for the node's constructor
137 * @param id String identifier for the node
138 * @param args Constructor arguments for the node
139 * @return Shared pointer to the created node
140 *
141 * This template method creates a node of any type that derives from Node,
142 * passing the provided arguments to its constructor. The created node is
143 * automatically registered with the given string identifier for later lookup.
144 *
145 * Example:
146 * ```cpp
147 * auto sine = manager.create_node<Generators::Sine>("my_sine", 440.0, 0.5);
148 * auto filter = manager.create_node<Filters::LowPass>("my_filter", sine, 1000.0);
149 * ```
150 */
151 template <typename NodeType, typename... Args>
152 inline std::shared_ptr<NodeType> create_node(const std::string& id, Args&&... args)
153 {
154 auto node = std::make_shared<NodeType>(std::forward<Args>(args)...);
155 m_Node_registry[id] = node;
156 return node;
157 }
158
159 /**
160 * @brief Looks up a node by its string identifier
161 * @param id The string identifier of the node
162 * @return Shared pointer to the node, or nullptr if not found
163 *
164 * Retrieves a previously registered node using its string identifier.
165 * This allows for connecting nodes by name rather than requiring direct
166 * references to node objects.
167 */
168 std::shared_ptr<Node> get_node(const std::string& id);
169
170 /**
171 * @brief Connects two nodes by their string identifiers
172 * @param source_id Identifier of the source node
173 * @param target_id Identifier of the target node
174 *
175 * Looks up both nodes by their identifiers and establishes a connection
176 * where the output of the source node becomes an input to the target node.
177 *
178 * Equivalent to:
179 * ```cpp
180 * connect(get_node(source_id), get_node(target_id));
181 * ```
182 *
183 * Throws an exception if either node identifier is not found.
184 */
185 void connect(const std::string& source_id, const std::string& target_id);
186
187 /**
188 * @brief Checks if a node is registered with this manager
189 * @param node Node to check
190 * @return true if the node is registered, false otherwise
191 *
192 * A node is considered registered if it exists in the node registry
193 * with any identifier.
194 */
195 bool is_node_registered(const std::shared_ptr<Node>& node);
196
197 /**
198 * @brief Process all nodes in a specific token domain
199 * Calls registered processor if available, otherwise calls process() on each root
200 * @param token Processing domain to process
201 * @param num_samples Number of samples/frames to process
202 *
203 * Processes all root nodes for the specified processing domain (token).
204 * If a custom processor is registered for the token, it is called with all root nodes.
205 * Otherwise, process() is called on each root node individually.
206 */
207 void process_token(ProcessingToken token, unsigned int num_samples = 1);
208
209 /**
210 * @brief Register per-channel processor for a specific token
211 * @param token Processing domain to handle (e.g., AUDIO_RATE, VISUAL_RATE)
212 * @param processor Function that receives a single root node and returns processed data
213 *
214 * Registers a per-channel processing function that processes one root node at a time
215 * and returns the processed data. This enables coordination with buffer management
216 * on a per-channel basis.
217 */
218 void register_token_channel_processor(ProcessingToken token,
219 TokenChannelProcessor processor);
220
221 /**
222 * @brief Register per-sample processor for a specific token
223 * @param token Processing domain to handle (e.g., AUDIO_RATE, VISUAL_RATE)
224 * @param processor Function that processes a single sample and returns the processed value
225 *
226 * Registers a per-sample processing function that processes one sample at a time
227 * and returns the processed value. This is useful for low-level sample manipulation.
228 */
229 void register_token_sample_processor(ProcessingToken token,
230 TokenSampleProcessor processor);
231
232 /**
233 * @brief Process a specific channel within a token domain
234 * @param token Processing domain
235 * @param channel Channel index within that domain
236 * @param num_samples Number of samples/frames to process
237 * @return Processed data from the channel's root node
238 *
239 * Processes a single channel's root node and returns the processed data.
240 * If a custom per-channel processor is registered, it is used; otherwise,
241 * the default root node processing is performed.
242 */
243 std::vector<double> process_channel(ProcessingToken token, unsigned int channel, unsigned int num_samples);
244
245 /**
246 * @brief Process a single sample for a specific channel
247 * @param token Processing domain
248 * @param channel Channel index within that domain
249 * @return Processed sample value from the channel's root node
250 *
251 * Processes a single sample for the specified channel and returns the processed value.
252 * If a custom per-sample processor is registered, it is used; otherwise, the default
253 * root node processing is performed.
254 * As node graph manager feeds into hardware audio output, the value returned is normalized
255 */
256 double process_sample(ProcessingToken token, uint32_t channel);
257
258 /**
259 * @brief Process all channels for a token and return channel-separated data
260 * @param token Processing domain
261 * @param num_samples Number of samples/frames to process
262 * @return Map of channel index to processed data
263 *
264 * Processes all channels for a token and returns a map where each channel
265 * index maps to its processed data. This enables bulk processing while
266 * maintaining per-channel data separation.
267 */
268 std::unordered_map<unsigned int, std::vector<double>> process_token_with_channel_data(
269 ProcessingToken token, unsigned int num_samples);
270
271 /**
272 * @brief Get the number of active channels for a specific token
273 * @param token Processing domain
274 * @return Number of channels that have active root nodes
275 */
276 unsigned int get_channel_count(ProcessingToken token) const;
277
278 /**
279 * @brief Get spans of root nodes for a token (for custom processing)
280 * @param token Processing domain
281 * @return Vector of RootNode pointers for that domain
282 *
283 * Returns a vector of pointers to all root nodes for the specified processing domain.
284 * Useful for custom processing, introspection, or multi-channel operations.
285 */
286 std::vector<RootNode*> get_all_root_nodes(ProcessingToken token);
287
288 /**
289 * @brief Gets or creates the root node for a specific token and channel
290 * @param token Processing domain
291 * @param channel Channel index
292 * @return Reference to the root node for the given token and channel
293 *
294 * If the root node does not exist, it is created and registered.
295 */
296 RootNode& get_root_node(ProcessingToken token, unsigned int channel);
297
298 /**
299 * @brief Process all active tokens sequentially
300 * @param num_samples Number of samples/frames to process
301 *
302 * Iterates over all processing domains (tokens) that have active root nodes,
303 * and processes each one in turn. This enables multi-modal, multi-channel
304 * processing in a single call.
305 */
306 void process_all_tokens(unsigned int num_samples = 1);
307
308 /**
309 * @brief Gets all currently active processing tokens (domains)
310 * @return Vector of active ProcessingToken values
311 *
312 * Returns a list of all processing domains that have at least one root node.
313 * Useful for introspection and for iterating over all active domains.
314 */
315 std::vector<ProcessingToken> get_active_tokens() const;
316
317 /**
318 * @brief Gets all channel indices for a given processing token
319 * @param token Processing domain
320 * @return Vector of channel indices that have root nodes for this token
321 */
322 std::vector<unsigned int> get_all_channels(ProcessingToken token) const;
323
324 /**
325 * @brief Gets the total number of nodes registered under a given token
326 * @param token Processing domain
327 * @return Total number of nodes across all channels for this token
328 */
329 size_t get_node_count(ProcessingToken token) const;
330
331 /**
332 * @brief Prints a summary of all tokens, channels, and node counts
333 *
334 * Outputs a human-readable summary of the current node graph structure,
335 * including the number of tokens, channels, and nodes per domain.
336 * Useful for debugging and introspection.
337 */
338 void print_summary() const;
339
340 //-------------------------------------------------------------------------
341 // NodeNetwork Management
342 //-------------------------------------------------------------------------
343
344 /**
345 * @brief Add a network to a processing token
346 * @param network Network to add
347 * @param token Processing domain (AUDIO_RATE, VISUAL_RATE, etc.)
348 *
349 * Networks are processed parallel to RootNodes, managing their own
350 * internal node coordination and processing.
351 */
352 void add_network(const std::shared_ptr<Network::NodeNetwork>& network, ProcessingToken token);
353
354 /**
355 * @brief Remove a network from a processing token
356 * @param network Network to remove
357 * @param token Processing domain
358 * @param channel Channel index within that domain, optional
359 */
360 void remove_network(const std::shared_ptr<Network::NodeNetwork>& network, ProcessingToken token);
361
362 /**
363 * @brief Get all networks for a specific token
364 * @param token Processing domain
365 * @return Vector of networks registered to this token
366 */
367 [[nodiscard]] std::vector<std::shared_ptr<Network::NodeNetwork>> get_networks(ProcessingToken token, uint32_t channel = 0) const;
368
369 /**
370 * @brief Get all networks for a specific token across all channels
371 * @param token Processing domain
372 * @return Vector of networks registered to this token
373 */
374 [[nodiscard]] std::vector<std::shared_ptr<Network::NodeNetwork>> get_all_networks(ProcessingToken token) const;
375
376 /**
377 * @brief Get count of networks for a token
378 */
379 [[nodiscard]] size_t get_network_count(ProcessingToken token) const;
380
381 /**
382 * @brief Clear all networks from a token
383 */
384 void clear_networks(ProcessingToken token);
385
386 /**
387 * @brief Register network globally (like nodes)
388 */
389 void register_network_global(const std::shared_ptr<Network::NodeNetwork>& network);
390
391 /**
392 * @brief Unregister network globally
393 */
394 void unregister_network_global(const std::shared_ptr<Network::NodeNetwork>& network);
395
396 /**
397 * @brief Process audio networks for a specific channel
398 * @param token Processing domain (should be AUDIO_RATE)
399 * @param num_samples Number of samples/frames to process
400 * @param channel Channel index within that domain
401 * @return Vector of processed audio data from all networks for that channel
402 *
403 * Processes all audio-sink networks registered to the specified channel
404 * and returns their combined output data.
405 */
406 std::vector<std::vector<double>> process_audio_networks(ProcessingToken token, uint32_t num_samples, uint32_t channel = 0);
407
408 /**
409 * @brief Terminates all active processing across all tokens and channels
410 *
411 * This method stops all active processing contexts in all root nodes
412 * and networks, ensuring a clean shutdown of processing activities.
413 */
414 void terminate_active_processing();
415
416 /**
417 * @brief Routes a node's output to specific channels within a token domain
418 * @param node Node to route
419 * @param target_channels Vector of channel indices to route the node's output to
420 * @param fade_cycles Number of cycles to fade in the routing (optional)
421 * @param token Processing domain to route within
422 *
423 * This method adds the specified node to the root nodes of the target channels
424 * within the given processing domain. If fade_cycles is greater than 0, the routing
425 * will be smoothly faded in over that many processing cycles.
426 */
427 void route_node_to_channels(
428 const std::shared_ptr<Node>& node,
429 const std::vector<uint32_t>& target_channels,
430 uint32_t fade_cycles,
431 ProcessingToken token);
432
433 /**
434 * @brief Routes a network's output to specific channels within a token domain
435 * @param network Network to route (must be an audio sink)
436 * @param target_channels Vector of channel indices to route the network's output to
437 * @param fade_cycles Number of cycles to fade in the routing (optional)
438 * @param token Processing domain to route within
439 *
440 * This method registers the network and adds it to the specified channels' root nodes
441 * within the given processing domain. If fade_cycles is greater than 0, the routing
442 * will be smoothly faded in over that many processing cycles.
443 */
444 void route_network_to_channels(
445 const std::shared_ptr<Network::NodeNetwork>& network,
446 const std::vector<uint32_t>& target_channels,
447 uint32_t fade_cycles,
448 ProcessingToken token);
449
450 /**
451 * @brief Updates routing states for all nodes and networks for a given token
452 * @param token Processing domain to update routing states for
453 *
454 * This method should be called at the end of each processing cycle to update the
455 * routing states of all nodes and networks that are currently undergoing routing changes.
456 * It handles the fade-in/out logic and transitions routing states as needed.
457 */
458 void update_routing_states_for_cycle(ProcessingToken token);
459
460 /**
461 * @brief Cleans up completed routing transitions for a given token
462 * @param token Processing domain to clean up routing for
463 *
464 * This method should be called after routing states have been updated to remove any nodes
465 * or networks that have completed their fade-out transitions and are no longer contributing
466 * to the output of their previous channels.
467 */
468 void cleanup_completed_routing(ProcessingToken token);
469
470 /**
471 * @brief Sets the node configuration for this manager
472 * @param config The NodeConfig to set
473 */
474 void set_node_config(const NodeConfig& config) { m_node_config = config; }
475
476 /**
477 * @brief Gets the current node configuration
478 * @return Reference to the current NodeConfig
479 */
480 NodeConfig& get_node_config() { return m_node_config; }
481 const NodeConfig& get_node_config() const { return m_node_config; }
482
483private:
484 /**
485 * @brief Map of channel indices to their root nodes (AUDIO_RATE domain)
486 *
487 * Each audio channel has its own root node that collects all nodes
488 * that should output to that channel. For multi-modal support,
489 * see m_token_roots.
490 */
491 std::unordered_map<unsigned int, std::shared_ptr<RootNode>> m_channel_root_nodes;
492
493 /**
494 * @brief Registry of all nodes by their string identifiers
495 *
496 * This registry allows nodes to be looked up by their string identifiers
497 * for operations like connecting nodes by name.
498 */
499 std::unordered_map<std::string, std::shared_ptr<Node>> m_Node_registry;
500
501 /**
502 * @brief Multi-modal map of processing tokens to their channel root nodes
503 *
504 * Each processing domain (token) can have multiple channels, each with its own RootNode.
505 * Enables support for audio, visual, and custom processing domains.
506 */
507 std::unordered_map<ProcessingToken,
508 std::unordered_map<unsigned int, std::shared_ptr<RootNode>>>
510
511 /**
512 * @brief Registered custom processors for each processing token
513 *
514 * Maps each processing domain (token) to a custom processing function that
515 * receives a span of all root nodes for that domain. Enables efficient
516 * backend-specific or multi-channel processing.
517 */
518 std::unordered_map<ProcessingToken,
519 std::function<void(std::span<RootNode*>)>>
521
522 /**
523 * @brief Per-channel processors for each processing token
524 *
525 * Maps each processing domain to a per-channel processing function that
526 * processes a single root node and returns processed data. This enables
527 * fine-grained processing with data extraction capabilities.
528 */
529 std::unordered_map<ProcessingToken, TokenChannelProcessor> m_token_channel_processors;
530
531 /**
532 * @brief Per-sample processors for each processing token
533 *
534 * Maps each processing domain to a per-sample processing function that
535 * processes a single sample and returns the processed value. This is useful
536 * for low-level sample manipulation and custom processing.
537 */
538 std::unordered_map<ProcessingToken, TokenSampleProcessor> m_token_sample_processors;
539
540 /**
541 * @brief Global network registry (like m_Node_registry)
542 *
543 * Maps generated IDs to networks for lifecycle management
544 */
545 std::unordered_map<std::string, std::shared_ptr<Network::NodeNetwork>> m_network_registry;
546
547 /**
548 * @brief Audio-sink networks
549 * Only populated for networks with OutputMode::AUDIO_SINK
550 */
551 std::unordered_map<ProcessingToken,
552 std::vector<std::shared_ptr<Network::NodeNetwork>>>
554
555 /**
556 * @brief Non-audio networks (token-level processing)
557 * For NONE, GRAPHICS_BIND, CUSTOM output modes
558 */
559 std::unordered_map<ProcessingToken, std::vector<std::shared_ptr<Network::NodeNetwork>>>
561
562 /**
563 * @brief Processing flags for each token's networks
564 *
565 * Used to prevent re-entrant processing of networks within the same cycle.
566 */
567 std::unordered_map<ProcessingToken, std::unique_ptr<std::atomic<bool>>> m_token_network_processing;
568
569 std::atomic<bool> m_terminate_requested { false }; ///< Global termination flag
570
571 uint32_t m_registered_sample_rate { 48000 }; ///< Sample rate for audio processing, used for normalization
572
573 uint32_t m_registered_block_size { 512 }; ///< Block size for audio processing, used for normalizationbuffer
574
575 NodeConfig m_node_config; ///< Configuration for node creation and management
576
577 /**
578 * @brief Ensures a root node exists for the given token and channel
579 * @param token Processing domain
580 * @param channel Channel index
581 *
582 * Creates and registers a new root node if one does not already exist.
583 */
584 void ensure_root_exists(ProcessingToken token, unsigned int channel);
585
586 /**
587 * @brief Ensures that a processing token entry exists
588 * @param token Processing domain
589 * @param num_channels Number of channels to initialize (default: 1)
590 *
591 * Creates the necessary data structures for the given processing token
592 * if they do not already exist.
593 */
594 void ensure_token_exists(ProcessingToken token, uint32_t num_channels = 1);
595
596 /**
597 * @brief Registers a node globally if not already registered
598 * @param node Node to register
599 *
600 * Assigns a generated identifier if needed and adds the node to the registry.
601 */
602 void register_global(const std::shared_ptr<Node>& node);
603
604 /**
605 * @brief Adds the specified channel mask to a node's global registration
606 * @param node Node to modify
607 * @param channel_id Channel mask to set
608 */
609 void set_channel_mask(const std::shared_ptr<Node>& node, uint32_t channel_id);
610
611 /**
612 * @brief Unsets the specified channel mask from a node's global registration
613 * @param node Node to modify
614 * @param channel_id Channel mask to unset
615 *
616 * Removes the specified channel mask from the node's global registration.
617 */
618 void unset_channel_mask(const std::shared_ptr<Node>& node, uint32_t channel_id);
619
620 /**
621 * @brief Unregisters a node globally
622 * @param node Node to unregister
623 *
624 * Removes the node from the global registry and cleans up any references.
625 */
626 void unregister_global(const std::shared_ptr<Node>& node);
627
628 /**
629 * @brief Normalizes a sample to the range [-1, 1] based on the number of nodes
630 * @param sample Reference to the sample value to normalize
631 * @param num_nodes Number of nodes in the processing chain
632 *
633 * Ensures that the sample value is within the valid range for audio processing.
634 */
635 void normalize_sample(double& sample, uint32_t num_nodes);
636
637 /**
638 * @brief Check if network is registered globally
639 */
640 bool is_network_registered(const std::shared_ptr<Network::NodeNetwork>& network);
641
642 /**
643 * @brief Resets the processing state of audio networks for a token and channel
644 * @param token Processing domain
645 * @param channel Channel index
646 */
647 void reset_audio_network_state(ProcessingToken token, uint32_t channel = 0);
648
649 /**
650 * @brief Preprocess networks for a specific token
651 * @param token Processing domain
652 * @return true if preprocessing succeeded, false otherwise
653 */
654 bool preprocess_networks(ProcessingToken token);
655
656 /**
657 * @brief Postprocess networks for a specific token and channel
658 * @param token Processing domain
659 * @param channel Channel index
660 */
661 void postprocess_networks(ProcessingToken token, std::optional<uint32_t> channel);
662};
663
664}
void set_node_config(const NodeConfig &config)
Sets the node configuration for this manager.
NodeGraphManager(NodeGraphManager &&)=delete
std::unordered_map< unsigned int, std::shared_ptr< RootNode > > m_channel_root_nodes
Map of channel indices to their root nodes (AUDIO_RATE domain)
std::unordered_map< ProcessingToken, std::vector< std::shared_ptr< Network::NodeNetwork > > > m_token_networks
Non-audio networks (token-level processing) For NONE, GRAPHICS_BIND, CUSTOM output modes.
void add_to_root(const std::string &node_id, ProcessingToken token=ProcessingToken::AUDIO_RATE, unsigned int channel=0)
Adds a node to a channel's root node by its identifier.
std::unordered_map< ProcessingToken, std::function< void(std::span< RootNode * >)> > m_token_processors
Registered custom processors for each processing token.
std::unordered_map< std::string, std::shared_ptr< Network::NodeNetwork > > m_network_registry
Global network registry (like m_Node_registry)
const NodeConfig & get_node_config() const
NodeGraphManager & operator=(const NodeGraphManager &)=delete
std::shared_ptr< NodeType > create_node(const std::string &id, Args &&... args)
Creates and registers a new node of the specified type.
std::unordered_map< ProcessingToken, TokenSampleProcessor > m_token_sample_processors
Per-sample processors for each processing token.
std::unordered_map< std::string, std::shared_ptr< Node > > m_Node_registry
Registry of all nodes by their string identifiers.
NodeGraphManager(const NodeGraphManager &)=delete
std::unordered_map< ProcessingToken, std::unordered_map< unsigned int, std::shared_ptr< RootNode > > > m_token_roots
Multi-modal map of processing tokens to their channel root nodes.
std::unordered_map< ProcessingToken, std::vector< std::shared_ptr< Network::NodeNetwork > > > m_audio_networks
Audio-sink networks Only populated for networks with OutputMode::AUDIO_SINK.
NodeGraphManager & operator=(NodeGraphManager &&)=delete
NodeConfig m_node_config
Configuration for node creation and management.
std::unordered_map< ProcessingToken, TokenChannelProcessor > m_token_channel_processors
Per-channel processors for each processing token.
std::unordered_map< ProcessingToken, std::unique_ptr< std::atomic< bool > > > m_token_network_processing
Processing flags for each token's networks.
NodeConfig & get_node_config()
Gets the current node configuration.
Central manager for the computational processing node graph.
Container for top-level nodes in a processing channel with multi-modal support.
Definition RootNode.hpp:29
ProcessingToken
Enumerates the different processing domains for nodes.
std::function< double(RootNode *, uint32_t)> TokenSampleProcessor
std::function< std::vector< double >(RootNode *, uint32_t)> TokenChannelProcessor
Contains the node-based computational processing system components.
Definition Chronie.hpp:11
Configuration settings for individual audio nodes.
Definition NodeSpec.hpp:29