MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NodeUtils.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "MayaFlux/Utils.hpp"
4
5namespace MayaFlux::Nodes {
6
7class Node;
8class NodeContext;
9
10/**
11 * @typedef NodeHook
12 * @brief Callback function type for node processing events
13 *
14 * A NodeHook is a function that receives a NodeContext object containing
15 * information about the node's current state. These callbacks are triggered
16 * during node processing to notify external components about node activity.
17 *
18 * Example:
19 * ```cpp
20 * node->on_tick([](NodeContext& ctx) {
21 * std::cout << "Node produced value: " << ctx.value << std::endl;
22 * });
23 * ```
24 */
25using NodeHook = std::function<void(NodeContext&)>;
26
27/**
28 * @typedef NodeCondition
29 * @brief Predicate function type for conditional callbacks
30 *
31 * A NodeCondition is a function that evaluates whether a callback should
32 * be triggered based on the node's current state. It receives a NodeContext
33 * object and returns true if the condition is met, false otherwise.
34 *
35 * Example:
36 * ```cpp
37 * node->on_tick_if(
38 * [](NodeContext& ctx) { std::cout << "Threshold exceeded!" << std::endl; },
39 * [](NodeContext& ctx) { return ctx.value > 0.8; }
40 * );
41 * ```
42 */
43using NodeCondition = std::function<bool(NodeContext&)>;
44
45/**
46 * @brief Checks if a callback function already exists in a collection
47 * @param callbacks The collection of callback functions to search
48 * @param callback The callback function to look for
49 * @return True if the callback exists in the collection, false otherwise
50 *
51 * This function compares function pointers to determine if a specific callback
52 * is already registered in a collection. It's used to prevent duplicate
53 * registrations of the same callback function.
54 */
55bool callback_exists(const std::vector<NodeHook>& callbacks, const NodeHook& callback);
56
57/**
58 * @brief Checks if a condition function already exists in a collection of conditional callbacks
59 * @param callbacks The collection of conditional callbacks to search
60 * @param callback The condition function to look for
61 * @return True if the condition exists in the collection, false otherwise
62 *
63 * This function compares function pointers to determine if a specific condition
64 * is already used in a collection of conditional callbacks. It's used to prevent
65 * duplicate registrations of the same condition function.
66 */
67bool conditional_callback_exists(const std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeCondition& callback);
68
69/**
70 * @brief Checks if a specific callback and condition pair already exists
71 * @param callbacks The collection of conditional callbacks to search
72 * @param callback The callback function to look for
73 * @param condition The condition function to look for
74 * @return True if the exact pair exists in the collection, false otherwise
75 *
76 * This function checks if a specific combination of callback and condition
77 * functions is already registered. It's used to prevent duplicate registrations
78 * of the same callback-condition pair.
79 */
80bool callback_pair_exists(const std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeHook& callback, const NodeCondition& condition);
81
82/**
83 * @brief Safely adds a callback to a collection if it doesn't already exist
84 * @param callbacks The collection of callbacks to add to
85 * @param callback The callback function to add
86 * @return True if the callback was added, false if it already existed
87 *
88 * This function first checks if the callback already exists in the collection,
89 * and only adds it if it's not already present. This prevents duplicate
90 * registrations of the same callback function.
91 */
92bool safe_add_callback(std::vector<NodeHook>& callbacks, const NodeHook& callback);
93
94/**
95 * @brief Safely adds a conditional callback if it doesn't already exist
96 * @param callbacks The collection of conditional callbacks to add to
97 * @param callback The callback function to add
98 * @param condition The condition function to add
99 * @return True if the conditional callback was added, false if it already existed
100 *
101 * This function first checks if the exact callback-condition pair already exists
102 * in the collection, and only adds it if it's not already present. This prevents
103 * duplicate registrations of the same conditional callback.
104 */
105bool safe_add_conditional_callback(std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeHook& callback, const NodeCondition& condition);
106
107/**
108 * @brief Safely removes a callback from a collection
109 * @param callbacks The collection of callbacks to remove from
110 * @param callback The callback function to remove
111 * @return True if the callback was found and removed, false otherwise
112 *
113 * This function searches for the specified callback in the collection and
114 * removes it if found. It's used to unregister callbacks when they're no
115 * longer needed.
116 */
117bool safe_remove_callback(std::vector<NodeHook>& callbacks, const NodeHook& callback);
118
119/**
120 * @brief Safely removes all conditional callbacks with a specific condition
121 * @param callbacks The collection of conditional callbacks to remove from
122 * @param callback The condition function to remove
123 * @return True if at least one conditional callback was found and removed, false otherwise
124 *
125 * This function searches for all conditional callbacks that use the specified
126 * condition function and removes them. It's used to unregister conditional
127 * callbacks when they're no longer needed.
128 */
129bool safe_remove_conditional_callback(std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeCondition& callback);
130
131/**
132 * @brief Atomically sets a node state flag with strong memory ordering
133 * @param flag The atomic node state to modify
134 * @param expected The expected current state value
135 * @param desired The desired new state value
136 *
137 * This function safely updates a node's state, ensuring that state transitions
138 * are consistent across the audio processing graph. Node states track important
139 * conditions like whether a node is active, processed, or pending removal,
140 * which are critical for coordinating audio signal flow.
141 */
142void atomic_set_strong(std::atomic<Utils::NodeState>& flag, Utils::NodeState& expected, const Utils::NodeState& desired);
143
144/**
145 * @brief Atomically sets a node state flag to a specific value
146 * @param flag The atomic node state to modify
147 * @param desired The desired new state value
148 *
149 * Forcefully updates a node's state to a specific value. This is used when
150 * the node needs to be placed into a definitive state regardless of its
151 * current condition, such as when activating or deactivating nodes in the
152 * audio processing chain.
153 */
154void atomic_set_flag_strong(std::atomic<Utils::NodeState>& flag, const Utils::NodeState& desired);
155
156/**
157 * @brief Atomically adds a flag to a node state
158 * @param state The atomic node state to modify
159 * @param flag The flag to add to the state
160 *
161 * Adds a specific state flag to a node's state without affecting other state flags.
162 * This is used to mark nodes with specific conditions (like PROCESSED or ACTIVE)
163 * while preserving other aspects of the node's current state.
164 */
165void atomic_add_flag(std::atomic<Utils::NodeState>& state, Utils::NodeState flag);
166
167/**
168 * @brief Atomically removes a flag from a node state
169 * @param state The atomic node state to modify
170 * @param flags The flags to remove from the state
171 *
172 * Removes specific state flags from a node's state. This is commonly used to
173 * clear processing markers after a node has been processed, or to remove
174 * special states like PENDING_REMOVAL when they're no longer applicable.
175 */
176void atomic_remove_flag(std::atomic<Utils::NodeState>& state, Utils::NodeState flags);
177
178/**
179 * @brief Atomically sets a node state flag with weak memory ordering
180 * @param flag The atomic node state to modify
181 * @param expected The expected current state value
182 * @param desired The desired new state value
183 *
184 * A performance-optimized version of state setting that's used in less
185 * critical paths of the audio engine. This helps maintain node state
186 * consistency while potentially improving performance in high-throughput
187 * audio processing scenarios.
188 */
189void atomic_set_flag_weak(std::atomic<Utils::NodeState>& flag, Utils::NodeState& expected, const Utils::NodeState& desired);
190
191/**
192 * @brief Atomically increments the modulator count by a specified amount
193 * @param count The atomic counter to increment
194 * @param amount The amount to increment by
195 *
196 * Increases a node's modulator count, which tracks how many other nodes are
197 * currently using this node as a modulation source. This count is crucial for
198 * determining when a node's processed state can be safely reset, preventing
199 * redundant processing while ensuring all dependent nodes receive the correct
200 * modulation values.
201 */
202void atomic_inc_modulator_count(std::atomic<uint32_t>& count, int amount);
203
204/**
205 * @brief Atomically decrements the modulator count by a specified amount
206 * @param count The atomic counter to decrement
207 * @param amount The amount to decrement by
208 *
209 * Decreases a node's modulator count when it's no longer being used as a
210 * modulation source by another node. When the count reaches zero, the node
211 * becomes eligible for state resets, allowing the audio engine to optimize
212 * processing and avoid redundant calculations in the signal chain.
213 */
214void atomic_dec_modulator_count(std::atomic<uint32_t>& count, int amount);
215
216/**
217 * @brief Attempts to reset the processed state of a node
218 * @param node The node whose processed state should be reset
219 *
220 * Evaluates whether a node's processed state can be safely reset based on its
221 * current modulator count and other conditions. This is essential for the audio
222 * engine's processing cycle, as it determines which nodes need to be recalculated
223 * in the next cycle and which can reuse their previous output values, balancing
224 * processing efficiency with signal accuracy.
225 */
226void try_reset_processed_state(std::shared_ptr<Node> node);
227
228/**
229 * @brief Extracts active channel list from a node's channel mask
230 * @param node Node to inspect (can be null)
231 * @param fallback_channel Channel to use if node has no active channels (default: 0)
232 * @return Vector of active channel indices
233 */
234std::vector<uint32_t> get_active_channels(const std::shared_ptr<Nodes::Node>& node, uint32_t fallback_channel = 0);
235
236/**
237 * @brief Extracts active channel list from a channel mask
238 * @param channel_mask Bitmask of active channels
239 * @param fallback_channel Channel to use if mask is 0 (default: 0)
240 * @return Vector of active channel indices
241 */
242std::vector<uint32_t> get_active_channels(uint32_t channel_mask, uint32_t fallback_channel = 0);
243
244}
Base context class for node callbacks.
Definition Node.hpp:30
std::function< void(NodeContext &)> NodeHook
Callback function type for node processing events.
Definition NodeUtils.hpp:25
bool callback_pair_exists(const std::vector< std::pair< NodeHook, NodeCondition > > &callbacks, const NodeHook &callback, const NodeCondition &condition)
Checks if a specific callback and condition pair already exists.
Definition NodeUtils.cpp:25
bool callback_exists(const std::vector< NodeHook > &callbacks, const NodeHook &callback)
Checks if a callback function already exists in a collection.
Definition NodeUtils.cpp:9
bool safe_remove_conditional_callback(std::vector< std::pair< NodeHook, NodeCondition > > &callbacks, const NodeCondition &callback)
Safely removes all conditional callbacks with a specific condition.
Definition NodeUtils.cpp:68
void atomic_add_flag(std::atomic< Utils::NodeState > &state, Utils::NodeState flag)
Atomically adds a flag to a node state.
Definition NodeUtils.cpp:96
bool safe_add_callback(std::vector< NodeHook > &callbacks, const NodeHook &callback)
Safely adds a callback to a collection if it doesn't already exist.
Definition NodeUtils.cpp:33
void atomic_set_strong(std::atomic< Utils::NodeState > &flag, Utils::NodeState &expected, const Utils::NodeState &desired)
Atomically sets a node state flag with strong memory ordering.
Definition NodeUtils.cpp:85
std::vector< uint32_t > get_active_channels(const std::shared_ptr< Nodes::Node > &node, uint32_t fallback_channel)
Extracts active channel list from a node's channel mask.
bool conditional_callback_exists(const std::vector< std::pair< NodeHook, NodeCondition > > &callbacks, const NodeCondition &callback)
Checks if a condition function already exists in a collection of conditional callbacks.
Definition NodeUtils.cpp:17
void try_reset_processed_state(std::shared_ptr< Node > node)
Attempts to reset the processed state of a node.
void atomic_inc_modulator_count(std::atomic< uint32_t > &count, int amount)
Atomically increments the modulator count by a specified amount.
std::function< bool(NodeContext &)> NodeCondition
Predicate function type for conditional callbacks.
Definition NodeUtils.hpp:43
void atomic_dec_modulator_count(std::atomic< uint32_t > &count, int amount)
Atomically decrements the modulator count by a specified amount.
bool safe_add_conditional_callback(std::vector< std::pair< NodeHook, NodeCondition > > &callbacks, const NodeHook &callback, const NodeCondition &condition)
Safely adds a conditional callback if it doesn't already exist.
Definition NodeUtils.cpp:42
void atomic_set_flag_strong(std::atomic< Utils::NodeState > &flag, const Utils::NodeState &desired)
Atomically sets a node state flag to a specific value.
Definition NodeUtils.cpp:90
void atomic_remove_flag(std::atomic< Utils::NodeState > &state, Utils::NodeState flag)
Atomically removes a flag from a node state.
void atomic_set_flag_weak(std::atomic< Utils::NodeState > &flag, Utils::NodeState &expected, const Utils::NodeState &desired)
Atomically sets a node state flag with weak memory ordering.
bool safe_remove_callback(std::vector< NodeHook > &callbacks, const NodeHook &callback)
Safely removes a callback from a collection.
Definition NodeUtils.cpp:51
Contains the node-based computational processing system components.
Definition Chronie.hpp:5