Start using disjoint_mut and up casting

This commit is contained in:
hodasemi 2025-04-03 18:36:48 +02:00
parent c9009f45d6
commit 0e5f8202b0
3 changed files with 62 additions and 25 deletions

View file

@ -5,7 +5,6 @@ members = ["ecs", "scene_update_macros"]
[workspace.dependencies] [workspace.dependencies]
anyhow = { version = "1.0.86", features = ["backtrace"] } anyhow = { version = "1.0.86", features = ["backtrace"] }
destructure_traitobject = "0.3.0"
indexmap = { version = "2.2.6", features = ["rayon"] } indexmap = { version = "2.2.6", features = ["rayon"] }
serde = { version = "1.0.203", features = ["derive"] } serde = { version = "1.0.203", features = ["derive"] }
paste = "1.0.15" paste = "1.0.15"

View file

@ -6,7 +6,6 @@ edition = "2024"
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
destructure_traitobject.workspace = true
indexmap.workspace = true indexmap.workspace = true
serde.workspace = true serde.workspace = true
paste.workspace = true paste.workspace = true

View file

@ -9,7 +9,6 @@ use std::{
}; };
use anyhow::Result; use anyhow::Result;
use destructure_traitobject;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::World; use crate::World;
@ -26,6 +25,16 @@ pub trait EntityComponent: Any + Send + Sync {
fn name(&self) -> &str; fn name(&self) -> &str;
} }
impl dyn EntityComponent {
pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
(self as &dyn Any).downcast_ref()
}
pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
(self as &mut dyn Any).downcast_mut()
}
}
pub trait ComponentDebug { pub trait ComponentDebug {
fn debug_name() -> &'static str; fn debug_name() -> &'static str;
} }
@ -88,7 +97,7 @@ impl TypeMap {
) -> std::result::Result<&T, ComponentNotFoundError> { ) -> std::result::Result<&T, ComponentNotFoundError> {
self.map self.map
.get(&TypeId::of::<T>()) .get(&TypeId::of::<T>())
.map(|any| Self::downcast_ref_unchecked(any)) .map(|any| any.downcast_ref().unwrap())
.ok_or_else(ComponentNotFoundError::component::<T>) .ok_or_else(ComponentNotFoundError::component::<T>)
} }
@ -106,7 +115,7 @@ impl TypeMap {
) -> std::result::Result<&mut T, ComponentNotFoundError> { ) -> std::result::Result<&mut T, ComponentNotFoundError> {
self.map self.map
.get_mut(&TypeId::of::<T>()) .get_mut(&TypeId::of::<T>())
.map(|any| Self::downcast_mut_unchecked(any)) .map(|any| any.downcast_mut().unwrap())
.ok_or_else(ComponentNotFoundError::component::<T>) .ok_or_else(ComponentNotFoundError::component::<T>)
} }
@ -139,29 +148,59 @@ impl TypeMap {
self.map.iter_mut() self.map.iter_mut()
} }
fn downcast_unchecked<T: EntityComponent>(boxed: Box<dyn EntityComponent>) -> Box<T> { // fn downcast_unchecked<T: EntityComponent>(boxed: Box<dyn EntityComponent>) -> Box<T> {
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) } // unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) }
// }
// pub fn downcast_ref_unchecked<T: EntityComponent>(boxed_ref: &Box<dyn EntityComponent>) -> &T {
// unsafe {
// let ptr_to_ptr: *const *const T =
// transmute(destructure_traitobject::data(boxed_ref as *const _));
// &**ptr_to_ptr
// }
// }
// pub fn downcast_mut_unchecked<T: EntityComponent>(
// boxed_ref: &mut Box<dyn EntityComponent>,
// ) -> &mut T {
// unsafe {
// let ptr_to_ptr: *mut *mut T =
// transmute(destructure_traitobject::data(boxed_ref as *mut _));
// &mut **ptr_to_ptr
// }
// }
} }
pub fn downcast_ref_unchecked<T: EntityComponent>(boxed_ref: &Box<dyn EntityComponent>) -> &T { pub trait GetTypeMap<T> {
unsafe { fn get_mut(&mut self) -> std::result::Result<&mut T, ComponentNotFoundError>;
let ptr_to_ptr: *const *const T = }
transmute(destructure_traitobject::data(boxed_ref as *const _));
&**ptr_to_ptr impl<T> GetTypeMap<T> for TypeMap
where
T: EntityComponent + ComponentDebug,
{
fn get_mut(&mut self) -> std::result::Result<&mut T, ComponentNotFoundError> {
self.map
.get_mut(&TypeId::of::<T>())
.map(|any| any.downcast_mut().unwrap())
.ok_or_else(ComponentNotFoundError::component::<T>)
} }
} }
pub fn downcast_mut_unchecked<T: EntityComponent>( macro_rules! impl_get_type_map {
boxed_ref: &mut Box<dyn EntityComponent>, ([$(t:ident,)+]) => {
) -> &mut T { impl<($(t,)+)> GetTypeMap<$(t,)+> for TypeMap {
unsafe { fn get_mut(&mut self) -> std::result::Result<($(&mut t,)+), ComponentNotFoundError> {
let ptr_to_ptr: *mut *mut T = self.map
transmute(destructure_traitobject::data(boxed_ref as *mut _)); .get_disjoint_mut(
[$(&TypeId::of::<t>(),)])
&mut **ptr_to_ptr .map(|any| any.downcast_mut().unwrap())
.ok_or_else(ComponentNotFoundError::component::<T>)
} }
} }
};
} }
/// Allows mutable access to multiple components at once /// Allows mutable access to multiple components at once