summaryrefslogtreecommitdiff
path: root/ecs/src
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src')
-rw-r--r--ecs/src/component.rs2
-rw-r--r--ecs/src/lib.rs71
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);
+ }
+ }
+ }
+}