diff options
Diffstat (limited to 'ecs/src/relationship.rs')
-rw-r--r-- | ecs/src/relationship.rs | 52 |
1 files changed, 35 insertions, 17 deletions
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<Kind, ComponentT: Component> { - entity_uid: SingleOrMultiple<EntityUid>, + entity_uid: SingleOrMultiple<Uid>, _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<Item = EntityUid>) -> Self + pub fn new_multiple(entity_uids: impl IntoIterator<Item = Uid>) -> Self { + let uids = entity_uids.into_iter().collect::<Vec<_>>(); + + 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<Uid> = + LazyLock::new(|| Uid::new_unique(UidKind::Component)); + impl<Kind, ComponentT> Component for Relationship<Kind, ComponentT> 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::<Self>() + *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::<ComponentT>())?; + 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<EntityUid> + pub fn remove_target(&mut self, index: usize) -> Option<Uid> { 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::<ComponentT>())?; + 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), |