diff options
author | HampusM <hampus@hampusmat.com> | 2024-04-04 21:07:11 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-04-04 21:07:11 +0200 |
commit | 3c8c135b9f41acf6a170822c0cba21a402f881d6 (patch) | |
tree | 368761f0445ac2b882bae9c62e2e840e1392e495 /ecs | |
parent | 171666ba9af47d762ccc2344f11fa5946d49679d (diff) |
feat(ecs): allow components to be specified to be dropped last
Diffstat (limited to 'ecs')
-rw-r--r-- | ecs/src/component.rs | 2 | ||||
-rw-r--r-- | ecs/src/lib.rs | 71 |
2 files changed, 66 insertions, 7 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index 120ba30..c1f8168 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -16,6 +16,8 @@ use crate::WorldData; pub trait Component: SystemInput + Any + TypeName { + fn drop_last(&self) -> bool; + #[doc(hidden)] fn as_any_mut(&mut self) -> &mut dyn Any; 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); + } + } + } +} |