summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-08-16 20:13:22 +0200
committerHampusM <hampus@hampusmat.com>2024-08-16 20:13:22 +0200
commit7d218b2525f90dfedcae02f3b3d0d2f7b9c99bd2 (patch)
treebc9523b82d138a7048ff583dd75e0a8c26fe5e6b
parent0f7811f3cba24c8a5927d5bcdfb30dd94de87102 (diff)
feat(ecs): make relationships creatable without reference to world
-rw-r--r--ecs/examples/relationship.rs2
-rw-r--r--ecs/src/component.rs7
-rw-r--r--ecs/src/lib.rs2
-rw-r--r--ecs/src/query.rs16
-rw-r--r--ecs/src/relationship.rs23
-rw-r--r--ecs/src/system.rs2
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))