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 | |
| parent | 171666ba9af47d762ccc2344f11fa5946d49679d (diff) | |
feat(ecs): allow components to be specified to be dropped last
| -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); +            } +        } +    } +}  | 
