@@ -89,19 +89,26 @@ impl Node {
89
89
return false ;
90
90
}
91
91
92
- // Drop when the node does not have any inputs and outputs
93
- if !self . has_inputs_connected && self . outgoing_edges . is_empty ( ) {
94
- return true ;
92
+ // When the nodes has no incoming connections:
93
+ if !self . has_inputs_connected {
94
+ // Drop when the processor reports it won't yield output.
95
+ if !tail_time {
96
+ return true ;
97
+ }
98
+
99
+ // Drop when the node does not have any inputs and outputs
100
+ if self . outgoing_edges . is_empty ( ) {
101
+ return true ;
102
+ }
95
103
}
96
104
97
- // Drop when the node does not have any inputs connected,
98
- // and if the processor reports it won't yield output.
99
- if !self . has_inputs_connected && !tail_time {
105
+ // Node has no control handle and does have inputs connected.
106
+ // Drop when the processor when it has no outpus connected and does not have side effects
107
+ if !self . processor . has_side_effects ( ) && self . outgoing_edges . is_empty ( ) {
100
108
return true ;
101
109
}
102
110
103
111
// Otherwise, do not drop the node.
104
- // (Even if it has no outputs connected, it may have side effects)
105
112
false
106
113
}
107
114
@@ -503,31 +510,14 @@ impl Graph {
503
510
504
511
// Nodes are only dropped when they do not have incoming connections.
505
512
// But they may have AudioParams feeding into them, these can de dropped too.
506
- self . nodes . retain ( |id, node| {
507
- let node = node. get_mut ( ) ; // unwrap the RefCell
508
-
513
+ self . nodes . values_mut ( ) . for_each ( |node| {
509
514
// Check if this node was connected to the dropped node. In that case, it is
510
- // either an AudioParam (which can be dropped), or the AudioListener that feeds
511
- // into a PannerNode (which can be disconnected).
512
- let was_connected = {
513
- let outgoing_edges = & mut node. outgoing_edges ;
514
- let prev_len = outgoing_edges. len ( ) ;
515
- outgoing_edges. retain ( |e| e. other_id != * index) ;
516
- outgoing_edges. len ( ) != prev_len
517
- } ;
518
-
519
- // Retain when
520
- // - special node (destination = id 0, listener = id 1), or
521
- // - not connected to this dropped node, or
522
- // - if the control thread still has a handle to it.
523
- let retain = id. 0 < 2 || !was_connected || !node. control_handle_dropped ;
524
-
525
- if !retain {
526
- self . reclaim_id_channel
527
- . push ( node. reclaim_id . take ( ) . unwrap ( ) ) ;
528
- }
529
- retain
530
- } )
515
+ // either an AudioParam or the AudioListener that feeds into a PannerNode.
516
+ // These should be disconnected
517
+ node. get_mut ( )
518
+ . outgoing_edges
519
+ . retain ( |e| e. other_id != * index) ;
520
+ } ) ;
531
521
}
532
522
} ) ;
533
523
@@ -819,7 +809,10 @@ mod tests {
819
809
node_id : std:: cell:: Cell :: new ( AudioNodeId ( 0 ) ) ,
820
810
event_sender : None ,
821
811
} ;
822
- graph. render ( & scope) ;
812
+
813
+ // render twice
814
+ graph. render ( & scope) ; // node is dropped
815
+ graph. render ( & scope) ; // param is dropped
823
816
824
817
// First the regular node should be dropped, then the audioparam
825
818
assert_eq ! ( node_id_consumer. pop( ) . unwrap( ) . 0 , 2 ) ;
@@ -870,6 +863,11 @@ mod tests {
870
863
let signal = Box :: new ( TestNode { tail_time : true } ) ;
871
864
add_node ( & mut graph, 4 , signal) ;
872
865
add_edge ( & mut graph, 4 , 3 ) ;
866
+ // Mark the node as 'detached from the control thread', so it is allowed to drop
867
+ graph
868
+ . nodes
869
+ . get_unchecked_mut ( AudioNodeId ( 4 ) )
870
+ . control_handle_dropped = true ;
873
871
874
872
// Render a single quantum
875
873
let scope = AudioWorkletGlobalScope {
@@ -879,7 +877,10 @@ mod tests {
879
877
node_id : std:: cell:: Cell :: new ( AudioNodeId ( 0 ) ) ,
880
878
event_sender : None ,
881
879
} ;
882
- graph. render ( & scope) ;
880
+
881
+ // render twice
882
+ graph. render ( & scope) ; // node is dropped
883
+ graph. render ( & scope) ; // param is dropped
883
884
884
885
// First the regular node should be dropped, then the audioparam
885
886
assert_eq ! ( node_id_consumer. pop( ) . unwrap( ) . 0 , 2 ) ;
@@ -889,7 +890,8 @@ mod tests {
889
890
assert ! ( node_id_consumer. pop( ) . is_none( ) ) ;
890
891
891
892
// Render again
892
- graph. render ( & scope) ;
893
+ graph. render ( & scope) ; // param signal source is dropped
894
+ assert_eq ! ( node_id_consumer. pop( ) . unwrap( ) . 0 , 4 ) ;
893
895
}
894
896
895
897
#[ test]
0 commit comments