use std::any::Any; use anyhow::Result; use super::ControllerButton; use crate::prelude::*; macro_rules! callbacks { ($name:ident, $($cb:tt)*) => { #[derive(Default)] pub struct $name<'a> { callbacks: Vec<(&'a str, Box)>, } impl<'a> $name<'a> { pub fn add(mut self, name: &'a str, callback: impl $($cb)* + 'static)->Self { self.callbacks.push((name, Box::new(callback))); self } } impl<'a> Into)>> for $name<'a> { fn into(self) -> Vec<(&'a str, Box)> { self.callbacks } } }; } callbacks!(ClickCallbacks, Fn(&mut GuiHandler) -> Result<()> + Send + Sync); callbacks!(SelectCallbacks, Fn(bool) -> anyhow::Result<()> + Send + Sync); callbacks!(CustomCallbacks, Fn(ControllerButton) -> anyhow::Result + Send + Sync); callbacks!(VecCallbacks, Fn(&dyn Any) -> Result<()> + Send + Sync); #[cfg(test)] mod test { use super::*; use anyhow::Result; fn normal_fn() -> impl Fn(&mut GuiHandler) -> Result<()> + Send + Sync { |_| Ok(()) } #[test] fn test_click_callback_builder() { struct Test; impl Test { fn set_click_callbacks( &self, _callbacks: Vec<( &str, Box Result<()> + Send + Sync>, )>, ) -> Result<()> { Ok(()) } } let t = Test; let cbs = ClickCallbacks::default().add("normal_test", normal_fn()); t.set_click_callbacks(cbs.into()).unwrap(); } }