refactor out typemap

This commit is contained in:
2025-12-15 16:25:12 -05:00
parent 9d8ca8fa72
commit dc2be7f688
3 changed files with 64 additions and 18 deletions

View File

@@ -1,25 +1,17 @@
use crate::{ use crate::{
ActiveData, Event, EventCtx, EventFn, EventLike, IdLike, LayerId, Ui, WidgetData, WidgetId, ActiveData, Event, EventCtx, EventFn, EventLike, IdLike, LayerId, Ui, WidgetData, WidgetId,
util::HashMap, util::{HashMap, TypeMap},
};
use std::{
any::{Any, TypeId},
rc::Rc,
}; };
use std::{any::TypeId, rc::Rc};
#[derive(Default)] #[derive(Default)]
pub struct EventManager { pub struct EventManager {
types: HashMap<TypeId, Box<dyn EventManagerLike>>, types: TypeMap<dyn EventManagerLike>,
} }
impl EventManager { impl EventManager {
pub fn get_type<E: EventLike, Ctx: 'static>(&mut self) -> &mut TypeEventManager<E::Event, Ctx> { pub fn get_type<E: EventLike, Ctx: 'static>(&mut self) -> &mut TypeEventManager<E::Event, Ctx> {
self.types self.types.type_or_default()
.entry(Self::type_key::<E, Ctx>())
.or_insert(Box::new(TypeEventManager::<E::Event, Ctx>::default()))
.as_any()
.downcast_mut()
.unwrap()
} }
pub fn register<I: IdLike, E: EventLike, Ctx: 'static>( pub fn register<I: IdLike, E: EventLike, Ctx: 'static>(
@@ -58,7 +50,6 @@ pub trait EventManagerLike {
fn remove(&mut self, id: WidgetId); fn remove(&mut self, id: WidgetId);
fn draw(&mut self, data: &ActiveData); fn draw(&mut self, data: &ActiveData);
fn undraw(&mut self, data: &ActiveData); fn undraw(&mut self, data: &ActiveData);
fn as_any(&mut self) -> &mut dyn Any;
} }
type EventData<E, Ctx> = (E, Rc<dyn for<'a> EventFn<Ctx, <E as Event>::Data<'a>>>); type EventData<E, Ctx> = (E, Rc<dyn for<'a> EventFn<Ctx, <E as Event>::Data<'a>>>);
@@ -87,9 +78,6 @@ impl<E: Event, Ctx: 'static> EventManagerLike for TypeEventManager<E, Ctx> {
layer.remove(&data.id); layer.remove(&data.id);
} }
} }
fn as_any(&mut self) -> &mut dyn Any {
self
}
} }
impl<E: Event, Ctx> Default for TypeEventManager<E, Ctx> { impl<E: Event, Ctx> Default for TypeEventManager<E, Ctx> {

View File

@@ -1,19 +1,21 @@
mod typemap;
mod arena; mod arena;
mod borrow; mod borrow;
mod change; mod change;
mod slot;
mod id; mod id;
mod math; mod math;
mod refcount; mod refcount;
mod slot;
mod vec2; mod vec2;
pub use typemap::*;
pub use arena::*; pub use arena::*;
pub use borrow::*; pub use borrow::*;
pub use change::*; pub use change::*;
pub use slot::*;
pub use id::*; pub use id::*;
pub use math::*; pub use math::*;
pub use refcount::*; pub use refcount::*;
pub use slot::*;
pub use vec2::*; pub use vec2::*;
pub type HashMap<K, V> = fxhash::FxHashMap<K, V>; pub type HashMap<K, V> = fxhash::FxHashMap<K, V>;

56
core/src/util/typemap.rs Normal file
View File

@@ -0,0 +1,56 @@
use crate::util::HashMap;
use std::{
any::TypeId,
marker::Unsize,
ops::{Deref, DerefMut},
};
pub struct TypeMap<Trait: ?Sized> {
map: HashMap<TypeId, Box<Trait>>,
}
impl<Trait: ?Sized> TypeMap<Trait> {
pub fn set_type<T: Unsize<Trait> + 'static>(&mut self, val: T) {
self.map
.insert(TypeId::of::<T>(), Box::new(val) as Box<Trait>);
}
pub fn type_mut<T: Unsize<Trait> + 'static>(&mut self) -> Option<&mut T> {
Some(Self::convert_mut(self.map.get_mut(&TypeId::of::<T>())?))
}
pub fn type_or_default<T: Default + Unsize<Trait> + 'static>(&mut self) -> &mut T {
Self::convert_mut(
self.map
.entry(TypeId::of::<T>())
.or_insert(Box::new(T::default()) as Box<Trait>),
)
}
fn convert_mut<T: Unsize<Trait>>(entry: &mut Box<Trait>) -> &mut T {
// allegedly this is just what Any does...
unsafe { &mut *(entry.as_mut() as *mut Trait as *mut T) }
}
}
impl<T: ?Sized> Deref for TypeMap<T> {
type Target = HashMap<TypeId, Box<T>>;
fn deref(&self) -> &Self::Target {
&self.map
}
}
impl<T: ?Sized> DerefMut for TypeMap<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.map
}
}
impl<T: ?Sized> Default for TypeMap<T> {
fn default() -> Self {
Self {
map: Default::default(),
}
}
}