flax/entity/
mod.rs

1mod builder;
2mod store;
3
4use core::fmt;
5use core::num::NonZeroU16;
6use core::sync::atomic::{AtomicU32, Ordering};
7
8pub use builder::*;
9pub(crate) use store::*;
10
11use crate::EntityIds;
12
13pub(crate) const DEFAULT_GEN: EntityGen = unsafe { EntityGen::new_unchecked(1) };
14
15/// Represents an entity identifier.
16/// An entity can either declare an identifier spawned into the world,
17/// a static entity, or a component.
18#[derive(PartialOrd, Clone, Copy, PartialEq, Eq, Ord, Hash)]
19pub struct Entity {
20    pub(crate) index: EntityIndex,
21    pub(crate) gen: EntityGen,
22    pub(crate) kind: EntityKind,
23}
24
25impl Entity {
26    /// The lowest possible entity
27    ///
28    /// May or may not refer to a valid entity.
29    pub(crate) const MIN: Self = unsafe {
30        Entity {
31            index: 0,
32            gen: NonZeroU16::new_unchecked(1),
33            kind: EntityKind::empty(),
34        }
35    };
36
37    /// The greatest possible entity
38    ///
39    /// May or may not refer to a valid entity.
40    pub(crate) const MAX: Self = unsafe {
41        Entity {
42            index: u32::MAX,
43            gen: NonZeroU16::new_unchecked(u16::MAX),
44            kind: EntityKind::all(),
45        }
46    };
47
48    pub(crate) fn from_parts(index: EntityIndex, gen: EntityGen, kind: EntityKind) -> Self {
49        Self { index, gen, kind }
50    }
51
52    /// Creates a new entity builder.
53    /// See [crate::EntityBuilder] for more details.
54    pub fn builder() -> EntityBuilder {
55        EntityBuilder::new()
56    }
57
58    /// Returns true if the id is a static id
59    pub fn is_static(&self) -> bool {
60        self.kind.contains(EntityKind::STATIC)
61    }
62
63    /// Returns true if the id is a component id
64    pub fn is_component(&self) -> bool {
65        self.kind.contains(EntityKind::COMPONENT)
66    }
67    ///
68    /// Generate a new static id
69    pub fn acquire_static_id(kind: EntityKind) -> Entity {
70        let index = STATIC_IDS.fetch_add(1, Ordering::Relaxed);
71        Entity::from_parts(index, DEFAULT_GEN, kind | EntityKind::STATIC)
72    }
73
74    #[doc(hidden)]
75    pub fn static_init(id: &AtomicU32, kind: EntityKind) -> Self {
76        let index = match id.fetch_update(Ordering::Acquire, Ordering::Relaxed, |v| {
77            if v != EntityIndex::MAX {
78                None
79            } else {
80                Some(Self::acquire_static_id(kind | EntityKind::STATIC).index())
81            }
82        }) {
83            Ok(_) => id.load(Ordering::Acquire),
84            Err(old) => old,
85        };
86
87        Self::from_parts(index, DEFAULT_GEN, kind | EntityKind::STATIC)
88    }
89
90    /// Returns the entity index
91    #[inline(always)]
92    pub fn index(&self) -> EntityIndex {
93        self.index
94    }
95
96    /// Returns the entity generation
97    #[inline(always)]
98    pub fn gen(&self) -> EntityGen {
99        self.gen
100    }
101
102    /// Returns the entity kind
103    #[inline(always)]
104    pub fn kind(&self) -> EntityKind {
105        self.kind
106    }
107}
108
109#[cfg(feature = "serde")]
110mod serde_impl {
111    use serde::{
112        de::{self, Unexpected, Visitor},
113        ser::SerializeTupleStruct,
114        Deserialize, Serialize,
115    };
116
117    use super::{Entity, EntityKind};
118
119    impl Serialize for EntityKind {
120        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
121        where
122            S: serde::Serializer,
123        {
124            self.bits().serialize(serializer)
125        }
126    }
127
128    impl<'de> Deserialize<'de> for EntityKind {
129        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
130        where
131            D: serde::Deserializer<'de>,
132        {
133            deserializer.deserialize_u16(EntityKindVisitor)
134        }
135    }
136
137    struct EntityKindVisitor;
138
139    impl<'de> Visitor<'de> for EntityKindVisitor {
140        type Value = EntityKind;
141
142        fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
143            write!(f, "A valid entity kind bitfield")
144        }
145
146        fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
147        where
148            E: de::Error,
149        {
150            EntityKind::from_bits(v)
151                .ok_or_else(|| de::Error::invalid_value(Unexpected::Unsigned(v as _), &self))
152        }
153
154        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
155        where
156            E: de::Error,
157        {
158            EntityKind::from_bits(v as _)
159                .ok_or_else(|| de::Error::invalid_value(Unexpected::Unsigned(v as _), &self))
160        }
161    }
162
163    impl Serialize for Entity {
164        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165        where
166            S: serde::Serializer,
167        {
168            let mut state = serializer.serialize_tuple_struct("Entity", 3)?;
169            state.serialize_field(&self.index)?;
170            state.serialize_field(&self.gen)?;
171            state.serialize_field(&self.kind)?;
172            state.end()
173        }
174    }
175
176    struct EntityVisitor;
177
178    impl<'de> Deserialize<'de> for Entity {
179        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
180        where
181            D: serde::Deserializer<'de>,
182        {
183            deserializer.deserialize_tuple_struct("Entity", 3, EntityVisitor)
184        }
185    }
186
187    impl<'de> Visitor<'de> for EntityVisitor {
188        type Value = Entity;
189
190        fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
191            write!(formatter, "a sequence of entity parts")
192        }
193
194        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
195        where
196            A: serde::de::SeqAccess<'de>,
197        {
198            let index = seq
199                .next_element()?
200                .ok_or_else(|| de::Error::invalid_length(0, &self))?;
201            let gen = seq
202                .next_element()?
203                .ok_or_else(|| de::Error::invalid_length(1, &self))?;
204            let kind = seq
205                .next_element()?
206                .ok_or_else(|| de::Error::invalid_length(2, &self))?;
207
208            Ok(Entity::from_parts(index, gen, kind))
209        }
210    }
211}
212
213static STATIC_IDS: AtomicU32 = AtomicU32::new(1);
214
215bitflags::bitflags! {
216    /// Declares the roles an entity id serves
217    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
218    pub struct EntityKind: u16 {
219        /// The entity is a component
220        const COMPONENT = 1;
221        /// The entity is created via static initialization and is never
222        /// despawned
223        const STATIC = 2;
224    }
225}
226
227impl Default for EntityKind {
228    fn default() -> Self {
229        Self::empty()
230    }
231}
232
233/// The entity id version
234pub type EntityGen = NonZeroU16;
235/// The index of the entity in the entity store
236pub type EntityIndex = u32;
237
238impl fmt::Debug for Entity {
239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240        let Self { index, gen, kind } = *self;
241        if kind.is_empty() {
242            write!(f, "{index}v{gen}")
243        } else {
244            write!(f, "{index}v{gen} [{kind:?}]")
245        }
246    }
247}
248
249impl fmt::Display for Entity {
250    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
251        let Self {
252            index,
253            gen,
254            kind: _,
255        } = *self;
256        write!(f, "{index}v{gen}")
257    }
258}
259
260/// Access the entity ids in a query
261#[inline]
262pub fn entity_ids() -> EntityIds {
263    EntityIds
264}
265
266#[cfg(test)]
267mod tests {
268
269    use core::mem::{align_of, size_of};
270
271    use crate::{entity::EntityKind, Entity};
272
273    use super::EntityStore;
274    #[test]
275    fn entity_store() {
276        let mut store = EntityStore::new(EntityKind::COMPONENT);
277
278        let a = store.spawn("a");
279        let b = store.spawn("b");
280        let c = store.spawn("c");
281
282        store.despawn(b).unwrap();
283
284        assert!(store.is_alive(a));
285        assert!(!store.is_alive(b));
286        assert!(store.is_alive(c));
287        assert_eq!(store.get(c), Some(&"c"));
288        assert_eq!(store.get(b), None);
289
290        let d = store.spawn("d");
291        assert_eq!(d.index(), b.index());
292
293        assert!(store.get(b).is_none());
294        assert_eq!(store.get(d), Some(&"d"));
295    }
296
297    #[test]
298    fn entity_size() {
299        assert_eq!(size_of::<Entity>(), 8);
300        assert_eq!(align_of::<Entity>(), 4);
301        assert_eq!(size_of::<Option<Entity>>(), 8);
302    }
303}