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#[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 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 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 pub fn builder() -> EntityBuilder {
55 EntityBuilder::new()
56 }
57
58 pub fn is_static(&self) -> bool {
60 self.kind.contains(EntityKind::STATIC)
61 }
62
63 pub fn is_component(&self) -> bool {
65 self.kind.contains(EntityKind::COMPONENT)
66 }
67 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 #[inline(always)]
92 pub fn index(&self) -> EntityIndex {
93 self.index
94 }
95
96 #[inline(always)]
98 pub fn gen(&self) -> EntityGen {
99 self.gen
100 }
101
102 #[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 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
218 pub struct EntityKind: u16 {
219 const COMPONENT = 1;
221 const STATIC = 2;
224 }
225}
226
227impl Default for EntityKind {
228 fn default() -> Self {
229 Self::empty()
230 }
231}
232
233pub type EntityGen = NonZeroU16;
235pub 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#[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}