summaryrefslogtreecommitdiff
path: root/engine-ecs/src/uid.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-ecs/src/uid.rs')
-rw-r--r--engine-ecs/src/uid.rs130
1 files changed, 38 insertions, 92 deletions
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() {