Replace contexts with resources
- Implements a new macro to generate code for a new structure: TypeMap - TypeMaps are wrappers for HashMaps that use TypeIDs as keys. - Refactor the entire codebase to use the new resource structures. - This commit is the first step towards getting rid of "god context objects everywhere".
This commit is contained in:
parent
6e42d94b44
commit
ef055a1bda
16 changed files with 287 additions and 93 deletions
44
core/src/utils/managers.rs
Normal file
44
core/src/utils/managers.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/// Unused as of now.
|
||||
#[macro_export]
|
||||
macro_rules! create_manager {
|
||||
($manager_name:ident, $trait_name:ident) => {
|
||||
pub struct $manager_name {
|
||||
systems: ::indexmap::IndexMap<::std::any::TypeId, Box<dyn $trait_name>>,
|
||||
}
|
||||
|
||||
impl $manager_name {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
systems: ::indexmap::IndexMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add<S: $trait_name + Default + 'static>(&mut self) {
|
||||
self.systems
|
||||
.insert(::std::any::TypeId::of::<S>(), Box::new(S::default()));
|
||||
}
|
||||
|
||||
pub fn remove<S: 'static>(&mut self) {
|
||||
self.systems.shift_remove(&::std::any::TypeId::of::<S>());
|
||||
}
|
||||
|
||||
pub fn for_each_value<F>(&self, mut f: F)
|
||||
where
|
||||
F: FnMut(&dyn $trait_name),
|
||||
{
|
||||
for value in self.systems.values() {
|
||||
f(value.as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn for_each_value_mut<F>(&mut self, mut f: F)
|
||||
where
|
||||
F: FnMut(&mut dyn $trait_name),
|
||||
{
|
||||
for value in self.systems.values_mut() {
|
||||
f(value.as_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
2
core/src/utils/mod.rs
Normal file
2
core/src/utils/mod.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pub mod typemap;
|
||||
mod managers;
|
||||
122
core/src/utils/typemap.rs
Normal file
122
core/src/utils/typemap.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#[macro_export]
|
||||
macro_rules! define_typemap {
|
||||
($name:ident, $($trait_bound:tt)*) => {
|
||||
pub struct $name {
|
||||
map: std::collections::HashMap<std::any::TypeId, Box<dyn std::any::Any>>,
|
||||
}
|
||||
|
||||
impl $name {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
map: std::collections::HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert<T>(&mut self, value: T) -> Option<Box<T>>
|
||||
where
|
||||
T: std::any::Any + 'static + $($trait_bound)*,
|
||||
{
|
||||
let type_id = std::any::TypeId::of::<T>();
|
||||
self.map
|
||||
.insert(type_id, Box::new(value))
|
||||
.and_then(|boxed| boxed.downcast().ok())
|
||||
}
|
||||
|
||||
pub fn get<T>(&self) -> Option<&T>
|
||||
where
|
||||
T: std::any::Any + 'static + $($trait_bound)*,
|
||||
{
|
||||
self.map
|
||||
.get(&std::any::TypeId::of::<T>())
|
||||
.and_then(|any| any.downcast_ref::<T>())
|
||||
}
|
||||
|
||||
pub fn get_mut<T>(&mut self) -> Option<&mut T>
|
||||
where
|
||||
T: std::any::Any + 'static + $($trait_bound)*,
|
||||
{
|
||||
self.map
|
||||
.get_mut(&std::any::TypeId::of::<T>())
|
||||
.and_then(|any| any.downcast_mut::<T>())
|
||||
}
|
||||
|
||||
pub fn remove<T>(&mut self) -> Option<Box<T>>
|
||||
where
|
||||
T: std::any::Any + 'static + $($trait_bound)*,
|
||||
{
|
||||
self.map
|
||||
.remove(&std::any::TypeId::of::<T>())
|
||||
.and_then(|boxed| boxed.downcast().ok())
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.map.is_empty()
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.map.clear();
|
||||
}
|
||||
|
||||
pub fn contains<T>(&self) -> bool
|
||||
where
|
||||
T: std::any::Any + 'static + $($trait_bound)*,
|
||||
{
|
||||
self.map.contains_key(&std::any::TypeId::of::<T>())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for $name {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// pub struct TypeMap {
|
||||
// map: HashMap<TypeId, Box<dyn Any>>,
|
||||
// }
|
||||
//
|
||||
// impl TypeMap {
|
||||
// pub fn new() -> Self {
|
||||
// Self {
|
||||
// map: HashMap::new(),
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// pub fn insert<T: Any + 'static>(&mut self, value: T) -> Option<Box<T>> {
|
||||
// let type_id = TypeId::of::<T>();
|
||||
// self.map
|
||||
// .insert(type_id, Box::new(value))
|
||||
// .and_then(|boxed| boxed.downcast().ok())
|
||||
// }
|
||||
//
|
||||
// pub fn get<T>(&self) -> Option<&T>
|
||||
// where
|
||||
// T: Any + 'static,
|
||||
// {
|
||||
// self.map.get(&TypeId::of::<T>())
|
||||
// .and_then(|any| any.downcast_ref::<T>())
|
||||
// }
|
||||
//
|
||||
// pub fn get_mut<T>(&mut self) -> Option<&mut T>
|
||||
// where
|
||||
// T: Any + 'static,
|
||||
// {
|
||||
// self.map.get_mut(&TypeId::of::<T>()).and_then(|any| any.downcast_mut::<T>())
|
||||
// }
|
||||
//
|
||||
// pub fn remove<T: Any>(&mut self) -> Option<Box<T>> {
|
||||
// unimplemented!()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl Default for TypeMap {
|
||||
// fn default() -> Self {
|
||||
// Self::new()
|
||||
// }
|
||||
// }
|
||||
Loading…
Add table
Add a link
Reference in a new issue