use std::ffi::c_void;
use libxev_sys as sys;
use crate::watcher::{CbAction, Completion, CompletionRef, LoopRef};
type DynCbIsize = dyn FnMut(&mut LoopRef<'_>, &mut CompletionRef<'_>, isize) -> CbAction + Send;
unsafe fn drop_dyn_cb_isize(ptr: *mut ()) {
let _ = unsafe { Box::from_raw(ptr as *mut Box<DynCbIsize>) };
}
pub(crate) unsafe extern "C" fn trampoline_isize(
l: *mut sys::xev_loop,
c: *mut sys::xev_completion,
result: isize,
userdata: *mut c_void,
) -> sys::xev_cb_action {
let cb = unsafe { &mut *(userdata as *mut Box<DynCbIsize>) };
let mut lr = unsafe { LoopRef::from_raw(l) };
let mut cr = unsafe { CompletionRef::from_raw(c) };
cb(&mut lr, &mut cr, result).to_raw()
}
pub trait CompletionExt {
fn install_callback_isize<F>(&mut self, cb: F) -> *mut c_void
where
F: FnMut(&mut LoopRef<'_>, &mut CompletionRef<'_>, isize) -> CbAction + Send + 'static;
}
impl CompletionExt for Completion {
fn install_callback_isize<F>(&mut self, cb: F) -> *mut c_void
where
F: FnMut(&mut LoopRef<'_>, &mut CompletionRef<'_>, isize) -> CbAction + Send + 'static,
{
let inner: Box<DynCbIsize> = Box::new(cb);
let outer: Box<Box<DynCbIsize>> = Box::new(inner);
let ptr = Box::into_raw(outer) as *mut ();
self.set_callback_owner(ptr, drop_dyn_cb_isize);
ptr as *mut c_void
}
}