mod runloop;
use crate::runloop::{start_notification_loop, Callback};
use coremidi::Client;
use once_cell::sync::OnceCell;
use std::{error::Error, sync::PoisonError};
pub(crate) static DEVICE_UPDATE_TX: OnceCell<Callback> = OnceCell::new();
fn handle_device_updates<T: Fn() + Send + 'static>(
device_update: T,
get_client: bool,
) -> Result<Option<Client>, Box<dyn Error + Send + Sync + 'static>> {
let mut client = None;
let mut current_device_update_tx = DEVICE_UPDATE_TX
.get_or_try_init(|| {
let (callback, maybe_client) = start_notification_loop(get_client)?;
client = maybe_client;
Ok::<_, Box<dyn Error + Send + Sync + 'static>>(callback)
})?
.lock()
.unwrap_or_else(PoisonError::into_inner);
*current_device_update_tx = Some(Box::new(device_update));
Ok(client)
}
pub fn receive_device_updates<T: Fn() + Send + 'static>(
device_update: T,
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
handle_device_updates(device_update, false)?;
Ok(())
}
pub fn get_client_and_receive_device_updates<T: Fn() + Send + 'static>(
device_update: T,
) -> Result<Client, Box<dyn Error + Send + Sync + 'static>> {
handle_device_updates(device_update, true)?.ok_or_else(|| "Client was already initialized".into())
}