refactor out typemap
This commit is contained in:
@@ -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> {
|
||||||
|
|||||||
@@ -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
56
core/src/util/typemap.rs
Normal 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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user