Skip to main content

shipyard/entities/
mod.rs

1mod iterator;
2
3pub use iterator::EntitiesIter;
4
5use crate::add_component::AddComponent;
6use crate::add_distinct_component::AddDistinctComponent;
7use crate::add_entity::AddEntity;
8use crate::entity_id::EntityId;
9use crate::error;
10use crate::memory_usage::StorageMemoryUsage;
11use crate::reserve::{BulkEntityIter, BulkReserve};
12use crate::storage::{SBoxBuilder, Storage};
13use crate::tracking::TrackingTimestamp;
14use alloc::boxed::Box;
15use alloc::vec::Vec;
16use core::any::type_name;
17use core::iter::repeat_with;
18use core::mem::size_of;
19
20/// Holds the handles to all entities: living, removed and dead.
21///
22/// A living entity is an entity currently present, with or without component.
23///
24/// Removed and dead entities don't have any component.
25///
26/// The big difference is that removed ones can become alive again.
27///
28/// The life cycle of an entity looks like this:
29///
30/// Generation -> Deletion -> Dead\
31///          
32///       ⬑----------↵
33// An entity starts with a generation at 0, each removal will increase it by 1
34// until genration::MAX() where the entity is considered dead.
35// Removed entities form a linked list inside the vector, using their index part to point to the next.
36// Removed entities are added to one end and removed from the other.
37// Dead entities are simply never added to the linked list.
38pub struct Entities {
39    pub(crate) data: Vec<EntityId>,
40    list: Option<(usize, usize)>,
41    on_deletion: Option<Box<dyn FnMut(EntityId) + Send + Sync>>,
42}
43
44impl Entities {
45    #[inline]
46    pub(crate) fn new() -> Self {
47        Entities {
48            data: Vec::new(),
49            list: None,
50            on_deletion: None,
51        }
52    }
53    /// Returns `true` if `entity` matches a living entity.
54    #[inline]
55    pub fn is_alive(&self, entity: EntityId) -> bool {
56        if let Some(&self_entity) = self.data.get(entity.uindex()) {
57            entity == self_entity
58        } else {
59            false
60        }
61    }
62    /// Adds `component` to `entity`, multiple components can be added at the same time using a tuple.  
63    /// `Entities` is only borrowed immutably.  
64    ///
65    /// ### Panics
66    ///
67    /// - `entity` is not alive.
68    ///
69    /// ### Example
70    /// ```
71    /// use shipyard::{Component, EntitiesView, ViewMut, World};
72    ///
73    /// #[derive(Component)]
74    /// struct U32(u32);
75    ///
76    /// let mut world = World::new();
77    ///
78    /// let entity = world.add_entity(());
79    ///
80    /// let (entities, mut u32s) = world.borrow::<(EntitiesView, ViewMut<U32>)>().unwrap();
81    ///
82    /// entities.add_component(entity, &mut u32s, U32(0));
83    /// ```
84    #[track_caller]
85    #[inline]
86    pub fn add_component<C, S: AddComponent<C>>(
87        &self,
88        entity: EntityId,
89        mut storages: S,
90        component: C,
91    ) {
92        if self.is_alive(entity) {
93            storages.add_component_unchecked(entity, component);
94        } else {
95            panic!("{:?}", error::AddComponent::EntityIsNotAlive);
96        }
97    }
98    /// Adds `component` to `entity`, multiple components can be added at the same time using a tuple.  
99    /// If the entity already has this component, it won't be replaced. Very useful if you want accurate modification tracking.  
100    /// `Entities` is only borrowed immutably.  
101    ///
102    /// Returns `true` if the component was added.
103    ///
104    /// ### Panics
105    ///
106    /// - `entity` is not alive.
107    ///
108    /// ### Example
109    /// ```
110    /// use shipyard::{Component, EntitiesView, ViewMut, World};
111    ///
112    /// #[derive(Component, PartialEq)]
113    /// struct U32(u32);
114    ///
115    /// let mut world = World::new();
116    ///
117    /// let entity = world.add_entity(());
118    ///
119    /// let (entities, mut u32s) = world.borrow::<(EntitiesView, ViewMut<U32>)>().unwrap();
120    ///
121    /// assert!(entities.add_distinct_component(entity, &mut u32s, U32(0)));
122    /// assert!(!entities.add_distinct_component(entity, &mut u32s, U32(0)));
123    /// ```
124    #[track_caller]
125    #[inline]
126    pub fn add_distinct_component<S: AddDistinctComponent>(
127        &self,
128        entity: EntityId,
129        mut storages: S,
130        component: S::Component,
131    ) -> bool {
132        if self.is_alive(entity) {
133            storages.add_distinct_component_unchecked(entity, component)
134        } else {
135            panic!("{:?}", error::AddComponent::EntityIsNotAlive);
136        }
137    }
138    pub(crate) fn generate(&mut self) -> EntityId {
139        if let Some((new, ref mut old)) = self.list {
140            let old_index = *old;
141
142            if new == *old {
143                self.list = None;
144            } else {
145                // SAFE old_index is always valid
146                *old = unsafe { self.data.get_unchecked(old_index).uindex() };
147            }
148            // SAFE old_index is always valid
149            unsafe {
150                self.data
151                    .get_unchecked_mut(old_index)
152                    .set_index(old_index as u64);
153                *self.data.get_unchecked(old_index)
154            }
155        } else {
156            let entity_id = EntityId::new(self.data.len() as u64);
157            self.data.push(entity_id);
158            entity_id
159        }
160    }
161    pub(crate) fn bulk_generate(&mut self, count: usize) -> &[EntityId] {
162        self.data
163            .extend((self.data.len() as u64..(self.data.len() + count) as u64).map(EntityId::new));
164
165        &self.data[self.data.len() - count..self.data.len()]
166    }
167    /// Deletes an entity, returns true if the entity was alive.  
168    /// If the entity has components, they will not be deleted and still be accessible using this id.
169    pub fn delete_unchecked(&mut self, entity_id: EntityId) -> bool {
170        if self.is_alive(entity_id) {
171            // SAFE we checked for OOB
172            if unsafe {
173                self.data
174                    .get_unchecked_mut(entity_id.uindex())
175                    .bump_gen()
176                    .is_ok()
177            } {
178                if let Some((ref mut new, _)) = self.list {
179                    // SAFE new is always in bound
180                    unsafe {
181                        self.data
182                            .get_unchecked_mut(*new)
183                            .set_index(entity_id.index())
184                    };
185                    unsafe {
186                        self.data
187                            .get_unchecked_mut(entity_id.uindex())
188                            .set_index(EntityId::max_index())
189                    };
190                    *new = entity_id.uindex();
191                } else {
192                    unsafe {
193                        self.data
194                            .get_unchecked_mut(entity_id.uindex())
195                            .set_index(EntityId::max_index())
196                    };
197                    self.list = Some((entity_id.uindex(), entity_id.uindex()));
198                }
199            }
200
201            if let Some(on_deletion) = &mut self.on_deletion {
202                (on_deletion)(entity_id)
203            }
204
205            true
206        } else {
207            false
208        }
209    }
210    /// Stores `component` in a new entity and returns its [`EntityId`].  
211    /// Multiple components can be added at the same time using a tuple.
212    ///
213    /// ### Example:
214    /// ```
215    /// use shipyard::{Component, EntitiesViewMut, ViewMut, World};
216    ///
217    /// #[derive(Component, Debug, PartialEq, Eq)]
218    /// struct U32(u32);
219    ///
220    /// #[derive(Component, Debug, PartialEq, Eq)]
221    /// struct USIZE(usize);
222    ///
223    /// let world = World::new();
224    ///
225    /// let (mut entities, mut usizes, mut u32s) = world
226    ///     .borrow::<(EntitiesViewMut, ViewMut<USIZE>, ViewMut<U32>)>()
227    ///     .unwrap();
228    ///
229    /// let entity = entities.add_entity((&mut usizes, &mut u32s), (USIZE(0), U32(1)));
230    /// assert_eq!(usizes[entity], USIZE(0));
231    /// assert_eq!(u32s[entity], U32(1));
232    /// ```
233    ///
234    /// [`EntityId`]: crate::entity_id::EntityId
235    #[inline]
236    pub fn add_entity<T: AddEntity>(
237        &mut self,
238        mut storages: T,
239        component: T::Component,
240    ) -> EntityId {
241        let entity_id = self.generate();
242        AddEntity::add_entity(&mut storages, entity_id, component);
243        entity_id
244    }
245    /// Creates multiple new entities and returns an iterator yielding the new [`EntityId`]s.  
246    /// Multiple components can be added at the same time using a tuple.
247    ///
248    /// ### Example
249    ///
250    /// ```
251    /// use shipyard::{Component, EntitiesViewMut, ViewMut, World};
252    ///
253    /// #[derive(Component)]
254    /// struct U32(u32);
255    ///
256    /// #[derive(Component)]
257    /// struct USIZE(usize);
258    ///
259    /// let world = World::new();
260    ///
261    /// let (mut entities, mut usizes, mut u32s) = world
262    ///     .borrow::<(EntitiesViewMut, ViewMut<USIZE>, ViewMut<U32>)>()
263    ///     .unwrap();
264    ///
265    /// let new_entities =
266    ///     entities.bulk_add_entity((&mut u32s, &mut usizes), (10..20).map(|i| (U32(i as u32), USIZE(i))));
267    /// ```
268    ///
269    /// [`EntityId`]: crate::entity_id::EntityId
270    pub fn bulk_add_entity<T: AddEntity + BulkReserve, I: IntoIterator<Item = T::Component>>(
271        &mut self,
272        mut storages: T,
273        component: I,
274    ) -> BulkEntityIter<'_> {
275        let mut iter = component.into_iter();
276        let len = iter.size_hint().0;
277
278        let entities_len = self.data.len();
279        let new_entities = self.bulk_generate(len);
280
281        storages.bulk_reserve(new_entities);
282        for (component, id) in (&mut iter).zip(new_entities.iter().copied()) {
283            AddEntity::add_entity(&mut storages, id, component);
284        }
285
286        // have to use two loops because of self borrow
287        for (component, id) in iter.zip(repeat_with(|| self.generate())) {
288            AddEntity::add_entity(&mut storages, id, component);
289        }
290
291        BulkEntityIter {
292            iter: self.data[entities_len..].iter().copied(),
293            slice: &self.data[entities_len..],
294        }
295    }
296    /// Creates an iterator over all entities.
297    #[inline]
298    pub fn iter(&self) -> EntitiesIter<'_> {
299        self.into_iter()
300    }
301    /// Make the given entity alive.  
302    /// Does nothing if an entity with a greater generation is already at this index.  
303    /// Returns `true` if the entity is successfully spawned.
304    pub fn spawn(&mut self, entity: EntityId) -> bool {
305        if let Some(&old_entity) = self.data.get(entity.index() as usize) {
306            if self.is_alive(old_entity) {
307                if old_entity.gen() <= entity.gen() {
308                    self.data[entity.uindex()] = entity;
309
310                    true
311                } else {
312                    false
313                }
314            } else if let Some((new, old)) = self.list {
315                if old_entity.gen() <= entity.gen() + 1 {
316                    // pop from removed list
317                    if entity.uindex() == old {
318                        if new == old {
319                            self.list = None;
320                        } else {
321                            self.list = Some((new, self.data[entity.uindex()].uindex()));
322                        }
323                    } else {
324                        let mut current_index = old;
325
326                        while self.data[current_index].index() != entity.index()
327                            && self.data[current_index].uindex() != new
328                        {
329                            current_index = self.data[current_index].uindex();
330                        }
331
332                        if self.data[current_index].uindex() == new {
333                            self.data[current_index].set_index(EntityId::max_index());
334                            self.list = Some((current_index, old));
335                        } else {
336                            let next_index = self.data[self.data[current_index].uindex()].index();
337                            self.data[current_index].set_index(next_index);
338                        }
339                    }
340
341                    self.data[entity.uindex()] = entity;
342
343                    true
344                } else {
345                    false
346                }
347            } else {
348                false
349            }
350        } else {
351            let old_len = self.data.len();
352            self.data.resize(entity.uindex() + 1, EntityId::new(0));
353
354            if self.data.len() - old_len > 1 {
355                // add to removed list
356                if let Some((new, _)) = &mut self.list {
357                    self.data[*new].set_index(old_len as u64);
358
359                    *new = entity.uindex() - 1;
360                } else {
361                    self.list = Some((entity.uindex() - 1, old_len));
362                }
363
364                for (e, index) in self.data[old_len..entity.uindex() - 1]
365                    .iter_mut()
366                    .zip(old_len as u64 + 1..)
367                {
368                    e.set_index(index);
369                }
370
371                self.data[entity.uindex() - 1].set_index(EntityId::max_index());
372            }
373
374            self.data[entity.uindex()] = entity;
375
376            true
377        }
378    }
379
380    /// Sets the on entity deletion callback.
381    pub fn on_deletion(&mut self, f: impl FnMut(EntityId) + Send + Sync + 'static) {
382        self.on_deletion = Some(Box::new(f));
383    }
384
385    /// Remove the on entity deletion callback.
386    pub fn take_on_deletion(&mut self) -> Option<Box<dyn FnMut(EntityId) + Send + Sync + 'static>> {
387        self.on_deletion.take()
388    }
389}
390
391impl Storage for Entities {
392    fn clear(&mut self, _current: TrackingTimestamp) {
393        if self.data.is_empty() {
394            return;
395        }
396
397        // the first value can be anything but self.data.len() - 1
398        // otherwise we would set data[len - 1].index to len - 1 and not delete it
399        let mut last_alive = if self.data.len() as u64 == EntityId::max_index() {
400            0
401        } else {
402            EntityId::max_index()
403        };
404        for (i, id) in self.data.iter_mut().enumerate().rev() {
405            let target = last_alive;
406            let id_before_bump = *id;
407
408            if id.bump_gen().is_ok() {
409                last_alive = i as u64;
410
411                if let Some(on_deletion) = &mut self.on_deletion {
412                    (on_deletion)(id_before_bump)
413                }
414            }
415
416            id.set_index(target);
417        }
418
419        let begin = self
420            .data
421            .iter()
422            .position(|id| id.gen() < EntityId::max_gen())
423            .unwrap();
424        let end = self
425            .data
426            .iter()
427            .rev()
428            .position(|id| id.gen() < EntityId::max_gen())
429            .unwrap();
430        self.list = Some((self.data.len() - end - 1, begin));
431    }
432
433    fn memory_usage(&self) -> Option<StorageMemoryUsage> {
434        Some(StorageMemoryUsage {
435            storage_name: type_name::<Self>().into(),
436            allocated_memory_bytes: (self.data.capacity() * size_of::<EntityId>())
437                + size_of::<Entities>(),
438            used_memory_bytes: (self.data.len() * size_of::<EntityId>()) + size_of::<Entities>(),
439            component_count: self.data.len(),
440        })
441    }
442
443    #[inline]
444    fn is_empty(&self) -> bool {
445        self.data.is_empty()
446    }
447
448    #[inline]
449    fn move_component_from(
450        &mut self,
451        _other_all_storages: &mut crate::all_storages::AllStorages,
452        _from: EntityId,
453        _to: EntityId,
454        _current: TrackingTimestamp,
455        _other_current: TrackingTimestamp,
456    ) {
457        // Do nothing here so this function can be used to implement both move component and move entity.
458    }
459
460    #[inline]
461    fn try_clone(&self, _other_current: TrackingTimestamp) -> Option<SBoxBuilder> {
462        Some(SBoxBuilder::new(Entities {
463            data: self.data.clone(),
464            list: self.list,
465            on_deletion: None,
466        }))
467    }
468
469    #[inline]
470    fn clone_component_to(
471        &self,
472        _other_all_storages: &mut crate::all_storages::AllStorages,
473        _from: EntityId,
474        _to: EntityId,
475        _other_current: TrackingTimestamp,
476    ) {
477        // Do nothing here so this function can be used to implement both clone component and clone entity.
478    }
479}
480
481#[test]
482fn entities() {
483    let mut entities = Entities::new();
484
485    let key00 = entities.generate();
486    let key10 = entities.generate();
487
488    assert_eq!(key00.index(), 0);
489    assert_eq!(key00.gen(), 0);
490    assert_eq!(key10.index(), 1);
491    assert_eq!(key10.gen(), 0);
492
493    assert!(entities.delete_unchecked(key00));
494    assert!(!entities.delete_unchecked(key00));
495    let key01 = entities.generate();
496
497    assert_eq!(key01.index(), 0);
498    assert_eq!(key01.gen(), 1);
499
500    assert!(entities.delete_unchecked(key10));
501    assert!(entities.delete_unchecked(key01));
502    let key11 = entities.generate();
503    let key02 = entities.generate();
504
505    assert_eq!(key11.index(), 1);
506    assert_eq!(key11.gen(), 1);
507    assert_eq!(key02.index(), 0);
508    assert_eq!(key02.gen(), 2);
509
510    let last_key = EntityId::new_from_index_and_gen(0, EntityId::max_gen());
511    entities.data[0] = last_key;
512    assert!(entities.delete_unchecked(last_key));
513    assert_eq!(entities.list, None);
514    let dead = entities.generate();
515    assert_eq!(dead.index(), 2);
516    assert_eq!(dead.gen(), 0);
517}
518
519#[test]
520fn iterator() {
521    let mut entities = Entities::new();
522
523    entities.add_entity((), ());
524    entities.add_entity((), ());
525    entities.add_entity((), ());
526
527    let mut iter = entities.iter();
528
529    let id0 = iter.next().unwrap();
530    assert_eq!(id0.index(), 0);
531    assert_eq!(id0.gen(), 0);
532
533    let id1 = iter.next().unwrap();
534    assert_eq!(id1.index(), 1);
535    assert_eq!(id1.gen(), 0);
536
537    let id2 = iter.next().unwrap();
538    assert_eq!(id2.index(), 2);
539    assert_eq!(id2.gen(), 0);
540
541    assert!(iter.next().is_none());
542
543    entities.delete_unchecked(id0);
544    entities.delete_unchecked(id1);
545    entities.add_entity((), ());
546
547    let mut iter = entities.iter();
548
549    let id = iter.next().unwrap();
550    assert_eq!(id.index(), 0);
551    assert_eq!(id.gen(), 1);
552
553    let id = iter.next().unwrap();
554    assert_eq!(id.index(), 2);
555    assert_eq!(id.gen(), 0);
556
557    assert!(iter.next().is_none());
558}