From c5946638d024493614953b74d97dc9692165eacc Mon Sep 17 00:00:00 2001 From: Tei Leelo Roberts Date: Wed, 18 Oct 2023 15:24:52 +0200 Subject: [PATCH] fix!: clear up naming with relation target The use of object is overly generic and is easily confused with its other meaning. Target is a more natural alternative --- guide/src/diving_deeper/dynamic_components.md | 2 +- guide/src/fundamentals/relations.md | 6 +-- guide/src/introduction.md | 2 +- src/cascade/mod.rs | 6 +-- src/component.rs | 51 +++++++++---------- src/entity/mod.rs | 1 - src/fetch/relations.rs | 6 +-- src/fetch/source.rs | 10 ++-- src/filter/mod.rs | 18 +++---- src/macros.rs | 8 +-- src/query/dfs.rs | 7 ++- src/query/topo.rs | 4 +- src/query/walk.rs | 4 +- src/relation.rs | 14 ++--- src/world.rs | 18 +++---- src/writer.rs | 2 +- tests/schedule.rs | 6 +-- 17 files changed, 81 insertions(+), 84 deletions(-) diff --git a/guide/src/diving_deeper/dynamic_components.md b/guide/src/diving_deeper/dynamic_components.md index 832df937..6ac08e2c 100644 --- a/guide/src/diving_deeper/dynamic_components.md +++ b/guide/src/diving_deeper/dynamic_components.md @@ -43,5 +43,5 @@ entity as the generation is not needed. {{ #include ../../../examples/guide/dynamic_components.rs:relation }} ``` -When despawning either the relation component or object entity, the "parent", +When despawning either the relation component or target entity, the "parent", the component is removed from all entities. diff --git a/guide/src/fundamentals/relations.md b/guide/src/fundamentals/relations.md index 0cc0dca1..e48647b4 100644 --- a/guide/src/fundamentals/relations.md +++ b/guide/src/fundamentals/relations.md @@ -4,7 +4,7 @@ A relation is a component which *links* to another `Entity`, similar to a foreig The links between entities are managed by the ECS itself and will always be valid, see [Lifetime](#lifetime) -The linked entity is referred to as the `object` of a relation, while the entity the component is attached to is called the `subject`. +The linked entity is referred to as the `target` of a relation, while the entity the component is attached to is called the `subject`. This allows forming hierarchies such as *parent-child* relations for transforms and UI, as well as arbitrary graphs. @@ -17,11 +17,11 @@ For example, declaring a child relationship that connects to a parent can be don {{ #include ../../../examples/guide/relations.rs:relation_basic }} ``` -The parameter to the component function determines the object entity or target of the relation. +The parameter to the component function determines the target entity of the relation. Since the value of the relation in this case is `()`, `set_default` can be used as a shorthand over `set` -Two relations of the same type but with different *objects* behave like two separate components and will not interfere. This allows having many-to-many relationships between entities, if so desired. +Two relations of the same type but with different *targets* behave like two separate components and will not interfere. This allows having many-to-many relationships between entities, if so desired. This allows constructing many different kinds of graphs inside the ECS. diff --git a/guide/src/introduction.md b/guide/src/introduction.md index 3b7bfd06..bb9d3cdd 100644 --- a/guide/src/introduction.md +++ b/guide/src/introduction.md @@ -17,7 +17,7 @@ and new functionality can be added to existing entities and components. In Flax, there are 3 fundamental building blocks. -[Entity](https://docs.rs/flax/latest/flax/struct.Entity.html). A unique identifier for the objects of the program. Has a managed lifecycle. +[Entity](https://docs.rs/flax/latest/flax/struct.Entity.html). A unique identifier for the entities of the program. Has a managed lifecycle. [Component](https://docs.rs/flax/latest/flax/struct.Component.html), data which can be added to an Entity. Has a unique Id, which works as the key for storing diff --git a/src/cascade/mod.rs b/src/cascade/mod.rs index 3250aa43..49b2d7e6 100644 --- a/src/cascade/mod.rs +++ b/src/cascade/mod.rs @@ -89,15 +89,15 @@ fn get_ordered_archetypes( }, } - // Find relations to other objects, and visit them as well + // Find relations to other targets, and visit them as well let relations = arch.relations_like(relation); let mut is_reachable = false; let mut is_root = true; for (key, _) in relations { is_root = false; - let parent = key.object.unwrap(); + let target = key.target.unwrap(); - let loc = world.location(parent).unwrap(); + let loc = world.location(target).unwrap(); // Part of the visited set if let Some(arch) = archetypes.get(&loc.arch_id) { if get_ordered_archetypes(world, archetypes, arch_id, arch, relation, visited, ordered) diff --git a/src/component.rs b/src/component.rs index fe66a502..197a0975 100644 --- a/src/component.rs +++ b/src/component.rs @@ -37,8 +37,8 @@ impl ComponentValue for T where T: Send + Sync + 'static {} #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ComponentKey { pub(crate) id: Entity, - /// The object entity if the component is a relation - pub(crate) object: Option, + /// The target entity if the component is a relation + pub(crate) target: Option, } #[cfg(feature = "serde")] @@ -49,7 +49,7 @@ impl Serialize for ComponentKey { { let mut seq = serializer.serialize_tuple_struct("ComponentId", 2)?; seq.serialize_field(&self.id)?; - seq.serialize_field(&self.object)?; + seq.serialize_field(&self.target)?; seq.end() } @@ -71,7 +71,7 @@ impl<'de> Deserialize<'de> for ComponentKey { ) -> smallvec::alloc::fmt::Result { write!( formatter, - "A tuple of a component id and optional relation object" + "A tuple of a component id and optional relation target" ) } @@ -82,11 +82,11 @@ impl<'de> Deserialize<'de> for ComponentKey { let id = seq .next_element()? .ok_or_else(|| Error::invalid_length(0, &self))?; - let object = seq + let target = seq .next_element()? .ok_or_else(|| Error::invalid_length(1, &self))?; - Ok(ComponentKey::new(id, object)) + Ok(ComponentKey::new(id, target)) } } @@ -98,17 +98,17 @@ impl ComponentKey { /// Returns true if the component is a relation #[inline] pub fn is_relation(&self) -> bool { - self.object.is_some() + self.target.is_some() } - pub(crate) fn new(id: Entity, object: Option) -> Self { - Self { id, object } + pub(crate) fn new(id: Entity, target: Option) -> Self { + Self { id, target } } #[inline] - /// Returns the object of the relation - pub fn object(&self) -> Option { - self.object + /// Returns the target of the relation + pub fn target(&self) -> Option { + self.target } #[inline] @@ -126,7 +126,7 @@ impl Display for ComponentKey { impl Debug for ComponentKey { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - match self.object { + match self.target { Some(s) => write!(f, "{}({s})", self.id), None => Debug::fmt(&self.id, f), } @@ -136,9 +136,8 @@ impl Debug for ComponentKey { /// Type alias for a function which instantiates a component pub type ComponentFn = fn() -> Component; -/// Type alias for a function which instantiates a relation with the specified -/// object -pub type RelationFn = fn(object: Entity) -> Component; +/// Type alias for a function which instantiates a relation with the specified target +pub type RelationFn = fn(target: Entity) -> Component; crate::component! { pub(crate) dummy, @@ -175,8 +174,8 @@ impl Clone for Component { impl fmt::Debug for Component { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self.key.object { - Some(object) => write!(f, "{}({}) {}", self.vtable.name, object, self.key.id()), + match self.key.target { + Some(target) => write!(f, "{}({}) {}", self.vtable.name, target, self.key.id()), None => write!(f, "{} {}", self.vtable.name, self.key.id), } } @@ -184,8 +183,8 @@ impl fmt::Debug for Component { impl Display for Component { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self.key.object { - Some(object) => write!(f, "{}({}) {}", self.vtable.name, object, self.key.id()), + match self.key.target { + Some(target) => write!(f, "{}({}) {}", self.vtable.name, target, self.key.id()), None => write!(f, "{} {}", self.vtable.name, self.key.id), } } @@ -237,7 +236,7 @@ impl Component { } /// Get the component's base id. - /// This is the id without any relation object + /// This is the id without any relation target #[inline(always)] pub fn id(&self) -> Entity { self.key.id @@ -326,9 +325,9 @@ impl RelationExt for Component { self.key().id } - fn of(&self, object: Entity) -> Component { + fn of(&self, target: Entity) -> Component { Self { - key: ComponentKey::new(self.key().id, Some(object)), + key: ComponentKey::new(self.key().id, Some(target)), ..*self } } @@ -370,8 +369,8 @@ impl PartialEq for ComponentDesc { impl core::fmt::Debug for ComponentDesc { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self.key.object { - Some(object) => write!(f, "{}({}) {}", self.vtable.name, object, self.key.id()), + match self.key.target { + Some(target) => write!(f, "{}({}) {}", self.vtable.name, target, self.key.id()), None => write!(f, "{} {}", self.vtable.name, self.key.id), } } @@ -464,7 +463,7 @@ impl ComponentDesc { #[inline] pub(crate) fn is_relation(&self) -> bool { - self.key.object.is_some() + self.key.target.is_some() } pub(crate) fn get_meta(&self) -> ComponentBuffer { diff --git a/src/entity/mod.rs b/src/entity/mod.rs index de4796fd..41801b08 100644 --- a/src/entity/mod.rs +++ b/src/entity/mod.rs @@ -18,7 +18,6 @@ pub(crate) const DEFAULT_GEN: EntityGen = unsafe { EntityGen::new_unchecked(1) } #[derive(PartialOrd, Clone, Copy, PartialEq, Eq, Ord, Hash)] pub struct Entity { pub(crate) index: EntityIndex, - /// Object pub(crate) gen: EntityGen, pub(crate) kind: EntityKind, } diff --git a/src/fetch/relations.rs b/src/fetch/relations.rs index 5f582f35..38530c8e 100644 --- a/src/fetch/relations.rs +++ b/src/fetch/relations.rs @@ -34,7 +34,7 @@ where let borrows: SmallVec<[_; 4]> = { data.arch .relations_like(self.component.id()) - .map(|(desc, cell)| (desc.object.unwrap(), cell.borrow())) + .map(|(desc, cell)| (desc.target.unwrap(), cell.borrow())) .collect() }; @@ -48,7 +48,7 @@ where fn access(&self, data: FetchAccessData, dst: &mut Vec) { let relation = self.component.key().id; dst.extend(data.arch.cells().keys().filter_map(move |k| { - if k.object.is_some() && k.id == relation { + if k.target.is_some() && k.id == relation { return Some(Access { kind: AccessKind::Archetype { id: data.arch_id, @@ -107,7 +107,7 @@ where } } -/// Iterates the relation object and data for the yielded query item +/// Iterates the relation targets and data for the yielded query item pub struct RelationsIter<'a, T> { borrows: slice::Iter<'a, (Entity, CellGuard<'a, [T]>)>, slot: Slot, diff --git a/src/fetch/source.rs b/src/fetch/source.rs index df91abbe..2d9de6d6 100644 --- a/src/fetch/source.rs +++ b/src/fetch/source.rs @@ -20,7 +20,7 @@ pub trait FetchSource { fn describe(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result; } -/// Selects the fetch value from the first parent/object of the specified relation +/// Selects the fetch value from the first target of the specified relation pub struct FromRelation { pub(crate) relation: Entity, pub(crate) name: &'static str, @@ -33,11 +33,11 @@ impl FetchSource for FromRelation { data: FetchAccessData<'a>, ) -> Option<(ArchetypeId, &'a Archetype, Option)> { for (key, _) in data.arch.relations_like(self.relation) { - let object = key.object().unwrap(); + let target = key.target.unwrap(); let loc = data .world - .location(object) + .location(target) .expect("Relation contains invalid entity"); let arch = data.world.archetypes.get(loc.arch_id); @@ -95,11 +95,11 @@ fn traverse_resolve<'a, 'w, Q: Fetch<'w>>( } for (key, _) in data.arch.relations_like(relation) { - let object = key.object().unwrap(); + let target = key.target.unwrap(); let loc = data .world - .location(object) + .location(target) .expect("Relation contains invalid entity"); let data = FetchAccessData { diff --git a/src/filter/mod.rs b/src/filter/mod.rs index 3a21bafc..bc72fd34 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -166,7 +166,7 @@ gen_bitops! { Nothing[]; Or[T]; RemovedFilter[T]; - WithObject[]; + WithTarget[]; WithRelation[]; With[]; WithoutRelation[]; @@ -319,15 +319,15 @@ impl StaticFilter for Without { #[derive(Debug, Clone)] /// Yields all entities with the relation of the specified kind -pub(crate) struct WithObject { - pub(crate) object: Entity, +pub(crate) struct WithTarget { + pub(crate) target: Entity, } -impl<'q> FetchItem<'q> for WithObject { +impl<'q> FetchItem<'q> for WithTarget { type Item = (); } -impl<'w> Fetch<'w> for WithObject { +impl<'w> Fetch<'w> for WithTarget { const MUTABLE: bool = false; type Prepared = All; @@ -341,18 +341,18 @@ impl<'w> Fetch<'w> for WithObject { } fn describe(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "with (*)({})", self.object) + write!(f, "with (*)({})", self.target) } #[inline] fn access(&self, _: FetchAccessData, _: &mut Vec) {} } -impl StaticFilter for WithObject { +impl StaticFilter for WithTarget { fn filter_static(&self, arch: &Archetype) -> bool { arch.components().any(|v| { - if let Some(v) = v.key().object { - if v == self.object { + if let Some(v) = v.key().target { + if v == self.target { return true; } } diff --git a/src/macros.rs b/src/macros.rs index 4e51395e..d3efa061 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -17,10 +17,10 @@ /// pub(crate) name: type => [ Metadata, ... ], /// /// // relational component -/// name(object): type +/// name(target): type /// /// // relation component with metadata/reflection -/// name(object): type => [ Metadata, ... ] +/// name(target): type => [ Metadata, ... ] /// /// // static entity /// name, @@ -50,7 +50,7 @@ /// /// # Relations /// A component can be associated to another entity, which declares a relation of the component -/// type between the subject (entity which has the component), and the object (the associated +/// type between the subject (entity which has the component), and the target (the associated /// entity). /// /// Relation components with different associated entities are distinct. @@ -101,7 +101,7 @@ /// another *generationless* entity id. /// /// This allows for the parameterization of components with component ids being -/// distinct with across different objects. +/// distinct with across different target. macro_rules! component { // Relations ($(#[$outer:meta])* $vis: vis $name: ident( $obj: ident ): $ty: ty $(=> [$($metadata: ty),*])?, $($rest:tt)*) => { diff --git a/src/query/dfs.rs b/src/query/dfs.rs index aa26ca1c..fa0b5d0b 100644 --- a/src/query/dfs.rs +++ b/src/query/dfs.rs @@ -112,9 +112,9 @@ impl State { let mut root = true; for (key, _) in arch.relations_like(relation) { root = false; - let object = key.object.unwrap(); + let target = key.target.unwrap(); - self.edges.entry(object).or_default().push(index); + self.edges.entry(target).or_default().push(index); } if root { @@ -285,7 +285,6 @@ where F: 'w, { while let Some((slot, id, item)) = chunk.next_full() { - let edge_value = edge.map(|v| &v[slot]); let value = (visit)(item, edge.map(|v| &v[slot]), value); // Iterate the archetypes which contain all references to `id` @@ -545,7 +544,7 @@ mod test { Query::new((entity_ids(), name())) .with_strategy(Dfs::new(child_of)) .borrow(&world) - .traverse(&Vec::new(), |(id, name), v, prefix| { + .traverse(&Vec::new(), |(id, name), _, prefix| { let mut p = prefix.clone(); p.push(name.clone()); diff --git a/src/query/topo.rs b/src/query/topo.rs index ed6865a7..4d504114 100644 --- a/src/query/topo.rs +++ b/src/query/topo.rs @@ -69,8 +69,8 @@ impl State { .relations_like(relation) .map(|(key, _)| { assert_eq!(key.id, relation); - let object = key.object().unwrap(); - let loc = world.location(object).unwrap(); + let target = key.target.unwrap(); + let loc = world.location(target).unwrap(); loc.arch_id }) .collect(); diff --git a/src/query/walk.rs b/src/query/walk.rs index eb49f3e3..7b2f3afb 100644 --- a/src/query/walk.rs +++ b/src/query/walk.rs @@ -146,9 +146,9 @@ impl GraphState { // Go backwards through the relations for (key, _) in arch.relations_like(relation) { - let object = key.object.unwrap(); + let target = key.target.unwrap(); - self.edges.entry(object).or_default().push(arch_id); + self.edges.entry(target).or_default().push(arch_id); } } } diff --git a/src/relation.rs b/src/relation.rs index b27363c7..2ee75ca2 100644 --- a/src/relation.rs +++ b/src/relation.rs @@ -26,7 +26,7 @@ where /// Returns the vtable of the relation fn vtable(&self) -> &'static UntypedVTable; /// Instantiate the relation - fn of(&self, object: Entity) -> Component; + fn of(&self, target: Entity) -> Component; /// Construct a new filter yielding entities with this kind of relation fn with_relation(self) -> WithRelation; /// Construct a new filter yielding entities without this kind of relation @@ -46,8 +46,8 @@ where (self)(dummy()).vtable() } - fn of(&self, object: Entity) -> Component { - (self)(object) + fn of(&self, target: Entity) -> Component { + (self)(target) } fn with_relation(self) -> WithRelation { @@ -144,8 +144,8 @@ impl RelationExt for Relation { self.vtable } - fn of(&self, object: Entity) -> Component { - Component::from_raw_parts(ComponentKey::new(self.id, Some(object)), self.vtable) + fn of(&self, target: Entity) -> Component { + Component::from_raw_parts(ComponentKey::new(self.id, Some(target)), self.vtable) } #[inline] @@ -195,7 +195,7 @@ where fn next(&mut self) -> Option { let (&key, cell) = self.cells.next()?; // Safety: the type matches the relation ext - Some((key.object().unwrap(), unsafe { + Some((key.target.unwrap(), unsafe { cell.get::(self.slot).unwrap() })) } @@ -240,7 +240,7 @@ where fn next(&mut self) -> Option { let (&key, cell) = self.cells.next()?; Some(( - key.object().unwrap(), + key.target.unwrap(), cell.get_mut::(self.entities[self.slot], self.slot, self.change_tick) .unwrap(), )) diff --git a/src/world.rs b/src/world.rs index 7c25b9f5..e0477f4f 100644 --- a/src/world.rs +++ b/src/world.rs @@ -455,7 +455,7 @@ impl World { .filter(ArchetypeFilter(|arch: &Archetype| { // Filter any subject or relation kind arch.components() - .any(|v| v.key().id == id || v.key().object == Some(id)) + .any(|v| v.key().id == id || v.key().target == Some(id)) })) .borrow(self) .archetypes() @@ -466,7 +466,7 @@ impl World { let components = src.components().filter(|v| { let key = v.key(); - !(key.id == id || key.object == Some(id)) + !(key.id == id || key.target == Some(id)) }); let (dst_id, dst) = self.archetypes.find_create(components); @@ -1184,8 +1184,8 @@ impl World { // Modify the relations to match new components id.id = *new_ids.get(&id.id).unwrap_or(&id.id); - if let Some(ref mut object) = id.object { - *object = *new_ids.get(object).unwrap_or(object); + if let Some(ref mut target) = id.target { + *target = *new_ids.get(target).unwrap_or(target); } // Safety @@ -1217,8 +1217,8 @@ impl World { // Modify the relations to match new components key.id = *new_ids.get(&key.id).unwrap_or(&key.id); - if let Some(ref mut object) = key.object { - *object = *new_ids.get(object).unwrap_or(object); + if let Some(ref mut target) = key.target { + *target = *new_ids.get(target).unwrap_or(target); } // Migrate custom components @@ -1286,9 +1286,9 @@ impl MigratedEntities { /// If the types do not match pub fn get_component(&self, component: Component) -> Component { let id = self.get(component.key().id); - let object = component.key().object.map(|v| self.get(v)); + let target = component.key().target.map(|v| self.get(v)); - Component::from_raw_parts(ComponentKey::new(id, object), component.vtable) + Component::from_raw_parts(ComponentKey::new(id, target), component.vtable) } /// Returns the migrated relation @@ -1302,7 +1302,7 @@ impl MigratedEntities { let component = self.get_component(component); - move |object| component.of(object) + move |target| component.of(target) } /// Returns the migrated ids diff --git a/src/writer.rs b/src/writer.rs index 1cd8a3e9..03363da0 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -420,7 +420,7 @@ unsafe impl<'b> EntityWriter for Buffered<'b> { // Component does not exist yet, so defer a move // Exclusive relation - if key.object.is_some() && desc.meta_ref().has(exclusive()) { + if key.target.is_some() && desc.meta_ref().has(exclusive()) { if exclusive_relations.contains(&key.id) { panic!("Multiple exclusive relations"); } diff --git a/tests/schedule.rs b/tests/schedule.rs index a864d05c..52d7dc85 100644 --- a/tests/schedule.rs +++ b/tests/schedule.rs @@ -418,7 +418,7 @@ fn schedule_par() { } #[derive(Fetch, Debug, Clone)] - struct BattleObject { + struct BattleTarget { id: EntityIds, pos: Component, health: Mutable, @@ -431,14 +431,14 @@ fn schedule_par() { range: range(), pos: pos(), })) - .with_query(Query::new(BattleObject { + .with_query(Query::new(BattleTarget { id: EntityIds, pos: pos(), health: health().as_mut(), })) .with_name("battle") .build( - |mut sub: QueryBorrow, mut obj: QueryBorrow| { + |mut sub: QueryBorrow, mut obj: QueryBorrow| { eprintln!("Prepared queries, commencing battles"); for a in sub.iter() { for b in obj.iter() {