use std::os::raw::{c_char, c_void};
use std::ffi::CString;
use std::ptr::null;
use super::{ContextInternal, Context};
use crate::def;
use crate::callbacks::{box_closure_get_capi_ptr, get_su_capi_params, get_su_callback};
use crate::{operation::Operation, volume::Volume, proplist::Proplist};
impl Context {
pub fn remove_sample<F>(&mut self, name: &str, callback: F) -> Operation<dyn FnMut(bool)>
where F: FnMut(bool) + 'static
{
let c_name = CString::new(name.clone()).unwrap();
let cb_data = box_closure_get_capi_ptr::<dyn FnMut(bool)>(Box::new(callback));
let ptr = unsafe { capi::pa_context_remove_sample(self.ptr, c_name.as_ptr(),
Some(super::success_cb_proxy), cb_data) };
assert!(!ptr.is_null());
Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
}
pub fn play_sample(&mut self, name: &str, dev: Option<&str>, volume: Volume,
callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
{
let c_name = CString::new(name.clone()).unwrap();
let c_dev = match dev {
Some(dev) => CString::new(dev.clone()).unwrap(),
None => CString::new("").unwrap(),
};
let p_dev = dev.map_or(null::<c_char>(), |_| c_dev.as_ptr() as *const c_char);
let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
let ptr = unsafe { capi::pa_context_play_sample(self.ptr, c_name.as_ptr(), p_dev, volume.0,
cb_fn, cb_data) };
assert!(!ptr.is_null());
Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
}
pub fn play_sample_with_proplist(&mut self, name: &str, dev: Option<&str>, volume: Volume,
proplist: &Proplist, callback: Option<Box<dyn FnMut(Result<u32, ()>) + 'static>>)
-> Operation<dyn FnMut(Result<u32, ()>)>
{
let c_name = CString::new(name.clone()).unwrap();
let c_dev = match dev {
Some(dev) => CString::new(dev.clone()).unwrap(),
None => CString::new("").unwrap(),
};
let p_dev = dev.map_or(null::<c_char>(), |_| c_dev.as_ptr() as *const c_char);
let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
get_su_capi_params::<_, _>(callback, play_sample_success_cb_proxy);
let ptr = unsafe {
capi::pa_context_play_sample_with_proplist(self.ptr, c_name.as_ptr(), p_dev, volume.0,
proplist.0.ptr, cb_fn, cb_data)
};
assert!(!ptr.is_null());
Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(Result<u32, ()>)>)
}
}
extern "C"
fn play_sample_success_cb_proxy(_: *mut ContextInternal, index: u32, userdata: *mut c_void) {
let index_actual = match index { def::INVALID_INDEX => Err(()), i => Ok(i) };
let _ = std::panic::catch_unwind(|| {
let mut callback = get_su_callback::<dyn FnMut(Result<u32, ()>)>(userdata);
(callback)(index_actual);
});
}