Skip to content

Commit bc8c628

Browse files
refactor: disconnect all outputs from a node
1 parent f151efa commit bc8c628

5 files changed

Lines changed: 53 additions & 6 deletions

File tree

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/AudioNodeHostObject.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ JSI_HOST_FUNCTION_IMPL(AudioNodeHostObject, connect) {
6363
auto obj = args[0].getObject(runtime);
6464
if (obj.isHostObject<AudioNodeHostObject>(runtime)) {
6565
auto node = obj.getHostObject<AudioNodeHostObject>(runtime);
66-
connectNode(*node);
66+
connect(*node);
6767
} else if (obj.isHostObject<AudioDestinationNodeHostObject>(runtime)) {
6868
auto dest = obj.getHostObject<AudioDestinationNodeHostObject>(runtime);
6969
graph_->addEdge(node_, dest->rawNode());
@@ -77,15 +77,14 @@ JSI_HOST_FUNCTION_IMPL(AudioNodeHostObject, connect) {
7777

7878
JSI_HOST_FUNCTION_IMPL(AudioNodeHostObject, disconnect) {
7979
if (args[0].isUndefined()) {
80-
// TODO
81-
// node_->disconnect();
80+
disconnect();
8281
return jsi::Value::undefined();
8382
}
8483

8584
auto obj = args[0].getObject(runtime);
8685
if (obj.isHostObject<AudioNodeHostObject>(runtime)) {
8786
auto node = obj.getHostObject<AudioNodeHostObject>(runtime);
88-
disconnectNode(*node);
87+
disconnect(*node);
8988
} else if (obj.isHostObject<AudioDestinationNodeHostObject>(runtime)) {
9089
auto dest = obj.getHostObject<AudioDestinationNodeHostObject>(runtime);
9190
graph_->removeEdge(node_, dest->rawNode());

packages/react-native-audio-api/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class AudioNodeHostObject : public JsiHostObject, public utils::graph::HostNode
2929
JSI_PROPERTY_GETTER_DECL(channelCountMode);
3030
JSI_PROPERTY_GETTER_DECL(channelInterpretation);
3131

32+
using utils::graph::HostNode::connect;
33+
using utils::graph::HostNode::disconnect;
34+
3235
JSI_HOST_FUNCTION_DECL(connect);
3336
JSI_HOST_FUNCTION_DECL(disconnect);
3437

packages/react-native-audio-api/common/cpp/audioapi/core/utils/graph/Graph.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,15 @@ class Graph {
173173
});
174174
}
175175

176+
/// @brief Removes all outgoing edges from `from`.
177+
Res removeAllEdges(HNode *from) {
178+
hostGraph.collectDisposedNodes();
179+
return hostGraph.removeAllEdges(from).map([&](AGEvent event) {
180+
eventSender_.send(std::move(event));
181+
return NoneType{};
182+
});
183+
}
184+
176185
// ── Param bridge API ───────────────────────────────────────────────────
177186

178187
/// @brief Creates a bridge node representing: source → bridge → owner.

packages/react-native-audio-api/common/cpp/audioapi/core/utils/graph/HostGraph.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class HostGraph {
103103
/// @return AGEvent that removes the input on the AudioGraph side.
104104
Res removeEdge(Node *from, Node *to);
105105

106+
/// @brief Removes all outgoing edges from `from`.
107+
/// @return single AGEvent that removes all inputs on the AudioGraph side, or NODE_NOT_FOUND.
108+
Res removeAllEdges(Node *from);
109+
106110
/// @brief Current number of live (non-ghost) edges.
107111
[[nodiscard]] size_t edgeCount() const;
108112

@@ -258,6 +262,32 @@ inline auto HostGraph::removeEdge(Node *from, Node *to) -> Res {
258262
});
259263
}
260264

265+
inline auto HostGraph::removeAllEdges(Node *from) -> Res {
266+
if (std::find(nodes.begin(), nodes.end(), from) == nodes.end() || from->ghost) {
267+
return Res::Err(ResultError::NODE_NOT_FOUND);
268+
}
269+
270+
auto pairs = std::make_shared<std::vector<std::pair<std::uint32_t, std::uint32_t>>>();
271+
pairs->reserve(from->outputs.size());
272+
273+
for (Node *to : from->outputs) {
274+
auto itIn = std::find(to->inputs.begin(), to->inputs.end(), from);
275+
if (itIn != to->inputs.end()) {
276+
to->inputs.erase(itIn);
277+
}
278+
edgeCount_--;
279+
pairs->emplace_back(from->handle->index, to->handle->index);
280+
}
281+
from->outputs.clear();
282+
283+
return Res::Ok([pairs = std::move(pairs)](AudioGraph &graph, auto &) {
284+
for (auto &[fromIdx, toIdx] : *pairs) {
285+
graph.pool().remove(graph[toIdx].input_head, fromIdx);
286+
}
287+
graph.markDirty();
288+
});
289+
}
290+
261291
inline bool HostGraph::hasPath(Node *start, Node *end) {
262292
if (start == end) {
263293
return true;

packages/react-native-audio-api/common/cpp/audioapi/core/utils/graph/HostNode.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ class HostNode {
9393

9494
/// @brief Connects this node's output to another node's input (this → other).
9595
/// @return Ok on success, Err on cycle / duplicate / not-found
96-
Res connectNode(HostNode &other) {
96+
Res connect(HostNode &other) {
9797
return graph_->addEdge(node_, other.node_);
9898
}
9999

100100
/// @brief Disconnects this node's output from another node's input.
101101
/// @return Ok on success, Err on not-found
102-
Res disconnectNode(HostNode &other) {
102+
Res disconnect(HostNode &other) {
103103
return graph_->removeEdge(node_, other.node_);
104104
}
105105

@@ -115,6 +115,12 @@ class HostNode {
115115
return graph_->disconnectParam(node_, owner.node_, param);
116116
}
117117

118+
/// @brief Disconnects all this node's outputs.
119+
/// @return Ok on success, Err on not-found
120+
Res disconnect() {
121+
return graph_->removeAllEdges(node_);
122+
}
123+
118124
/// @brief Returns the raw HostGraph::Node pointer (for advanced usage / testing).
119125
[[nodiscard]] HNode *rawNode() const {
120126
return node_;

0 commit comments

Comments
 (0)