macro_rules! listener {
($handler:expr, ($($params: ty)?) $(-> $return:ty)?) => {{
use std::ffi::c_void;
unsafe extern "C" fn shim(data: *mut c_void, event: *mut nappgui_sys::Event) {
let data = data as *mut Box<dyn FnMut($(& $params)?) $(-> $return)?>;
let f = &mut *data;
#[allow(unused)]
let event = crate::core::event::Event::new(event);
$(
let params = event.params::<$params>().unwrap();
)?
#[allow(unused)]
if let Ok(r) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| f($(&(params as $params))?))) {
$( event.result(r as $return); )?
}
}
let cb: Box<dyn FnMut($(& $params)?) $(-> $return)?> = Box::new($handler);
let data: *mut Box<dyn FnMut($(& $params)?) $(-> $return)?> = Box::into_raw(Box::new(cb));
let listener = unsafe { nappgui_sys::listener_imp(data as *mut c_void, Some(shim)) };
listener
}};
}
macro_rules! callback {
(
$(#[$meta:meta])*
$vis:vis $func:ident($($params: ty)?) $(-> $return:ty)? => $c_func:ident
) => {
$(#[$meta])*
$vis fn $func<F>(&self, handler: F)
where
F: FnMut($(& $params)?) $(-> $return)? + 'static,
{
use std::ffi::c_void;
unsafe extern "C" fn shim(data: *mut c_void, event: *mut nappgui_sys::Event) {
let data = data as *mut Box<dyn FnMut($(& $params)?) $(-> $return)?>;
let f = &mut *data;
#[allow(unused)]
let event = crate::core::event::Event::new(event);
$(
let params = event.params::<$params>().unwrap();
)?
#[allow(unused)]
if let Ok(r) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| f($(&(params as $params))?))) {
$( event.result(r as $return); )?
}
}
let cb: Box<dyn FnMut($(& $params)?) $(-> $return)?> = Box::new(handler);
let data: *mut Box<dyn FnMut($(& $params)?) $(-> $return)?> = Box::into_raw(Box::new(cb));
let listener = unsafe { nappgui_sys::listener_imp(data as *mut c_void, Some(shim)) };
unsafe {
$c_func(self.as_ptr(), listener);
}
}
};
(
$(
$(#[$meta:meta])*
$vis:vis $func:ident($($params: ty)?) $(-> $return:ty)? => $c_func:ident
);*$(;)?
) => {
$(
callback!(
$(#[$meta])*
$vis $func($($params)?) $(-> $return)? => $c_func
);
)*
}
}
pub(crate) use callback;
pub(crate) use listener;