summaryrefslogtreecommitdiff
path: root/ecs/src/uid.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/uid.rs')
-rw-r--r--ecs/src/uid.rs261
1 files changed, 0 insertions, 261 deletions
diff --git a/ecs/src/uid.rs b/ecs/src/uid.rs
deleted file mode 100644
index bb393a1..0000000
--- a/ecs/src/uid.rs
+++ /dev/null
@@ -1,261 +0,0 @@
-use std::fmt::{Debug, Display, Formatter};
-use std::mem::transmute;
-use std::sync::atomic::{AtomicU32, Ordering};
-
-use seq_macro::seq;
-
-use crate::component::Component;
-use crate::util::{gen_mask_64, Array, BitMask, NumberExt};
-
-static NEXT: AtomicU32 = AtomicU32::new(Uid::FIRST_UNIQUE_ID);
-
-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,
-}
-
-/// A unique identifier.
-#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Uid
-{
- inner: u64,
-}
-
-impl Uid
-{
- /// The id part of the first unique `Uid`. The ids `0..Uid::FIRST_UNIQUE_ID` are
- /// reserved.
- pub const FIRST_UNIQUE_ID: u32 = 5;
-
- /// Returns a new unique entity/component ID.
- pub fn new_unique(kind: Kind) -> 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),
- }
- }
-
- #[must_use]
- pub fn wildcard() -> Self
- {
- Self {
- inner: ID_BITS.field_prep(u64::from(WILDCARD_ID))
- | KIND_BITS.field_prep(Kind::Component as u64),
- }
- }
-
- /// Returns a new pair UID.
- ///
- /// # Panics
- /// Will panic if either the given relation or target is a pair 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"
- );
-
- 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),
- }
- }
-
- #[must_use]
- pub fn id(&self) -> u32
- {
- let Ok(id) = u32::try_from(self.inner.field_get(ID_BITS)) else {
- unreachable!("Uid id does not fit in u32");
- };
-
- id
- }
-
- #[must_use]
- pub fn kind(&self) -> Kind
- {
- let Ok(kind) = u8::try_from(self.inner.field_get(KIND_BITS)) else {
- unreachable!("Uid kind does not fit in u8");
- };
-
- // 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) }
- }
-
- /// If this `Uid` is a pair, returns the relation as a component `Uid`.
- ///
- /// # Panics
- /// Will panic if this `Uid` is not a pair.
- #[must_use]
- pub fn relation_component(&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),
- }
- }
-
- #[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");
-
- Self {
- inner: ID_BITS.field_prep(u64::from(self.relation()))
- | KIND_BITS.field_prep(Kind::Entity as u64),
- }
- }
-
- /// If this `Uid` is a pair, returns the target as a component `Uid`.
- ///
- /// # Panics
- /// Will panic if this `Uid` is not a pair.
- #[must_use]
- pub fn target_component(&self) -> Self
- {
- 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),
- }
- }
-
- /// If this `Uid` is a pair, returns the target as a entity `Uid`.
- ///
- /// # Panics
- /// Will panic if this `Uid` is not a pair.
- #[must_use]
- pub fn target_entity(&self) -> Self
- {
- 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::Entity as u64),
- }
- }
-
- 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()
- }
-}
-
-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 == Uid::wildcard() {
- return write!(formatter, "*");
- }
-
- write!(formatter, "{}", self.id())
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct PairParams
-{
- pub relation: Uid,
- pub target: Uid,
-}
-
-pub trait With
-{
- fn uid() -> Uid;
-}
-
-impl<ComponentT: Component> With for ComponentT
-{
- fn uid() -> Uid
- {
- Self::id()
- }
-}
-
-pub trait WithUidTuple
-{
- type UidsArray: Array<Uid>;
-
- fn uids() -> Self::UidsArray;
-}
-
-macro_rules! impl_with_uid_tuple {
- ($c: tt) => {
- seq!(I in 0..=$c {
- impl<#(WithUid~I: With,)*> WithUidTuple for (#(WithUid~I,)*)
- {
- type UidsArray = [Uid; $c + 1];
-
- fn uids() -> Self::UidsArray
- {
- [#(WithUid~I::uid(),)*]
- }
- }
- });
- };
-}
-
-seq!(C in 0..=16 {
- impl_with_uid_tuple!(C);
-});