MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NodeUtils.cpp
Go to the documentation of this file.
1#include "NodeUtils.hpp"
2
3#include "Node.hpp"
4
5namespace MayaFlux::Nodes {
6
7bool callback_exists(const std::vector<NodeHook>& callbacks, const NodeHook& callback)
8{
9 return std::ranges::any_of(callbacks,
10 [&callback](const NodeHook& hook) {
11 return hook.target_type() == callback.target_type();
12 });
13}
14
15bool conditional_callback_exists(const std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeCondition& callback)
16{
17 return std::ranges::any_of(callbacks,
18 [&callback](const std::pair<NodeHook, NodeCondition>& pair) {
19 return pair.second.target_type() == callback.target_type();
20 });
21}
22
23bool callback_pair_exists(const std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeHook& callback, const NodeCondition& condition)
24{
25 return std::ranges::any_of(callbacks,
26 [&callback, &condition](const std::pair<NodeHook, NodeCondition>& pair) {
27 return pair.first.target_type() == callback.target_type() && pair.second.target_type() == condition.target_type();
28 });
29}
30
31bool safe_add_callback(std::vector<NodeHook>& callbacks, const NodeHook& callback)
32{
33 if (!callback_exists(callbacks, callback)) {
34 callbacks.push_back(callback);
35 return true;
36 }
37 return false;
38}
39
40bool safe_add_conditional_callback(std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeHook& callback, const NodeCondition& condition)
41{
42 if (!callback_pair_exists(callbacks, callback, condition)) {
43 callbacks.emplace_back(callback, condition);
44 return true;
45 }
46 return false;
47}
48
49bool safe_remove_callback(std::vector<NodeHook>& callbacks, const NodeHook& callback)
50{
51 bool removed = false;
52 auto it = callbacks.begin();
53
54 while (it != callbacks.end()) {
55 if (it->target_type() == callback.target_type()) {
56 it = callbacks.erase(it);
57 removed = true;
58 } else {
59 ++it;
60 }
61 }
62
63 return removed;
64}
65
66bool safe_remove_conditional_callback(std::vector<std::pair<NodeHook, NodeCondition>>& callbacks, const NodeCondition& callback)
67{
68 bool removed = false;
69 auto it = callbacks.begin();
70
71 while (it != callbacks.end()) {
72 if (it->second.target_type() == callback.target_type()) {
73 it = callbacks.erase(it);
74 removed = true;
75 } else {
76 ++it;
77 }
78 }
79
80 return removed;
81}
82
83void atomic_set_strong(std::atomic<NodeState>& flag, NodeState& expected, const NodeState& desired)
84{
85 flag.compare_exchange_strong(expected, desired);
86};
87
88void atomic_set_flag_strong(std::atomic<NodeState>& flag, const NodeState& desired)
89{
90 auto expected = flag.load();
91 flag.compare_exchange_strong(expected, desired);
92};
93
94void atomic_add_flag(std::atomic<NodeState>& state, NodeState flag)
95{
96 auto current = state.load();
97 NodeState desired;
98 do {
99 desired = static_cast<NodeState>(current | flag);
100 } while (!state.compare_exchange_weak(current, desired,
101 std::memory_order_acq_rel,
102 std::memory_order_acquire));
103}
104
105void atomic_remove_flag(std::atomic<NodeState>& state, NodeState flag)
106{
107 auto current = state.load();
108 NodeState desired;
109 do {
110 desired = static_cast<NodeState>(current & ~flag);
111 } while (!state.compare_exchange_weak(current, desired,
112 std::memory_order_acq_rel,
113 std::memory_order_acquire));
114}
115
116void atomic_set_flag_weak(std::atomic<NodeState>& flag, NodeState& expected, const NodeState& desired)
117{
118 flag.compare_exchange_weak(expected, desired);
119};
120
121void atomic_inc_modulator_count(std::atomic<uint32_t>& count, int amount)
122{
123 count.fetch_add(amount, std::memory_order_relaxed);
124}
125
126void atomic_dec_modulator_count(std::atomic<uint32_t>& count, int amount)
127{
128 count.fetch_sub(amount, std::memory_order_relaxed);
129}
130
131void try_reset_processed_state(std::shared_ptr<Node> node)
132{
133 if (node && node->m_modulator_count.load(std::memory_order_relaxed) == 0) {
134 node->reset_processed_state();
135 }
136}
137
138std::vector<uint32_t> get_active_channels(const std::shared_ptr<Nodes::Node>& node, uint32_t fallback_channel)
139{
140 uint32_t channel_mask = node ? node->get_channel_mask().load() : 0;
141 return get_active_channels(channel_mask, fallback_channel);
142}
143
144std::vector<uint32_t> get_active_channels(uint32_t channel_mask, uint32_t fallback_channel)
145{
146 std::vector<uint32_t> channels;
147
148 if (channel_mask == 0) {
149 channels.push_back(fallback_channel);
150 } else {
151 for (uint32_t channel = 0; channel < MAX_CHANNEL_COUNT; ++channel) {
152 if (channel_mask & (1ULL << channel)) {
153 channels.push_back(channel);
154 }
155 }
156 }
157
158 return channels;
159}
160
162{
163 state.cycles_elapsed++;
164
165 double progress = 0.;
166 if (state.fade_cycles > 0) {
167 progress = std::min<double>(1.0, static_cast<double>(state.cycles_elapsed) / state.fade_cycles);
168 } else {
169 for (uint32_t ch = 0; ch < 32; ++ch) {
170 bool will_be_in = state.to_channels & (1 << ch);
171 state.amount[ch] = will_be_in ? 1.0 : 0.0;
172 }
173 state.phase = RoutingState::NONE;
174 return;
175 }
176
177 for (uint32_t ch = 0; ch < 32; ch++) {
178 bool was_in = state.from_channels & (1 << ch);
179 bool will_be_in = state.to_channels & (1 << ch);
180
181 if (was_in && will_be_in) {
182 state.amount[ch] = 1.0;
183 } else if (was_in && !will_be_in) {
184 state.amount[ch] = 1.0 - progress;
185 } else if (!was_in && will_be_in) {
186 state.amount[ch] = progress;
187 } else {
188 state.amount[ch] = 0.0;
189 }
190 }
191
192 if (state.cycles_elapsed >= state.fade_cycles) {
193 state.phase = RoutingState::COMPLETED;
194 }
195}
196
197}
Eigen::Index count
std::function< void(NodeContext &)> NodeHook
Callback function type for node processing events.
Definition NodeUtils.hpp:25
NodeState
Represents the processing state of a node in the audio graph.
Definition NodeSpec.hpp:43
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:23
void atomic_add_flag(std::atomic< NodeState > &state, NodeState flag)
Atomically adds a flag to a node state.
Definition NodeUtils.cpp:94
bool callback_exists(const std::vector< NodeHook > &callbacks, const NodeHook &callback)
Checks if a callback function already exists in a collection.
Definition NodeUtils.cpp:7
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:66
constexpr uint32_t MAX_CHANNEL_COUNT
Hard limit imposed by uint32_t channel mask width.
Definition NodeSpec.hpp:5
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:31
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.
void atomic_set_strong(std::atomic< NodeState > &flag, NodeState &expected, const NodeState &desired)
Atomically sets a node state flag with strong memory ordering.
Definition NodeUtils.cpp:83
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:15
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.
void atomic_remove_flag(std::atomic< NodeState > &state, NodeState flag)
Atomically removes a flag from a node state.
void atomic_set_flag_strong(std::atomic< NodeState > &flag, const NodeState &desired)
Atomically sets a node state flag to a specific value.
Definition NodeUtils.cpp:88
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:40
void atomic_set_flag_weak(std::atomic< NodeState > &flag, NodeState &expected, const NodeState &desired)
Atomically sets a node state flag with weak memory ordering.
void update_routing_state(RoutingState &state)
Updates the routing state for a node based on its current channel usage.
bool safe_remove_callback(std::vector< NodeHook > &callbacks, const NodeHook &callback)
Safely removes a callback from a collection.
Definition NodeUtils.cpp:49
Contains the node-based computational processing system components.
Definition Chronie.hpp:11
enum MayaFlux::Nodes::RoutingState::Phase NONE
@ COMPLETED
Routing transition has completed.
Definition NodeSpec.hpp:82
Represents the state of routing transitions for a node.
Definition NodeSpec.hpp:64