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]
anyhow = { version = "1.0.86", features = ["backtrace"] }
destructure_traitobject = "0.3.0"
indexmap = { version = "2.2.6", features = ["rayon"] }
serde = { version = "1.0.203", features = ["derive"] }
paste = "1.0.15"

View file

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

View file

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