From dc2be7f6889fdc44a9059a068ee54a954d4083d0 Mon Sep 17 00:00:00 2001 From: shadowcat Date: Mon, 15 Dec 2025 16:25:12 -0500 Subject: [PATCH] refactor out typemap --- core/src/event/manager.rs | 20 +++----------- core/src/util/mod.rs | 6 +++-- core/src/util/typemap.rs | 56 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 core/src/util/typemap.rs diff --git a/core/src/event/manager.rs b/core/src/event/manager.rs index aa98b23..5cc37e9 100644 --- a/core/src/event/manager.rs +++ b/core/src/event/manager.rs @@ -1,25 +1,17 @@ use crate::{ ActiveData, Event, EventCtx, EventFn, EventLike, IdLike, LayerId, Ui, WidgetData, WidgetId, - util::HashMap, -}; -use std::{ - any::{Any, TypeId}, - rc::Rc, + util::{HashMap, TypeMap}, }; +use std::{any::TypeId, rc::Rc}; #[derive(Default)] pub struct EventManager { - types: HashMap>, + types: TypeMap, } impl EventManager { pub fn get_type(&mut self) -> &mut TypeEventManager { - self.types - .entry(Self::type_key::()) - .or_insert(Box::new(TypeEventManager::::default())) - .as_any() - .downcast_mut() - .unwrap() + self.types.type_or_default() } pub fn register( @@ -58,7 +50,6 @@ pub trait EventManagerLike { fn remove(&mut self, id: WidgetId); fn draw(&mut self, data: &ActiveData); fn undraw(&mut self, data: &ActiveData); - fn as_any(&mut self) -> &mut dyn Any; } type EventData = (E, Rc EventFn::Data<'a>>>); @@ -87,9 +78,6 @@ impl EventManagerLike for TypeEventManager { layer.remove(&data.id); } } - fn as_any(&mut self) -> &mut dyn Any { - self - } } impl Default for TypeEventManager { diff --git a/core/src/util/mod.rs b/core/src/util/mod.rs index 014c79c..ec45deb 100644 --- a/core/src/util/mod.rs +++ b/core/src/util/mod.rs @@ -1,19 +1,21 @@ +mod typemap; mod arena; mod borrow; mod change; -mod slot; mod id; mod math; mod refcount; +mod slot; mod vec2; +pub use typemap::*; pub use arena::*; pub use borrow::*; pub use change::*; -pub use slot::*; pub use id::*; pub use math::*; pub use refcount::*; +pub use slot::*; pub use vec2::*; pub type HashMap = fxhash::FxHashMap; diff --git a/core/src/util/typemap.rs b/core/src/util/typemap.rs new file mode 100644 index 0000000..3a24e8b --- /dev/null +++ b/core/src/util/typemap.rs @@ -0,0 +1,56 @@ +use crate::util::HashMap; +use std::{ + any::TypeId, + marker::Unsize, + ops::{Deref, DerefMut}, +}; + +pub struct TypeMap { + map: HashMap>, +} + +impl TypeMap { + pub fn set_type + 'static>(&mut self, val: T) { + self.map + .insert(TypeId::of::(), Box::new(val) as Box); + } + + pub fn type_mut + 'static>(&mut self) -> Option<&mut T> { + Some(Self::convert_mut(self.map.get_mut(&TypeId::of::())?)) + } + + pub fn type_or_default + 'static>(&mut self) -> &mut T { + Self::convert_mut( + self.map + .entry(TypeId::of::()) + .or_insert(Box::new(T::default()) as Box), + ) + } + + fn convert_mut>(entry: &mut Box) -> &mut T { + // allegedly this is just what Any does... + unsafe { &mut *(entry.as_mut() as *mut Trait as *mut T) } + } +} + +impl Deref for TypeMap { + type Target = HashMap>; + + fn deref(&self) -> &Self::Target { + &self.map + } +} + +impl DerefMut for TypeMap { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.map + } +} + +impl Default for TypeMap { + fn default() -> Self { + Self { + map: Default::default(), + } + } +}