From 0e5f8202b0c930331a2e0ca78f9d6e48d9e5b11c Mon Sep 17 00:00:00 2001 From: hodasemi Date: Thu, 3 Apr 2025 18:36:48 +0200 Subject: [PATCH] Start using disjoint_mut and up casting --- Cargo.toml | 1 - ecs/Cargo.toml | 1 - ecs/src/type_map.rs | 85 +++++++++++++++++++++++++++++++++------------ 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0b812cd..ad5496b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/ecs/Cargo.toml b/ecs/Cargo.toml index 340face..2e54ab9 100644 --- a/ecs/Cargo.toml +++ b/ecs/Cargo.toml @@ -6,7 +6,6 @@ edition = "2024" [dependencies] anyhow.workspace = true -destructure_traitobject.workspace = true indexmap.workspace = true serde.workspace = true paste.workspace = true diff --git a/ecs/src/type_map.rs b/ecs/src/type_map.rs index 3dfb1a1..9d85cdc 100644 --- a/ecs/src/type_map.rs +++ b/ecs/src/type_map.rs @@ -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(&self) -> Option<&T> { + (self as &dyn Any).downcast_ref() + } + + pub fn downcast_mut(&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::()) - .map(|any| Self::downcast_ref_unchecked(any)) + .map(|any| any.downcast_ref().unwrap()) .ok_or_else(ComponentNotFoundError::component::) } @@ -106,7 +115,7 @@ impl TypeMap { ) -> std::result::Result<&mut T, ComponentNotFoundError> { self.map .get_mut(&TypeId::of::()) - .map(|any| Self::downcast_mut_unchecked(any)) + .map(|any| any.downcast_mut().unwrap()) .ok_or_else(ComponentNotFoundError::component::) } @@ -139,29 +148,59 @@ impl TypeMap { self.map.iter_mut() } - fn downcast_unchecked(boxed: Box) -> Box { - unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) } + // fn downcast_unchecked(boxed: Box) -> Box { + // unsafe { Box::from_raw(Box::into_raw(boxed) as *mut T) } + // } + + // pub fn downcast_ref_unchecked(boxed_ref: &Box) -> &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( + // boxed_ref: &mut Box, + // ) -> &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 { + fn get_mut(&mut self) -> std::result::Result<&mut T, ComponentNotFoundError>; +} + +impl GetTypeMap for TypeMap +where + T: EntityComponent + ComponentDebug, +{ + fn get_mut(&mut self) -> std::result::Result<&mut T, ComponentNotFoundError> { + self.map + .get_mut(&TypeId::of::()) + .map(|any| any.downcast_mut().unwrap()) + .ok_or_else(ComponentNotFoundError::component::) } +} - pub fn downcast_ref_unchecked(boxed_ref: &Box) -> &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::(),)]) + .map(|any| any.downcast_mut().unwrap()) + .ok_or_else(ComponentNotFoundError::component::) + } } - } - - pub fn downcast_mut_unchecked( - boxed_ref: &mut Box, - ) -> &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