use crate::{ ActiveData, Event, EventCtx, EventFn, EventIdCtx, EventLike, HasEvents, IdLike, LayerId, Widget, WidgetEventFn, WidgetId, WidgetRef, util::{HashMap, HashSet, TypeMap}, }; use std::{any::TypeId, rc::Rc}; pub struct EventManager { widget_to_types: HashMap>, types: TypeMap>, } impl Default for EventManager { fn default() -> Self { Self { widget_to_types: Default::default(), types: Default::default(), } } } impl EventManager { pub fn get_type(&mut self) -> &mut TypeEventManager { self.types.type_or_default() } pub fn register( &mut self, id: WidgetRef, event: E, f: impl WidgetEventFn::Data, W>, ) { self.get_type::().register(id, event, f); self.widget_to_types .entry(id.id()) .or_default() .insert(Self::type_key::()); } pub fn type_key() -> TypeId { TypeId::of::>() } } pub trait EventsLike { fn remove(&mut self, id: WidgetId); fn draw(&mut self, active: &ActiveData); fn undraw(&mut self, active: &ActiveData); } impl EventsLike for EventManager { fn remove(&mut self, id: WidgetId) { for t in self.widget_to_types.get(&id).into_flat_iter() { self.types.get_mut(t).unwrap().remove(id); } } fn draw(&mut self, active: &ActiveData) { for t in self.widget_to_types.get(&active.id).into_flat_iter() { self.types.get_mut(t).unwrap().draw(active); } } fn undraw(&mut self, active: &ActiveData) { for t in self.widget_to_types.get(&active.id).into_flat_iter() { self.types.get_mut(t).unwrap().undraw(active); } } } pub trait EventManagerLike { fn remove(&mut self, id: WidgetId); fn draw(&mut self, data: &ActiveData); fn undraw(&mut self, data: &ActiveData); } type EventData = (E, Rc::Data>>); pub struct TypeEventManager { // TODO: reduce visiblity!! pub active: HashMap>, map: HashMap>>, } impl EventManagerLike for TypeEventManager { fn remove(&mut self, id: WidgetId) { self.map.remove(&id); for layer in self.active.values_mut() { layer.remove(&id); } } fn draw(&mut self, data: &ActiveData) { self.active .entry(data.layer) .or_default() .entry(data.id) .or_default(); } fn undraw(&mut self, data: &ActiveData) { if let Some(layer) = self.active.get_mut(&data.layer) { layer.remove(&data.id); } } } impl Default for TypeEventManager { fn default() -> Self { Self { active: Default::default(), map: Default::default(), } } } impl TypeEventManager { fn register( &mut self, widget: WidgetRef, event: impl EventLike, f: impl WidgetEventFn, ) { let event = event.into_event(); self.map.entry(widget.id()).or_default().push(( event, Rc::new(move |ctx, rsc| { f( EventIdCtx { widget, state: ctx.state, data: ctx.data, }, rsc, ); }), )); } pub fn run_fn<'a>( &mut self, id: impl IdLike, ) -> impl FnOnce(EventCtx<'_, Rsc, E::Data>, &mut Rsc) + 'a { let fs = self.map.get(&id.id()).cloned().unwrap_or_default(); move |ctx, rsc| { for (e, f) in fs { if let Some(data) = e.should_run(&ctx.data) { f( EventCtx { state: ctx.state, data, }, rsc, ) } } } } }