|
1 | 1 | //! The `OfflineAudioContext` type
|
2 |
| -use std::collections::hash_map::Entry; |
3 |
| -use std::collections::HashMap; |
| 2 | +
|
4 | 3 | use std::sync::atomic::AtomicU64;
|
5 | 4 | use std::sync::{Arc, Mutex};
|
6 | 5 |
|
@@ -33,10 +32,10 @@ pub struct OfflineAudioContext {
|
33 | 32 | struct OfflineAudioContextRenderer {
|
34 | 33 | /// the rendering 'thread', fully controlled by the offline context
|
35 | 34 | renderer: RenderThread,
|
36 |
| - /// promises to resolve at certain render quanta (via `suspend`) |
37 |
| - suspend_promises: HashMap<usize, oneshot::Sender<()>>, |
38 |
| - /// callbacks to run at certain render quanta (via `suspend_sync`) |
39 |
| - suspend_callbacks: HashMap<usize, Box<OfflineAudioContextCallback>>, |
| 35 | + /// sorted list of promises to resolve at certain render quanta (via `suspend`) |
| 36 | + suspend_promises: Vec<(usize, oneshot::Sender<()>)>, |
| 37 | + /// sorted list of callbacks to run at certain render quanta (via `suspend_sync`) |
| 38 | + suspend_callbacks: Vec<(usize, Box<OfflineAudioContextCallback>)>, |
40 | 39 | /// channel to listen for `resume` calls on a suspended context
|
41 | 40 | resume_receiver: futures::channel::mpsc::Receiver<()>,
|
42 | 41 | }
|
@@ -96,8 +95,8 @@ impl OfflineAudioContext {
|
96 | 95 |
|
97 | 96 | let renderer = OfflineAudioContextRenderer {
|
98 | 97 | renderer,
|
99 |
| - suspend_promises: HashMap::new(), |
100 |
| - suspend_callbacks: HashMap::new(), |
| 98 | + suspend_promises: Vec::new(), |
| 99 | + suspend_callbacks: Vec::new(), |
101 | 100 | resume_receiver,
|
102 | 101 | };
|
103 | 102 |
|
@@ -242,13 +241,16 @@ impl OfflineAudioContext {
|
242 | 241 | }
|
243 | 242 | };
|
244 | 243 |
|
245 |
| - match renderer.suspend_promises.entry(quantum) { |
246 |
| - Entry::Occupied(_) => panic!( |
| 244 | + match renderer |
| 245 | + .suspend_promises |
| 246 | + .binary_search_by_key(&quantum, |&(q, _)| q) |
| 247 | + { |
| 248 | + Ok(_) => panic!( |
247 | 249 | "InvalidStateError: cannot suspend multiple times at the same render quantum"
|
248 | 250 | ),
|
249 |
| - Entry::Vacant(e) => { |
250 |
| - e.insert(sender); |
251 |
| - } |
| 251 | + Err(position) => renderer |
| 252 | + .suspend_promises |
| 253 | + .insert(position, (quantum, sender)), |
252 | 254 | }
|
253 | 255 | } // lock is dropped
|
254 | 256 |
|
@@ -304,13 +306,16 @@ impl OfflineAudioContext {
|
304 | 306 | Some(r) => r,
|
305 | 307 | None => panic!("InvalidStateError: cannot suspend when rendering has already started"),
|
306 | 308 | };
|
307 |
| - match renderer.suspend_callbacks.entry(quantum) { |
308 |
| - Entry::Occupied(_) => panic!( |
| 309 | + match renderer |
| 310 | + .suspend_callbacks |
| 311 | + .binary_search_by_key(&quantum, |(q, _c)| *q) |
| 312 | + { |
| 313 | + Ok(_) => panic!( |
309 | 314 | "InvalidStateError: cannot suspend multiple times at the same render quantum"
|
310 | 315 | ),
|
311 |
| - Entry::Vacant(e) => { |
312 |
| - e.insert(Box::new(callback)); |
313 |
| - } |
| 316 | + Err(position) => renderer |
| 317 | + .suspend_callbacks |
| 318 | + .insert(position, (quantum, Box::new(callback))), |
314 | 319 | }
|
315 | 320 | }
|
316 | 321 |
|
|
0 commit comments