refactor out typemap
This commit is contained in:
1 parent
9d8ca8fa72
commit
dc2be7f688
3 files changed
+64
-18
No files matched your search
@@ -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<K, V> = fxhash::FxHashMap<K, V>;
|
||||
|
||||
@@ -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