22
33use std:: any:: Any ;
44use std:: cell:: Cell ;
5-
5+ use std :: ops :: ControlFlow ;
66use std:: sync:: atomic:: { AtomicU64 , AtomicU8 , Ordering } ;
77use std:: sync:: Arc ;
88use std:: time:: { Duration , Instant } ;
@@ -105,116 +105,125 @@ impl RenderThread {
105105 }
106106 }
107107
108+ #[ inline( always) ]
108109 fn handle_control_messages ( & mut self ) {
109- let receiver = match & self . receiver {
110- None => return ,
111- Some ( receiver) => receiver,
112- } ;
110+ if self . receiver . is_none ( ) {
111+ return ;
112+ }
113113
114- for msg in receiver. try_iter ( ) {
115- use ControlMessage :: * ;
114+ while let Ok ( msg) = self . receiver . as_ref ( ) . unwrap ( ) . try_recv ( ) {
115+ let result = self . handle_control_message ( msg) ;
116+ if result. is_break ( ) {
117+ return ; // stop processing
118+ }
119+ }
120+ }
116121
117- match msg {
118- RegisterNode {
119- id : node_id,
122+ fn handle_control_message ( & mut self , msg : ControlMessage ) -> ControlFlow < ( ) > {
123+ use ControlMessage :: * ;
124+
125+ match msg {
126+ RegisterNode {
127+ id : node_id,
128+ reclaim_id,
129+ node,
130+ inputs,
131+ outputs,
132+ channel_config,
133+ } => {
134+ self . graph . as_mut ( ) . unwrap ( ) . add_node (
135+ node_id,
120136 reclaim_id,
121137 node,
122138 inputs,
123139 outputs,
124140 channel_config,
125- } => {
126- self . graph . as_mut ( ) . unwrap ( ) . add_node (
127- node_id,
128- reclaim_id,
129- node,
130- inputs,
131- outputs,
132- channel_config,
133- ) ;
134- }
135- ConnectNode {
136- from,
137- to,
138- output,
139- input,
140- } => {
141- self . graph
142- . as_mut ( )
143- . unwrap ( )
144- . add_edge ( ( from, output) , ( to, input) ) ;
145- }
146- DisconnectNode { from, to } => {
147- self . graph . as_mut ( ) . unwrap ( ) . remove_edge ( from, to) ;
148- }
149- DisconnectAll { from } => {
150- self . graph . as_mut ( ) . unwrap ( ) . remove_edges_from ( from) ;
151- }
152- ControlHandleDropped { id } => {
153- self . graph . as_mut ( ) . unwrap ( ) . mark_control_handle_dropped ( id) ;
154- }
155- MarkCycleBreaker { id } => {
156- self . graph . as_mut ( ) . unwrap ( ) . mark_cycle_breaker ( id) ;
157- }
158- CloseAndRecycle { sender } => {
159- self . set_state ( AudioContextState :: Suspended ) ;
160- let _ = sender. send ( self . graph . take ( ) . unwrap ( ) ) ;
161- self . receiver = None ;
162- return ; // no further handling of ctrl msgs
163- }
164- Startup { graph } => {
165- debug_assert ! ( self . graph. is_none( ) ) ;
166- self . graph = Some ( graph) ;
167- self . set_state ( AudioContextState :: Running ) ;
168- }
169- NodeMessage { id, mut msg } => {
170- self . graph . as_mut ( ) . unwrap ( ) . route_message ( id, msg. as_mut ( ) ) ;
171- if let Some ( gc) = self . garbage_collector . as_mut ( ) {
172- gc. push ( msg)
173- }
174- }
175- RunDiagnostics { mut buffer } => {
176- use std:: io:: Write ;
177- writeln ! ( & mut buffer, "{:#?}" , & self ) . ok ( ) ;
178- writeln ! ( & mut buffer, "{:?}" , & self . graph) . ok ( ) ;
179- self . event_sender
180- . try_send ( EventDispatch :: diagnostics ( buffer) )
181- . expect ( "Unable to send diagnostics - channel is full" ) ;
182- }
183- Suspend { notify } => {
184- self . suspended = true ;
185- self . set_state ( AudioContextState :: Suspended ) ;
186- notify. send ( ) ;
187- }
188- Resume { notify } => {
189- self . suspended = false ;
190- self . set_state ( AudioContextState :: Running ) ;
191- notify. send ( ) ;
192- }
193- Close { notify } => {
194- self . suspended = true ;
195- self . set_state ( AudioContextState :: Closed ) ;
196- notify. send ( ) ;
141+ ) ;
142+ }
143+ ConnectNode {
144+ from,
145+ to,
146+ output,
147+ input,
148+ } => {
149+ self . graph
150+ . as_mut ( )
151+ . unwrap ( )
152+ . add_edge ( ( from, output) , ( to, input) ) ;
153+ }
154+ DisconnectNode { from, to } => {
155+ self . graph . as_mut ( ) . unwrap ( ) . remove_edge ( from, to) ;
156+ }
157+ DisconnectAll { from } => {
158+ self . graph . as_mut ( ) . unwrap ( ) . remove_edges_from ( from) ;
159+ }
160+ ControlHandleDropped { id } => {
161+ self . graph . as_mut ( ) . unwrap ( ) . mark_control_handle_dropped ( id) ;
162+ }
163+ MarkCycleBreaker { id } => {
164+ self . graph . as_mut ( ) . unwrap ( ) . mark_cycle_breaker ( id) ;
165+ }
166+ CloseAndRecycle { sender } => {
167+ self . set_state ( AudioContextState :: Suspended ) ;
168+ let _ = sender. send ( self . graph . take ( ) . unwrap ( ) ) ;
169+ self . receiver = None ;
170+ return ControlFlow :: Break ( ( ) ) ; // no further handling of ctrl msgs
171+ }
172+ Startup { graph } => {
173+ debug_assert ! ( self . graph. is_none( ) ) ;
174+ self . graph = Some ( graph) ;
175+ self . set_state ( AudioContextState :: Running ) ;
176+ }
177+ NodeMessage { id, mut msg } => {
178+ self . graph . as_mut ( ) . unwrap ( ) . route_message ( id, msg. as_mut ( ) ) ;
179+ if let Some ( gc) = self . garbage_collector . as_mut ( ) {
180+ gc. push ( msg)
197181 }
182+ }
183+ RunDiagnostics { mut buffer } => {
184+ use std:: io:: Write ;
185+ writeln ! ( & mut buffer, "{:#?}" , & self ) . ok ( ) ;
186+ writeln ! ( & mut buffer, "{:?}" , & self . graph) . ok ( ) ;
187+ self . event_sender
188+ . try_send ( EventDispatch :: diagnostics ( buffer) )
189+ . expect ( "Unable to send diagnostics - channel is full" ) ;
190+ }
191+ Suspend { notify } => {
192+ self . suspended = true ;
193+ self . set_state ( AudioContextState :: Suspended ) ;
194+ notify. send ( ) ;
195+ }
196+ Resume { notify } => {
197+ self . suspended = false ;
198+ self . set_state ( AudioContextState :: Running ) ;
199+ notify. send ( ) ;
200+ }
201+ Close { notify } => {
202+ self . suspended = true ;
203+ self . set_state ( AudioContextState :: Closed ) ;
204+ notify. send ( ) ;
205+ }
198206
199- SetChannelCount { id, count } => {
200- self . graph . as_mut ( ) . unwrap ( ) . set_channel_count ( id, count) ;
201- }
207+ SetChannelCount { id, count } => {
208+ self . graph . as_mut ( ) . unwrap ( ) . set_channel_count ( id, count) ;
209+ }
202210
203- SetChannelCountMode { id, mode } => {
204- self . graph
205- . as_mut ( )
206- . unwrap ( )
207- . set_channel_count_mode ( id, mode) ;
208- }
211+ SetChannelCountMode { id, mode } => {
212+ self . graph
213+ . as_mut ( )
214+ . unwrap ( )
215+ . set_channel_count_mode ( id, mode) ;
216+ }
209217
210- SetChannelInterpretation { id, interpretation } => {
211- self . graph
212- . as_mut ( )
213- . unwrap ( )
214- . set_channel_interpretation ( id, interpretation) ;
215- }
218+ SetChannelInterpretation { id, interpretation } => {
219+ self . graph
220+ . as_mut ( )
221+ . unwrap ( )
222+ . set_channel_interpretation ( id, interpretation) ;
216223 }
217224 }
225+
226+ ControlFlow :: Continue ( ( ) ) // continue handling more messages
218227 }
219228
220229 // Render method of the `OfflineAudioContext::start_rendering_sync`
@@ -240,22 +249,26 @@ impl RenderThread {
240249 let mut buffer = AudioBuffer :: new ( options) ;
241250 let num_frames = ( length + RENDER_QUANTUM_SIZE - 1 ) / RENDER_QUANTUM_SIZE ;
242251
243- // Handle addition/removal of nodes/edges
252+ // Handle initial control messages
244253 self . handle_control_messages ( ) ;
245254
246255 for quantum in 0 ..num_frames {
247256 // Suspend at given times and run callbacks
248257 if suspend_callbacks. first ( ) . map ( |& ( q, _) | q) == Some ( quantum) {
249258 let callback = suspend_callbacks. remove ( 0 ) . 1 ;
250259 ( callback) ( context) ;
251- }
252260
253- // Handle addition/removal of nodes/edges
254- self . handle_control_messages ( ) ;
261+ // Handle any control messages that may have been submitted by the callback
262+ self . handle_control_messages ( ) ;
263+ }
255264
256265 self . render_offline_quantum ( & mut buffer) ;
257266
258- event_loop. handle_pending_events ( ) ;
267+ let events_were_handled = event_loop. handle_pending_events ( ) ;
268+ if events_were_handled {
269+ // Handle any control messages that may have been submitted by the handler
270+ self . handle_control_messages ( ) ;
271+ }
259272 }
260273
261274 buffer
0 commit comments