use crate::event::event_name::EventName;
use crate::event::EventHandler;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use wasm_bindgen::JsValue;
#[doc(hidden)]
pub const EVENTS_ID_PROP: &'static str = "__events_id__";
type Events = Rc<RefCell<HashMap<u32, HashMap<EventName, ManagedEvent>>>>;
pub(crate) type EventWrapper = Rc<dyn AsRef<JsValue>>;
#[derive(Clone)]
pub struct EventsByNodeIdx {
events: Events,
events_id_props_prefix: f64,
}
pub enum ManagedEvent {
Delegated(EventHandler),
NonDelegated(EventHandler, EventWrapper),
}
impl ManagedEvent {
fn is_delegated(&self) -> bool {
matches!(self, ManagedEvent::Delegated(_))
}
}
impl EventsByNodeIdx {
pub fn new() -> Self {
EventsByNodeIdx {
events: Rc::new(RefCell::new(Default::default())),
events_id_props_prefix: js_sys::Math::random(),
}
}
pub fn events_id_props_prefix(&self) -> f64 {
self.events_id_props_prefix
}
pub fn insert_managed_event(&self, node_idx: u32, event_name: EventName, event: ManagedEvent) {
assert_eq!(event_name.is_delegated(), event.is_delegated());
self.events
.borrow_mut()
.entry(node_idx)
.or_default()
.insert(event_name, event);
}
pub fn overwrite_event_attrib_fn(
&self,
node_idx: u32,
event_name: &EventName,
event: EventHandler,
) {
let mut events = self.events.borrow_mut();
let func = match events
.entry(node_idx)
.or_default()
.get_mut(event_name)
.unwrap()
{
ManagedEvent::Delegated(func) => func,
ManagedEvent::NonDelegated(func, _) => func,
};
*func = event;
}
pub fn move_events(&mut self, old_node_id: &u32, new_node_id: u32) {
let mut events = self.events.borrow_mut();
if let Some(old_events) = events.remove(old_node_id) {
events.insert(new_node_id, old_events);
}
}
pub fn remove_managed_event(&mut self, node_id: &u32, event_name: &EventName) -> ManagedEvent {
self.events
.borrow_mut()
.get_mut(node_id)
.unwrap()
.remove(event_name)
.unwrap()
}
pub fn get_event_handler(&self, node_id: &u32, event_name: &EventName) -> Option<EventHandler> {
self.events.borrow().get(node_id)?.get(event_name).map(|e| {
let event = match e {
ManagedEvent::Delegated(e) => e,
ManagedEvent::NonDelegated(e, _) => e,
};
event.clone()
})
}
#[doc(hidden)]
pub fn __get_event_wrapper_clone(&self, node_id: &u32, event_name: &EventName) -> EventWrapper {
self.events
.borrow()
.get(node_id)
.unwrap()
.get(event_name)
.map(|e| match e {
ManagedEvent::NonDelegated(_, wrapper) => wrapper.clone(),
_ => panic!(),
})
.unwrap()
}
pub fn remove_event_handler(
&self,
node_id: &u32,
event_name: &EventName,
) -> Option<ManagedEvent> {
self.events
.borrow_mut()
.get_mut(node_id)?
.remove(event_name)
}
pub fn remove_node(&self, node_id: &u32) {
self.events.borrow_mut().remove(node_id);
}
}