use firewheel::{FirewheelConfig, FirewheelContext};
use std::sync::mpsc;
use super::{AudioThreadState, LocalStore};
#[derive(Debug)]
pub struct InnerContext(mpsc::Sender<ThreadLocalCall>);
type ThreadLocalCall = Box<dyn FnOnce(&mut AudioThreadState) + Send + 'static>;
impl InnerContext {
#[inline(always)]
pub fn new(settings: FirewheelConfig) -> Self {
let (bev_to_audio_tx, bev_to_audio_rx) = mpsc::channel::<ThreadLocalCall>();
std::thread::spawn(move || {
let mut state = AudioThreadState::new(settings);
while let Ok(func) = bev_to_audio_rx.recv() {
(func)(&mut state);
}
});
InnerContext(bev_to_audio_tx)
}
#[inline(always)]
pub fn with_store<F, O>(&mut self, f: F) -> O
where
F: FnOnce(&mut FirewheelContext, &mut LocalStore) -> O + Send,
O: Send + 'static,
{
let (send, receive) = mpsc::sync_channel(1);
let func: Box<dyn FnOnce(&mut AudioThreadState) + Send> = Box::new(move |state| {
let AudioThreadState { context, store } = state;
let result = f(context, store);
send.send(result).unwrap();
});
let func = unsafe {
core::mem::transmute::<
Box<dyn FnOnce(&mut AudioThreadState) + Send>,
Box<dyn FnOnce(&mut AudioThreadState) + Send + 'static>,
>(func)
};
self.0.send(func).unwrap();
receive.recv().unwrap()
}
}