From 7d218b2525f90dfedcae02f3b3d0d2f7b9c99bd2 Mon Sep 17 00:00:00 2001 From: HampusM Date: Fri, 16 Aug 2024 20:13:22 +0200 Subject: feat(ecs): make relationships creatable without reference to world --- ecs/examples/relationship.rs | 2 +- ecs/src/component.rs | 7 +++++-- ecs/src/lib.rs | 2 +- ecs/src/query.rs | 16 +++++++++++----- ecs/src/relationship.rs | 23 +++++++---------------- ecs/src/system.rs | 2 ++ 6 files changed, 27 insertions(+), 25 deletions(-) (limited to 'ecs') 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::::new(&world, sword_uid), + Relationship::::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, + world: &'component World, ) -> Self::Refs<'component>; } @@ -203,6 +204,7 @@ pub trait FromOptional<'comp> { fn from_optional_component( optional_component: Option>>, + world: &'comp World, ) -> Self; } @@ -235,6 +237,7 @@ macro_rules! inner { fn from_components<'component>( components: impl Iterator, + 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>) -> 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>() -> 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, 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 { entity_uid: EntityUid, - component_storage: Weak>, _pd: PhantomData<(Kind, ComponentT)>, } @@ -28,13 +26,9 @@ impl Relationship 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>, - _component_storage: Arc>, } impl<'rel_comp, Kind, ComponentT> ComponentFromOptional<'rel_comp> @@ -98,19 +91,18 @@ where optional_component: Option< crate::lock::WriteGuard<'rel_comp, Box>, >, + world: &'rel_comp World, ) -> Self { let relationship_comp = ComponentRefMut::>::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>>, + _world: &'component World, ) -> Self { Self { @@ -240,6 +241,7 @@ where { fn from_optional_component( optional_component: Option>>, + _world: &'comp World, ) -> Self { optional_component.map(|component| ComponentRefMut::new(component)) -- cgit v1.2.3-18-g5258