diff options
| author | HampusM <hampus@hampusmat.com> | 2026-06-06 18:55:07 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-06-06 19:22:04 +0200 |
| commit | 7fe8e9ea15fac647fe8655ee096a9aa5703a97c6 (patch) | |
| tree | d67f60d3275580d3963409bdc34afe8bc811453d | |
| parent | e5d67bf7e36671d290b19064f58bc11616c05b8b (diff) | |
feat(engine-ecs): remove Uid kinds
| -rw-r--r-- | engine-ecs-macros/src/lib.rs | 4 | ||||
| -rw-r--r-- | engine-ecs/src/actions.rs | 14 | ||||
| -rw-r--r-- | engine-ecs/src/component/storage.rs | 29 | ||||
| -rw-r--r-- | engine-ecs/src/component/storage/archetype.rs | 39 | ||||
| -rw-r--r-- | engine-ecs/src/component/storage/graph.rs | 7 | ||||
| -rw-r--r-- | engine-ecs/src/entity.rs | 24 | ||||
| -rw-r--r-- | engine-ecs/src/event.rs | 4 | ||||
| -rw-r--r-- | engine-ecs/src/lib.rs | 12 | ||||
| -rw-r--r-- | engine-ecs/src/pair.rs | 13 | ||||
| -rw-r--r-- | engine-ecs/src/query.rs | 6 | ||||
| -rw-r--r-- | engine-ecs/src/uid.rs | 130 |
11 files changed, 93 insertions, 189 deletions
diff --git a/engine-ecs-macros/src/lib.rs b/engine-ecs-macros/src/lib.rs index f133cfe..3eb02dd 100644 --- a/engine-ecs-macros/src/lib.rs +++ b/engine-ecs-macros/src/lib.rs @@ -68,7 +68,7 @@ pub fn component_derive(input: TokenStream) -> TokenStream let id_var = quote! { static #id_var_ident: LazyLock<Uid> = LazyLock::new(|| { - Uid::new_unique(UidKind::Component) + Uid::new_unique() }); }; @@ -83,7 +83,7 @@ pub fn component_derive(input: TokenStream) -> TokenStream use ::std::sync::{LazyLock, Mutex}; use #ecs_path::component::Component; - use #ecs_path::uid::{Uid, Kind as UidKind}; + use #ecs_path::uid::Uid; use #ecs_path::system::Input as SystemInput; use super::*; diff --git a/engine-ecs/src/actions.rs b/engine-ecs/src/actions.rs index 3d8afe6..efef384 100644 --- a/engine-ecs/src/actions.rs +++ b/engine-ecs/src/actions.rs @@ -2,7 +2,7 @@ use crate::component::{Parts as ComponentParts, Sequence as ComponentSequence}; use crate::event::component::Removed; use crate::pair::Pair; use crate::system::{Metadata as SystemMetadata, Param as SystemParam}; -use crate::uid::{Kind as UidKind, Uid, WithUidTuple}; +use crate::uid::{Uid, WithUidTuple}; use crate::{ActionQueue, World}; /// Used to to queue up actions for a [`World`] to perform. @@ -19,7 +19,7 @@ impl Actions<'_> /// that the entity will have. pub fn spawn<Comps: ComponentSequence>(&mut self, components: Comps) -> Uid { - let new_entity_uid = Uid::new_unique(UidKind::Entity); + let new_entity_uid = Uid::new_unique(); self.action_queue.push(Action::Spawn( new_entity_uid, @@ -32,7 +32,7 @@ impl Actions<'_> /// Queues up despawning a entity at the end of the current tick. pub fn despawn(&mut self, entity_uid: Uid) { - debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + debug_assert!(!entity_uid.is_pair()); let Some(world) = self.world else { self.action_queue.push(Action::Despawn(entity_uid)); @@ -46,7 +46,7 @@ impl Actions<'_> // TODO: Submit all events with a single function call to reduce overhead for comp_id in ent.component_ids() { - if comp_id.kind() == UidKind::Pair { + if comp_id.is_pair() { continue; } @@ -67,7 +67,7 @@ impl Actions<'_> where Comps: ComponentSequence, { - debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + debug_assert!(!entity_uid.is_pair()); if Comps::COUNT == 0 { return; @@ -87,7 +87,7 @@ impl Actions<'_> component_ids: impl IntoIterator<Item = Uid>, ) { - debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + debug_assert!(!entity_uid.is_pair()); let mut component_ids = component_ids.into_iter().peekable(); @@ -118,7 +118,7 @@ impl Actions<'_> // TODO: Submit all events with a single function call to reduce overhead for comp_id in &component_ids { - if comp_id.kind() == UidKind::Pair { + if comp_id.is_pair() { continue; } diff --git a/engine-ecs/src/component/storage.rs b/engine-ecs/src/component/storage.rs index d4457bb..e77cfa3 100644 --- a/engine-ecs/src/component/storage.rs +++ b/engine-ecs/src/component/storage.rs @@ -17,7 +17,7 @@ use crate::component::storage::graph::{ ArchetypeEdges, Graph, }; -use crate::uid::{Kind as UidKind, Uid}; +use crate::uid::Uid; use crate::util::{BorrowedOrOwned, Either, StreamingIterator, VecExt}; pub mod archetype; @@ -35,21 +35,18 @@ impl ArchetypeSearchTerms<'_> { fn excluded_contains(&self, comp_id: Uid) -> bool { - let comp_id_kind = comp_id.kind(); - debug_assert!( - comp_id_kind == UidKind::Component - || (comp_id_kind == UidKind::Pair - && comp_id.target_component() != Uid::wildcard()) + !comp_id.is_pair() + || (comp_id.is_pair() && comp_id.target() != Uid::wildcard()) ); let is_found = self.excluded_components.binary_search(&comp_id).is_ok(); - if !is_found && comp_id_kind == UidKind::Pair { + if !is_found && comp_id.is_pair() { return self.excluded_components.iter().any(|excluded_comp_id| { - excluded_comp_id.kind() == UidKind::Pair + excluded_comp_id.is_pair() && excluded_comp_id.has_same_relation_as(comp_id) - && excluded_comp_id.target_component() == Uid::wildcard() + && excluded_comp_id.target() == Uid::wildcard() }); } @@ -107,8 +104,8 @@ impl Storage .push(ImaginaryArchetype { id: ArchetypeId::new(search_terms.required_components.iter().filter( |required_comp_id| { - required_comp_id.kind() != UidKind::Pair - || required_comp_id.target_component() != Uid::wildcard() + !required_comp_id.is_pair() + || required_comp_id.target() != Uid::wildcard() }, )), component_ids: search_terms @@ -116,8 +113,8 @@ impl Storage .iter() .copied() .filter(|required_comp_id| { - required_comp_id.kind() != UidKind::Pair - || required_comp_id.target_component() != Uid::wildcard() + !required_comp_id.is_pair() + || required_comp_id.target() != Uid::wildcard() }) .collect(), }); @@ -147,7 +144,7 @@ impl Storage pub fn create_entity(&mut self, uid: Uid) -> Result<(), EntityAlreadyExistsError> { - debug_assert_eq!(uid.kind(), UidKind::Entity); + debug_assert!(!uid.is_pair()); if self.entity_archetype_lookup.contains_key(&uid) { return Err(EntityAlreadyExistsError); @@ -768,14 +765,14 @@ mod tests { use crate::component::storage::archetype::Id as ArchetypeId; use crate::component::storage::Storage; - use crate::uid::{Kind as UidKind, Uid}; + use crate::uid::Uid; #[test] fn create_entity_works() { let mut new_storage = Storage::default(); - let uid = Uid::new_unique(UidKind::Entity); + let uid = Uid::new_unique(); new_storage.create_entity(uid).expect("Expected Ok"); diff --git a/engine-ecs/src/component/storage/archetype.rs b/engine-ecs/src/component/storage/archetype.rs index a7fe7ed..c5cce10 100644 --- a/engine-ecs/src/component/storage/archetype.rs +++ b/engine-ecs/src/component/storage/archetype.rs @@ -8,7 +8,7 @@ use std::slice::Iter as SliceIter; use hashbrown::HashMap; use crate::lock::Lock; -use crate::uid::{Kind as UidKind, Uid}; +use crate::uid::Uid; use crate::util::{Either, HashMapExt}; #[derive(Debug)] @@ -77,8 +77,6 @@ impl Archetype pub fn remove_entity(&mut self, entity_uid: Uid) -> Option<Entity> { - //debug_assert_eq!(entity_uid.kind(), UidKind::Entity); - let entity_index = self.entity_index_lookup.remove(&entity_uid)?; if self.entities.len() == 1 { @@ -124,14 +122,7 @@ impl Archetype component_id: Uid, ) -> MatchingComponentIter<'_> { - assert!( - component_id.kind() == UidKind::Component - || component_id.kind() == UidKind::Pair - ); - - if component_id.kind() == UidKind::Pair - && component_id.target_component() == Uid::wildcard() - { + if component_id.is_pair() && component_id.target() == Uid::wildcard() { return MatchingComponentIter { inner: Either::A( self.component_ids @@ -140,7 +131,7 @@ impl Archetype .zip(std::iter::repeat_n(component_id, self.component_ids.len())) .filter( (|((_, other_comp_id), component_id)| { - other_comp_id.kind() == UidKind::Pair + other_comp_id.is_pair() && other_comp_id.has_same_relation_as(*component_id) }) as MatchingComponentIterFilterFn, @@ -162,9 +153,8 @@ impl Archetype pub fn get_index_for_component(&self, component_id: Uid) -> Option<usize> { assert!( - component_id.kind() == UidKind::Component - || (component_id.kind() == UidKind::Pair - && component_id.target_component() != Uid::wildcard()) + !component_id.is_pair() + || (component_id.is_pair() && component_id.target() != Uid::wildcard()) ); self.component_index_lookup.get(&component_id).copied() @@ -182,17 +172,9 @@ impl Archetype pub fn contains_matching_component(&self, component_id: Uid) -> bool { - let component_id_kind = component_id.kind(); - - debug_assert!( - component_id_kind == UidKind::Component || component_id_kind == UidKind::Pair - ); - - if component_id.kind() == UidKind::Pair - && component_id.target_component() == Uid::wildcard() - { + if component_id.is_pair() && component_id.target() == Uid::wildcard() { return self.component_ids.iter().any(|other_comp_id| { - other_comp_id.kind() == UidKind::Pair + other_comp_id.is_pair() && other_comp_id.has_same_relation_as(component_id) }); } @@ -202,12 +184,9 @@ impl Archetype pub fn contains_component_with_exact_id(&self, component_id: Uid) -> bool { - let component_id_kind = component_id.kind(); - debug_assert!( - component_id_kind == UidKind::Component - || (component_id_kind == UidKind::Pair - && component_id.target_component() != Uid::wildcard()) + !component_id.is_pair() + || (component_id.is_pair() && component_id.target() != Uid::wildcard()) ); self.component_index_lookup.contains_key(&component_id) diff --git a/engine-ecs/src/component/storage/graph.rs b/engine-ecs/src/component/storage/graph.rs index 76200f9..add25e4 100644 --- a/engine-ecs/src/component/storage/graph.rs +++ b/engine-ecs/src/component/storage/graph.rs @@ -3,7 +3,7 @@ use std::vec::IntoIter as VecIntoIter; use hashbrown::{HashMap, HashSet}; use crate::component::storage::archetype::{Archetype, Id as ArchetypeId}; -use crate::uid::{Kind as UidKind, Uid}; +use crate::uid::Uid; use crate::util::{BorrowedOrOwned, StreamingIterator}; #[derive(Debug, Default)] @@ -250,11 +250,6 @@ impl ArchetypeNode insert_fn: impl FnOnce() -> ArchetypeEdges, ) -> &mut ArchetypeEdges { - debug_assert!(matches!( - component_id.kind(), - UidKind::Component | UidKind::Pair - )); - self.edges.entry(component_id).or_insert_with(insert_fn) } diff --git a/engine-ecs/src/entity.rs b/engine-ecs/src/entity.rs index ad9f179..f551de1 100644 --- a/engine-ecs/src/entity.rs +++ b/engine-ecs/src/entity.rs @@ -18,7 +18,7 @@ use crate::pair::{ Pair, WithWildcard as PairWithWildcard, }; -use crate::uid::{Kind as UidKind, Uid}; +use crate::uid::Uid; use crate::{EntityComponentRef, World}; pub mod obtainer; @@ -47,12 +47,12 @@ impl<'a> Handle<'a> /// /// # Panics /// Will panic if: - /// - The component's ID is not a component ID + /// - The component's ID is pair /// - The component is mutably borrowed elsewhere #[must_use] pub fn get<ComponentT: Component>(&self) -> Option<ComponentHandle<'a, ComponentT>> { - assert_eq!(ComponentT::id().kind(), UidKind::Component); + assert!(!ComponentT::id().is_pair()); let component = self.get_matching_components(ComponentT::id()).next()?; @@ -73,14 +73,14 @@ impl<'a> Handle<'a> /// /// # Panics /// Will panic if: - /// - The component's ID is not a component ID + /// - The component's ID is a pair /// - The component is borrowed elsewhere #[must_use] pub fn get_mut<ComponentT: Component>( &self, ) -> Option<ComponentHandleMut<'a, ComponentT>> { - assert_eq!(ComponentT::id().kind(), UidKind::Component); + assert!(!ComponentT::id().is_pair()); let component = self.get_matching_components(ComponentT::id()).next()?; @@ -100,7 +100,6 @@ impl<'a> Handle<'a> /// /// # Panics /// Will panic if: - /// - The ID is not a component/pair ID /// - The component is borrowed mutably elsewhere /// - The component type is incorrect #[must_use] @@ -109,11 +108,6 @@ impl<'a> Handle<'a> id: Uid, ) -> Option<ComponentHandle<'a, ComponentDataT>> { - assert!( - matches!(id.kind(), UidKind::Component | UidKind::Pair), - "ID {id:?} is not a component/pair ID" - ); - let component = self.get_matching_components(id).next()?; Some( @@ -133,7 +127,6 @@ impl<'a> Handle<'a> /// /// # Panics /// Will panic if: - /// - The ID is not a component/pair ID /// - The component is borrowed elsewhere /// - The component type is incorrect #[must_use] @@ -142,11 +135,6 @@ impl<'a> Handle<'a> id: Uid, ) -> Option<ComponentHandleMut<'a, ComponentDataT>> { - assert!( - matches!(id.kind(), UidKind::Component | UidKind::Pair), - "ID {id:?} is not a component/pair ID" - ); - let component = self.get_matching_components(id).next()?; Some( @@ -267,7 +255,7 @@ impl Declaration pub const fn new(create_func: fn(&mut World)) -> Self { Self { - uid: LazyLock::new(|| Uid::new_unique(UidKind::Entity)), + uid: LazyLock::new(|| Uid::new_unique()), create_func, } } diff --git a/engine-ecs/src/event.rs b/engine-ecs/src/event.rs index 15455b6..cec9269 100644 --- a/engine-ecs/src/event.rs +++ b/engine-ecs/src/event.rs @@ -1,6 +1,6 @@ use crate::lock::Lock; use crate::pair::Pair; -use crate::uid::{Kind as UidKind, Uid}; +use crate::uid::Uid; use crate::util::VecExt; pub mod component; @@ -53,7 +53,7 @@ impl NewEvents { let event_id = event.id(); - assert_eq!(event_id.kind(), UidKind::Pair); + assert!(event_id.is_pair()); if let Ok(event_index) = self .events diff --git a/engine-ecs/src/lib.rs b/engine-ecs/src/lib.rs index 70816b3..8b3b8c3 100644 --- a/engine-ecs/src/lib.rs +++ b/engine-ecs/src/lib.rs @@ -51,7 +51,7 @@ use crate::sole::{Single, Sole}; use crate::stats::Stats; use crate::system::observer::Observer; use crate::system::{Callbacks, Metadata as SystemMetadata, System, SystemComponent}; -use crate::uid::{Kind as UidKind, Uid}; +use crate::uid::Uid; pub mod actions; pub mod component; @@ -114,7 +114,7 @@ impl World where Comps: ComponentSequence, { - let entity_uid = Uid::new_unique(UidKind::Entity); + let entity_uid = Uid::new_unique(); self.create_entity_with_uid(entity_uid, components); @@ -165,7 +165,7 @@ impl World { let (system, mut system_callbacks) = observer.finish_observer(); - let ent_id = Uid::new_unique(UidKind::Entity); + let ent_id = Uid::new_unique(); self.create_ent( ent_id, @@ -353,7 +353,7 @@ impl World components: impl IntoIterator<Item = ComponentParts>, ) { - debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + debug_assert!(!entity_uid.is_pair()); if let Err(EntityAlreadyExistsError) = self.data.component_storage.create_entity(entity_uid) @@ -552,7 +552,7 @@ impl World continue; } - if comp_id.kind() == UidKind::Pair { + if comp_id.is_pair() { continue; } @@ -585,7 +585,7 @@ impl World fn emit_event_observers(&self, event_id: Uid, emitted_event: &EmittedEvent<'_>) { - assert_eq!(event_id.kind(), UidKind::Pair); + assert!(event_id.is_pair()); let query = Query::<(&SystemComponent,)>::from_flexible_query( self.flexible_query( diff --git a/engine-ecs/src/pair.rs b/engine-ecs/src/pair.rs index 0d353e3..eff0332 100644 --- a/engine-ecs/src/pair.rs +++ b/engine-ecs/src/pair.rs @@ -18,7 +18,7 @@ use crate::query::{ TermsBuilder as QueryTermsBuilder, TermsBuilderInterface, }; -use crate::uid::{Kind as UidKind, PairParams as UidPairParams, Uid, With as WithUid}; +use crate::uid::{PairParams as UidPairParams, Uid, With as WithUid}; use crate::util::impl_multiple; use crate::{Component, EntityComponentRef, World}; @@ -374,16 +374,15 @@ impl<'world, Relation, Target> WithWildcard<'world, Relation, Target> { let component_id = component_ref.id(); - assert!(component_id.kind() == UidKind::Pair); + assert!(component_id.is_pair()); assert!( Relation::uid() == Wildcard::uid() - || component_id.relation_component() == Relation::uid() + || component_id.relation() == Relation::uid() ); assert!( - Target::uid() == Wildcard::uid() - || component_id.target_component() == Target::uid() + Target::uid() == Wildcard::uid() || component_id.target() == Target::uid() ); assert!(Relation::uid() == Wildcard::uid() || Target::uid() == Wildcard::uid()); @@ -472,10 +471,10 @@ where .world .data .component_storage - .get_entity_archetype(self.component_ref.id().target_entity())?; + .get_entity_archetype(self.component_ref.id().target())?; let Some(archetype_entity) = - archetype.get_entity_by_id(self.component_ref.id().target_entity()) + archetype.get_entity_by_id(self.component_ref.id().target()) else { unreachable!(); }; diff --git a/engine-ecs/src/query.rs b/engine-ecs/src/query.rs index 5f13579..ad5f4dd 100644 --- a/engine-ecs/src/query.rs +++ b/engine-ecs/src/query.rs @@ -11,7 +11,7 @@ use crate::component::{ use crate::entity::Handle as EntityHandle; use crate::query::flexible::{Iter as FlexibleQueryIter, Query as FlexibleQuery}; use crate::system::{Metadata as SystemMetadata, Param as SystemParam}; -use crate::uid::{Kind as UidKind, Uid, With as WithUid}; +use crate::uid::{Uid, With as WithUid}; use crate::util::array_vec::ArrayVec; use crate::util::Array; use crate::World; @@ -353,7 +353,7 @@ impl<ComponentT: Component> TermWithField for &ComponentT _world: &'world World, ) -> Self::Field<'world> { - assert_eq!(ComponentT::id().kind(), UidKind::Component); + assert!(!ComponentT::id().is_pair()); let Some(component) = entity_handle .get_matching_components(ComponentT::id()) @@ -394,7 +394,7 @@ impl<ComponentT: Component> TermWithField for &mut ComponentT world: &'world World, ) -> Self::Field<'world> { - assert_eq!(ComponentT::id().kind(), UidKind::Component); + assert!(!ComponentT::id().is_pair()); let Some(component) = entity_handle .get_matching_components(ComponentT::id()) diff --git a/engine-ecs/src/uid.rs b/engine-ecs/src/uid.rs index bb393a1..26fbaee 100644 --- a/engine-ecs/src/uid.rs +++ b/engine-ecs/src/uid.rs @@ -1,5 +1,4 @@ use std::fmt::{Debug, Display, Formatter}; -use std::mem::transmute; use std::sync::atomic::{AtomicU32, Ordering}; use seq_macro::seq; @@ -13,16 +12,7 @@ static WILDCARD_ID: u32 = 1; const ID_BITS: BitMask<u64> = BitMask::new(gen_mask_64!(32..=63)); const RELATION_BITS: BitMask<u64> = BitMask::new(gen_mask_64!(6..=31)); -const KIND_BITS: BitMask<u64> = BitMask::new(gen_mask_64!(0..=1)); - -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[repr(u8)] -pub enum Kind -{ - Pair = 3, - Entity = 2, - Component = 1, -} +const IS_PAIR_BITS: BitMask<u64> = BitMask::new(1 << 0); /// A unique identifier. #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] @@ -38,12 +28,12 @@ impl Uid pub const FIRST_UNIQUE_ID: u32 = 5; /// Returns a new unique entity/component ID. - pub fn new_unique(kind: Kind) -> Self + pub fn new_unique() -> Self { let id = NEXT.fetch_add(1, Ordering::Relaxed); Self { - inner: ID_BITS.field_prep(u64::from(id)) | KIND_BITS.field_prep(kind as u64), + inner: ID_BITS.field_prep(u64::from(id)) | IS_PAIR_BITS.field_prep(0), } } @@ -52,7 +42,7 @@ impl Uid { Self { inner: ID_BITS.field_prep(u64::from(WILDCARD_ID)) - | KIND_BITS.field_prep(Kind::Component as u64), + | IS_PAIR_BITS.field_prep(0), } } @@ -63,22 +53,13 @@ impl Uid #[must_use] pub fn new_pair(params: &PairParams) -> Self { - assert_ne!( - params.relation.kind(), - Kind::Pair, - "Pair relation cannot be a pair" - ); - - assert_ne!( - params.target.kind(), - Kind::Pair, - "Pair target cannot be a pair" - ); + assert!(!params.relation.is_pair(), "Pair relation cannot be a pair"); + assert!(!params.target.is_pair(), "Pair target cannot be a pair"); Self { inner: ID_BITS.field_prep(u64::from(params.target.id())) | RELATION_BITS.field_prep(u64::from(params.relation.id())) - | KIND_BITS.field_prep(Kind::Pair as u64), + | IS_PAIR_BITS.field_prep(1), } } @@ -93,102 +74,72 @@ impl Uid } #[must_use] - pub fn kind(&self) -> Kind + pub fn is_pair(&self) -> bool { - let Ok(kind) = u8::try_from(self.inner.field_get(KIND_BITS)) else { - unreachable!("Uid kind does not fit in u8"); + let Ok(is_pair) = u8::try_from(self.inner.field_get(IS_PAIR_BITS)) else { + unreachable!(); }; - // SAFETY: The kind bits cannot be invalid since they are set using the Kind enum - // in the new_unique function - unsafe { transmute::<u8, Kind>(kind) } + is_pair == 1 } - /// If this `Uid` is a pair, returns the relation as a component `Uid`. + /// If this `Uid` is a pair, returns the relation `Uid`. /// /// # Panics /// Will panic if this `Uid` is not a pair. #[must_use] - pub fn relation_component(&self) -> Self + pub fn relation(&self) -> Self { - assert_eq!(self.kind(), Kind::Pair, "Uid is not a pair"); - - Self { - inner: ID_BITS.field_prep(u64::from(self.relation())) - | KIND_BITS.field_prep(Kind::Component as u64), - } - } + assert!(self.is_pair(), "Uid is not a pair"); - #[must_use] - pub fn has_same_relation_as(&self, other: Self) -> bool - { - self.relation() == other.relation() - } - - /// If this `Uid` is a pair, returns the relation as a entity `Uid`. - /// - /// # Panics - /// Will panic if this `Uid` is not a pair. - #[must_use] - pub fn relation_entity(&self) -> Self - { - assert_eq!(self.kind(), Kind::Pair, "Uid is not a pair"); + let Ok(relation) = u32::try_from(self.inner.field_get(RELATION_BITS)) else { + unreachable!("Uid relation does not fit in u32"); + }; Self { - inner: ID_BITS.field_prep(u64::from(self.relation())) - | KIND_BITS.field_prep(Kind::Entity as u64), + inner: ID_BITS.field_prep(u64::from(relation)) | IS_PAIR_BITS.field_prep(0), } } - /// If this `Uid` is a pair, returns the target as a component `Uid`. + /// Compares the relation of this pair `Uid` with the relation of another pair `Uid`. /// /// # Panics - /// Will panic if this `Uid` is not a pair. + /// Will panic if any of the `Uid`s are not a pair. #[must_use] - pub fn target_component(&self) -> Self + pub fn has_same_relation_as(&self, other: Self) -> bool { - assert_eq!(self.kind(), Kind::Pair, "Uid is not a pair"); - - Self { - inner: ID_BITS.field_prep(u64::from(self.id())) - | KIND_BITS.field_prep(Kind::Component as u64), - } + self.relation() == other.relation() } - /// If this `Uid` is a pair, returns the target as a entity `Uid`. + /// If this `Uid` is a pair, returns the target `Uid`. /// /// # Panics /// Will panic if this `Uid` is not a pair. #[must_use] - pub fn target_entity(&self) -> Self + pub fn target(&self) -> Self { - assert_eq!(self.kind(), Kind::Pair, "Uid is not a pair"); + assert!(self.is_pair(), "Uid is not a pair"); Self { - inner: ID_BITS.field_prep(u64::from(self.id())) - | KIND_BITS.field_prep(Kind::Entity as u64), + inner: ID_BITS.field_prep(u64::from(self.id())) | IS_PAIR_BITS.field_prep(0), } } - - fn relation(self) -> u32 - { - let Ok(relation) = u32::try_from(self.inner.field_get(RELATION_BITS)) else { - unreachable!("Uid relation does not fit in u32"); - }; - - relation - } } impl Debug for Uid { fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result { - formatter - .debug_struct("Uid") - .field("id", &self.id()) - .field("kind", &self.kind()) - .finish_non_exhaustive() + let mut debug_struct = formatter.debug_struct("Uid"); + + if self.is_pair() { + return debug_struct + .field("relation", &self.relation()) + .field("target", &self.target()) + .finish(); + } + + debug_struct.field("id", &self.id()).finish() } } @@ -196,13 +147,8 @@ impl Display for Uid { fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result { - if self.kind() == Kind::Pair { - return write!( - formatter, - "({}, {})", - self.relation(), - self.target_component() - ); + if self.is_pair() { + return write!(formatter, "({}, {})", self.relation(), self.target()); } if *self == Uid::wildcard() { |
