use crate::{ ActiveData, Event, EventCtx, EventFn, EventIdCtx, EventLike, HasEvents, IdLike, LayerId, WeakWidget, WidgetEventFn, WidgetId, 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: I, event: E, f: impl for<'a> WidgetEventFn::Data<'a>, I::Widget>, ) { let i = id.id(); self.get_type::().register(id, event, f); self.widget_to_types .entry(i) .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 EventFn::Data<'a>>>); pub struct TypeEventManager { // TODO: reduce visiblity!! pub active: HashMap>, pub global: E::Global, 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(), global: Default::default(), map: Default::default(), } } } impl TypeEventManager { fn register( &mut self, widget: I, event: impl EventLike, f: impl for<'a> WidgetEventFn, I::Widget>, ) { let event = event.into_event(); self.map.entry(widget.id()).or_default().push(( event, Rc::new(move |ctx, rsc| { f( EventIdCtx { widget: WeakWidget::new(widget.id()), state: ctx.state, data: ctx.data, }, rsc, ); }), )); } pub fn run_fn<'a>( &mut self, id: impl IdLike, ) -> impl for<'b> FnOnce(EventCtx<'_, Rsc, E::Data<'b>>, &mut Rsc) -> bool + 'a { let fs = self.map.get(&id.id()).cloned().unwrap_or_default(); move |ctx, rsc| { let mut consumed = false; for (e, f) in fs { if let Some(data) = e.should_run(&ctx.data) { consumed |= e.consumes(&data); f( EventCtx { state: ctx.state, data, }, rsc, ) } } consumed } } }