diff options
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r-- | ecs/src/lib.rs | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 7a56f37..4d6e4e5 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -4,6 +4,7 @@ use std::any::{type_name, Any, TypeId}; use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::marker::PhantomData; +use std::mem::ManuallyDrop; use std::ops::RangeBounds; use std::slice::Iter as SliceIter; use std::sync::{Arc, Weak}; @@ -35,7 +36,7 @@ pub use ecs_macros::Component; #[derive(Debug, Default)] struct Entity { - components: Vec<EntityComponent>, + components: Vec<ManuallyDrop<EntityComponent>>, } #[derive(Debug)] @@ -43,6 +44,7 @@ struct EntityComponent { id: TypeId, component: Lock<Box<dyn Component>>, + drop_last: bool, } #[derive(Debug, Default)] @@ -73,9 +75,14 @@ impl World components: components .into_vec() .into_iter() - .map(|component| EntityComponent { - id: (*component).type_id(), - component: Lock::new(component), + .map(|component| { + let drop_last = component.drop_last(); + + ManuallyDrop::new(EntityComponent { + id: (*component).type_id(), + component: Lock::new(component), + drop_last, + }) }) .collect(), }); @@ -144,9 +151,14 @@ impl World .push(Entity { components: components .into_iter() - .map(|component| EntityComponent { - id: (*component).type_id(), - component: Lock::new(component), + .map(|component| { + let drop_last = component.drop_last(); + + ManuallyDrop::new(EntityComponent { + id: (*component).type_id(), + component: Lock::new(component), + drop_last, + }) }) .collect(), }); @@ -443,3 +455,48 @@ impl TypeName for ComponentStorage type_name::<Self>() } } + +impl Drop for ComponentStorage +{ + fn drop(&mut self) + { + let mut components_to_drop_last = Vec::new(); + + for entity in &mut self.entities { + for component in &mut entity.components { + if component.drop_last { + #[cfg(feature = "debug")] + tracing::debug!( + "Component {} pushed to dropping last queue", + component.component.read_nonblock().unwrap().type_name() + ); + + components_to_drop_last.push(component); + continue; + } + + #[cfg(feature = "debug")] + tracing::debug!( + "Dropping component {}", + component.component.read_nonblock().unwrap().type_name() + ); + + unsafe { + ManuallyDrop::drop(component); + } + } + } + + for component in &mut components_to_drop_last { + #[cfg(feature = "debug")] + tracing::debug!( + "Dropping component {} last", + component.component.read_nonblock().unwrap().type_name() + ); + + unsafe { + ManuallyDrop::drop(component); + } + } + } +} |