diff options
author | HampusM <hampus@hampusmat.com> | 2024-08-16 20:13:22 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-08-16 20:13:22 +0200 |
commit | 7d218b2525f90dfedcae02f3b3d0d2f7b9c99bd2 (patch) | |
tree | bc9523b82d138a7048ff583dd75e0a8c26fe5e6b | |
parent | 0f7811f3cba24c8a5927d5bcdfb30dd94de87102 (diff) |
feat(ecs): make relationships creatable without reference to world
-rw-r--r-- | ecs/examples/relationship.rs | 2 | ||||
-rw-r--r-- | ecs/src/component.rs | 7 | ||||
-rw-r--r-- | ecs/src/lib.rs | 2 | ||||
-rw-r--r-- | ecs/src/query.rs | 16 | ||||
-rw-r--r-- | ecs/src/relationship.rs | 23 | ||||
-rw-r--r-- | ecs/src/system.rs | 2 |
6 files changed, 27 insertions, 25 deletions
diff --git a/ecs/examples/relationship.rs b/ecs/examples/relationship.rs index 81f6028..33b7091 100644 --- a/ecs/examples/relationship.rs +++ b/ecs/examples/relationship.rs @@ -41,7 +41,7 @@ fn main() world.create_entity(( Player, Health { health: 180 }, - Relationship::<Holding, Sword>::new(&world, sword_uid), + Relationship::<Holding, Sword>::new(sword_uid), )); world.emit(StartEvent); diff --git a/ecs/src/component.rs b/ecs/src/component.rs index 67ae453..5b1e7f5 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -6,7 +6,7 @@ use seq_macro::seq; use crate::lock::WriteGuard; use crate::system::{ComponentRefMut, Input as SystemInput}; use crate::type_name::TypeName; -use crate::EntityComponent; +use crate::{EntityComponent, World}; pub mod local; @@ -143,6 +143,7 @@ pub trait Sequence fn from_components<'component>( components: impl Iterator<Item = &'component EntityComponent>, + world: &'component World, ) -> Self::Refs<'component>; } @@ -203,6 +204,7 @@ pub trait FromOptional<'comp> { fn from_optional_component( optional_component: Option<WriteGuard<'comp, Box<dyn Component>>>, + world: &'comp World, ) -> Self; } @@ -235,6 +237,7 @@ macro_rules! inner { fn from_components<'component>( components: impl Iterator<Item = &'component EntityComponent>, + world: &'component World, ) -> Self::Refs<'component> { #( @@ -251,7 +254,7 @@ macro_rules! inner { } (#( - Comp~I::RefMut::from_optional_component(comp_~I), + Comp~I::RefMut::from_optional_component(comp_~I, world), )*) } } diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 39b6bf3..e298919 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -145,7 +145,7 @@ impl World Comps: ComponentSequence, OptionsT: QueryOptions, { - Query::new(&self.data.component_storage) + Query::new(&self) } /// Peforms the actions that have been queued up using [`Actions`]. diff --git a/ecs/src/query.rs b/ecs/src/query.rs index ea61640..06633bc 100644 --- a/ecs/src/query.rs +++ b/ecs/src/query.rs @@ -2,7 +2,6 @@ use std::any::Any; use std::collections::HashSet; use std::iter::{Filter, Flatten, Map}; use std::marker::PhantomData; -use std::sync::Arc; use crate::component::storage::{ Archetype, @@ -13,7 +12,7 @@ use crate::component::storage::{ }; use crate::component::{Metadata as ComponentMetadata, Sequence as ComponentSequence}; use crate::entity::Uid as EntityUid; -use crate::lock::{Lock, ReadGuard}; +use crate::lock::ReadGuard; use crate::query::options::Options; use crate::system::{ NoInitParamFlag as NoInitSystemParamFlag, @@ -29,6 +28,7 @@ pub struct Query<'world, Comps, OptionsT = ()> where Comps: ComponentSequence, { + world: &'world World, component_storage: ReadGuard<'world, ComponentStorage>, _pd: PhantomData<(Comps, OptionsT)>, } @@ -49,6 +49,7 @@ where #[allow(clippy::map_flatten)] ComponentIter { + world: self.world, entities: self .component_storage .find_entities(Comps::metadata()) @@ -72,10 +73,13 @@ where ) } - pub(crate) fn new(component_storage: &'world Arc<Lock<ComponentStorage>>) -> Self + pub(crate) fn new(world: &'world World) -> Self { Self { - component_storage: component_storage + world, + component_storage: world + .data + .component_storage .read_nonblock() .expect("Failed to acquire read-only component storage lock"), _pd: PhantomData, @@ -118,7 +122,7 @@ where world: &'world World, ) -> Self { - Self::new(&world.data.component_storage) + Self::new(&world) } fn is_compatible<Other: SystemParam<'world>>() -> bool @@ -146,6 +150,7 @@ type ComponentIterFilterFn = for<'a, 'b> fn(&'a &'b ArchetypeEntity) -> bool; pub struct ComponentIter<'world, Comps> { + world: &'world World, entities: Filter< Flatten<Map<ArchetypeRefIter<'world>, ComponentIterMapFn>>, ComponentIterFilterFn, @@ -163,6 +168,7 @@ where { Some(Comps::from_components( self.entities.next()?.components().iter(), + self.world, )) } } diff --git a/ecs/src/relationship.rs b/ecs/src/relationship.rs index 82c9e70..fa3f761 100644 --- a/ecs/src/relationship.rs +++ b/ecs/src/relationship.rs @@ -1,6 +1,5 @@ use std::any::{type_name, Any}; use std::marker::PhantomData; -use std::sync::{Arc, Weak}; use crate::component::storage::Storage as ComponentStorage; use crate::component::{ @@ -11,7 +10,7 @@ use crate::component::{ Metadata as ComponentMetadata, }; use crate::entity::Uid as EntityUid; -use crate::lock::{Lock, ReadGuard}; +use crate::lock::ReadGuard; use crate::system::{ComponentRefMut, Input as SystemInput}; use crate::type_name::TypeName; use crate::World; @@ -20,7 +19,6 @@ use crate::World; pub struct Relationship<Kind, ComponentT: Component> { entity_uid: EntityUid, - component_storage: Weak<Lock<ComponentStorage>>, _pd: PhantomData<(Kind, ComponentT)>, } @@ -28,13 +26,9 @@ impl<Kind, ComponentT> Relationship<Kind, ComponentT> where ComponentT: Component, { - pub fn new(world: &World, entity_uid: EntityUid) -> Self + pub fn new(entity_uid: EntityUid) -> Self { - Self { - entity_uid, - component_storage: Arc::downgrade(&world.data.component_storage), - _pd: PhantomData, - } + Self { entity_uid, _pd: PhantomData } } } @@ -86,7 +80,6 @@ where { component_storage_lock: ReadGuard<'static, ComponentStorage>, relationship_comp: ComponentRefMut<'rel_comp, Relationship<Kind, ComponentT>>, - _component_storage: Arc<Lock<ComponentStorage>>, } impl<'rel_comp, Kind, ComponentT> ComponentFromOptional<'rel_comp> @@ -98,19 +91,18 @@ where optional_component: Option< crate::lock::WriteGuard<'rel_comp, Box<dyn Component>>, >, + world: &'rel_comp World, ) -> Self { let relationship_comp = ComponentRefMut::<Relationship<Kind, ComponentT>>::from_optional_component( optional_component, + world, ); - let component_storage = relationship_comp + let component_storage_lock = world + .data .component_storage - .upgrade() - .expect("World has been dropped"); - - let component_storage_lock = component_storage .read_nonblock() .expect("Failed to aquire read-only component storage lock"); @@ -119,7 +111,6 @@ where // SAFETY: The component lock is not used for longer than the original // lifetime component_storage_lock: unsafe { component_storage_lock.upgrade_lifetime() }, - _component_storage: component_storage, } } } diff --git a/ecs/src/system.rs b/ecs/src/system.rs index 36359c7..7c0e454 100644 --- a/ecs/src/system.rs +++ b/ecs/src/system.rs @@ -219,6 +219,7 @@ impl<'component, ComponentT: Component> FromOptionalComponent<'component> { fn from_optional_component( inner: Option<WriteGuard<'component, Box<dyn Component>>>, + _world: &'component World, ) -> Self { Self { @@ -240,6 +241,7 @@ where { fn from_optional_component( optional_component: Option<WriteGuard<'comp, Box<dyn Component>>>, + _world: &'comp World, ) -> Self { optional_component.map(|component| ComponentRefMut::new(component)) |