use crossbeam_channel::{unbounded, Receiver, Sender};
use once_cell::sync::{Lazy, OnceCell};
use crate::MenuId;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MenuEvent {
pub id: MenuId,
}
pub type MenuEventReceiver = Receiver<MenuEvent>;
type MenuEventHandler = Box<dyn Fn(MenuEvent) + Send + Sync + 'static>;
static MENU_CHANNEL: Lazy<(Sender<MenuEvent>, MenuEventReceiver)> = Lazy::new(unbounded);
static MENU_EVENT_HANDLER: OnceCell<Option<MenuEventHandler>> = OnceCell::new();
impl MenuEvent {
pub fn id(&self) -> &MenuId {
&self.id
}
pub fn receiver<'a>() -> &'a MenuEventReceiver {
&MENU_CHANNEL.1
}
pub fn set_event_handler<F: Fn(MenuEvent) + Send + Sync + 'static>(f: Option<F>) {
if let Some(f) = f {
let _ = MENU_EVENT_HANDLER.set(Some(Box::new(f)));
} else {
let _ = MENU_EVENT_HANDLER.set(None);
}
}
pub(crate) fn send(event: MenuEvent) {
if let Some(handler) = MENU_EVENT_HANDLER.get_or_init(|| None) {
handler(event);
} else {
let _ = MENU_CHANNEL.0.send(event);
}
}
}