From daf0bc236df25c0e9f44bc3e30839c16cda3f638 Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 11 Nov 2024 00:11:22 +0100 Subject: refactor(ecs): use same ID for entities & components --- ecs/src/relationship.rs | 52 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 17 deletions(-) (limited to 'ecs/src/relationship.rs') diff --git a/ecs/src/relationship.rs b/ecs/src/relationship.rs index 4db29da..9f2a81e 100644 --- a/ecs/src/relationship.rs +++ b/ecs/src/relationship.rs @@ -1,24 +1,24 @@ use std::any::{type_name, Any}; use std::marker::PhantomData; +use std::sync::LazyLock; use crate::component::storage::Storage as ComponentStorage; use crate::component::{ Component, FromOptional as FromOptionalComponent, FromOptionalMut as FromOptionalMutComponent, - Id as ComponentId, }; -use crate::entity::Uid as EntityUid; use crate::lock::ReadGuard; use crate::system::{ComponentRef, ComponentRefMut, Input as SystemInput}; use crate::type_name::TypeName; +use crate::uid::{Kind as UidKind, Uid}; use crate::World; /// A relationship to one or more targets. #[derive(Debug)] pub struct Relationship { - entity_uid: SingleOrMultiple, + entity_uid: SingleOrMultiple, _pd: PhantomData<(Kind, ComponentT)>, } @@ -28,8 +28,10 @@ where { /// Creates a new `Relationship` with a single target. #[must_use] - pub fn new(entity_uid: EntityUid) -> Self + pub fn new(entity_uid: Uid) -> Self { + debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + Self { entity_uid: SingleOrMultiple::Single(entity_uid), _pd: PhantomData, @@ -38,15 +40,24 @@ where /// Creates a new `Relationship` with multiple targets. #[must_use] - pub fn new_multiple(entity_uids: impl IntoIterator) -> Self + pub fn new_multiple(entity_uids: impl IntoIterator) -> Self { + let uids = entity_uids.into_iter().collect::>(); + + for euid in &uids { + debug_assert_eq!(euid.kind(), UidKind::Entity); + } + Self { - entity_uid: SingleOrMultiple::Multiple(entity_uids.into_iter().collect()), + entity_uid: SingleOrMultiple::Multiple(uids), _pd: PhantomData, } } } +static COMPONENT_EUID: LazyLock = + LazyLock::new(|| Uid::new_unique(UidKind::Component)); + impl Component for Relationship where Kind: 'static, @@ -56,9 +67,16 @@ where type Ref<'component> = Relation<'component, Kind, ComponentT>; type RefMut<'component> = RelationMut<'component, Kind, ComponentT>; - fn id(&self) -> ComponentId + fn id() -> Uid + where + Self: Sized, { - ComponentId::of::() + *COMPONENT_EUID + } + + fn self_id(&self) -> Uid + { + Self::id() } fn as_any_mut(&mut self) -> &mut dyn Any @@ -151,8 +169,7 @@ where .get_entity(*target) .expect("Target entity is gone from archetype"); - let component_index = - archetype.get_index_for_component(&ComponentId::of::())?; + let component_index = archetype.get_index_for_component(&ComponentT::id())?; let component = ComponentRefMut::new( entity @@ -172,7 +189,7 @@ where /// Returns a reference to the target at the specified index. #[must_use] - pub fn get_target(&self, index: usize) -> Option<&EntityUid> + pub fn get_target(&self, index: usize) -> Option<&Uid> { match &self.relationship_comp.entity_uid { SingleOrMultiple::Single(entity_uid) if index == 0 => Some(entity_uid), @@ -183,7 +200,7 @@ where /// Returns a mutable reference to the target at the specified index. #[must_use] - pub fn get_target_mut(&mut self, index: usize) -> Option<&mut EntityUid> + pub fn get_target_mut(&mut self, index: usize) -> Option<&mut Uid> { match &mut self.relationship_comp.entity_uid { SingleOrMultiple::Single(entity_uid) if index == 0 => Some(entity_uid), @@ -193,8 +210,10 @@ where } /// Adds a target to the relationship. - pub fn add_target(&mut self, entity_uid: EntityUid) + pub fn add_target(&mut self, entity_uid: Uid) { + debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + match &mut self.relationship_comp.entity_uid { SingleOrMultiple::Single(prev_entity_uid) => { self.relationship_comp.entity_uid = @@ -205,7 +224,7 @@ where } /// Removes a target to the relationship, returning it. - pub fn remove_target(&mut self, index: usize) -> Option + pub fn remove_target(&mut self, index: usize) -> Option { match &mut self.relationship_comp.entity_uid { SingleOrMultiple::Single(entity_uid) => { @@ -354,8 +373,7 @@ where .get_entity(*target) .expect("Target entity is gone from archetype"); - let component_index = - archetype.get_index_for_component(&ComponentId::of::())?; + let component_index = archetype.get_index_for_component(&ComponentT::id())?; let component = ComponentRef::new( entity @@ -375,7 +393,7 @@ where /// Returns a reference to the target at the specified index. #[must_use] - pub fn get_target(&self, index: usize) -> Option<&EntityUid> + pub fn get_target(&self, index: usize) -> Option<&Uid> { match &self.relationship_comp.entity_uid { SingleOrMultiple::Single(entity_uid) if index == 0 => Some(entity_uid), -- cgit v1.2.3-18-g5258