Thanks to visit codestin.com
Credit goes to docs.rs

bevy_ecs/storage/
sparse_set.rs

1use crate::{
2    change_detection::MaybeLocation,
3    component::{CheckChangeTicks, ComponentId, ComponentInfo, ComponentTicks, Tick, TickCells},
4    entity::{Entity, EntityRow},
5    storage::{Column, TableRow},
6};
7use alloc::{boxed::Box, vec::Vec};
8use bevy_ptr::{OwningPtr, Ptr};
9use core::{cell::UnsafeCell, hash::Hash, marker::PhantomData, panic::Location};
10use nonmax::{NonMaxU32, NonMaxUsize};
11
12#[derive(Debug)]
13pub(crate) struct SparseArray<I, V = I> {
14    values: Vec<Option<V>>,
15    marker: PhantomData<I>,
16}
17
18/// A space-optimized version of [`SparseArray`] that cannot be changed
19/// after construction.
20#[derive(Debug)]
21pub(crate) struct ImmutableSparseArray<I, V = I> {
22    values: Box<[Option<V>]>,
23    marker: PhantomData<I>,
24}
25
26impl<I: SparseSetIndex, V> Default for SparseArray<I, V> {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32impl<I, V> SparseArray<I, V> {
33    #[inline]
34    pub const fn new() -> Self {
35        Self {
36            values: Vec::new(),
37            marker: PhantomData,
38        }
39    }
40}
41
42macro_rules! impl_sparse_array {
43    ($ty:ident) => {
44        impl<I: SparseSetIndex, V> $ty<I, V> {
45            /// Returns `true` if the collection contains a value for the specified `index`.
46            #[inline]
47            pub fn contains(&self, index: I) -> bool {
48                let index = index.sparse_set_index();
49                self.values.get(index).is_some_and(Option::is_some)
50            }
51
52            /// Returns a reference to the value at `index`.
53            ///
54            /// Returns `None` if `index` does not have a value or if `index` is out of bounds.
55            #[inline]
56            pub fn get(&self, index: I) -> Option<&V> {
57                let index = index.sparse_set_index();
58                self.values.get(index).and_then(Option::as_ref)
59            }
60        }
61    };
62}
63
64impl_sparse_array!(SparseArray);
65impl_sparse_array!(ImmutableSparseArray);
66
67impl<I: SparseSetIndex, V> SparseArray<I, V> {
68    /// Inserts `value` at `index` in the array.
69    ///
70    /// If `index` is out-of-bounds, this will enlarge the buffer to accommodate it.
71    #[inline]
72    pub fn insert(&mut self, index: I, value: V) {
73        let index = index.sparse_set_index();
74        if index >= self.values.len() {
75            self.values.resize_with(index + 1, || None);
76        }
77        self.values[index] = Some(value);
78    }
79
80    /// Returns a mutable reference to the value at `index`.
81    ///
82    /// Returns `None` if `index` does not have a value or if `index` is out of bounds.
83    #[inline]
84    pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
85        let index = index.sparse_set_index();
86        self.values.get_mut(index).and_then(Option::as_mut)
87    }
88
89    /// Removes and returns the value stored at `index`.
90    ///
91    /// Returns `None` if `index` did not have a value or if `index` is out of bounds.
92    #[inline]
93    pub fn remove(&mut self, index: I) -> Option<V> {
94        let index = index.sparse_set_index();
95        self.values.get_mut(index).and_then(Option::take)
96    }
97
98    /// Removes all of the values stored within.
99    pub fn clear(&mut self) {
100        self.values.clear();
101    }
102
103    /// Converts the [`SparseArray`] into an immutable variant.
104    pub(crate) fn into_immutable(self) -> ImmutableSparseArray<I, V> {
105        ImmutableSparseArray {
106            values: self.values.into_boxed_slice(),
107            marker: PhantomData,
108        }
109    }
110}
111
112/// A sparse data structure of [`Component`](crate::component::Component)s.
113///
114/// Designed for relatively fast insertions and deletions.
115#[derive(Debug)]
116pub struct ComponentSparseSet {
117    dense: Column,
118    // Internally this only relies on the Entity index to keep track of where the component data is
119    // stored for entities that are alive. The generation is not required, but is stored
120    // in debug builds to validate that access is correct.
121    #[cfg(not(debug_assertions))]
122    entities: Vec<EntityRow>,
123    #[cfg(debug_assertions)]
124    entities: Vec<Entity>,
125    sparse: SparseArray<EntityRow, TableRow>,
126}
127
128impl ComponentSparseSet {
129    /// Creates a new [`ComponentSparseSet`] with a given component type layout and
130    /// initial `capacity`.
131    pub(crate) fn new(component_info: &ComponentInfo, capacity: usize) -> Self {
132        Self {
133            dense: Column::with_capacity(component_info, capacity),
134            entities: Vec::with_capacity(capacity),
135            sparse: Default::default(),
136        }
137    }
138
139    /// Removes all of the values stored within.
140    pub(crate) fn clear(&mut self) {
141        self.dense.clear();
142        self.entities.clear();
143        self.sparse.clear();
144    }
145
146    /// Returns the number of component values in the sparse set.
147    #[inline]
148    pub fn len(&self) -> usize {
149        self.dense.len()
150    }
151
152    /// Returns `true` if the sparse set contains no component values.
153    #[inline]
154    pub fn is_empty(&self) -> bool {
155        self.dense.len() == 0
156    }
157
158    /// Inserts the `entity` key and component `value` pair into this sparse
159    /// set.
160    ///
161    /// # Safety
162    /// The `value` pointer must point to a valid address that matches the [`Layout`](std::alloc::Layout)
163    /// inside the [`ComponentInfo`] given when constructing this sparse set.
164    pub(crate) unsafe fn insert(
165        &mut self,
166        entity: Entity,
167        value: OwningPtr<'_>,
168        change_tick: Tick,
169        caller: MaybeLocation,
170    ) {
171        if let Some(&dense_index) = self.sparse.get(entity.row()) {
172            #[cfg(debug_assertions)]
173            assert_eq!(entity, self.entities[dense_index.index()]);
174            self.dense.replace(dense_index, value, change_tick, caller);
175        } else {
176            let dense_index = self.dense.len();
177            self.dense
178                .push(value, ComponentTicks::new(change_tick), caller);
179
180            // SAFETY: This entity row does not exist here yet, so there are no duplicates,
181            // and the entity index can not be the max, so the length must not be max either.
182            // To do so would have caused a panic in the entity alloxator.
183            let table_row = unsafe { TableRow::new(NonMaxU32::new_unchecked(dense_index as u32)) };
184
185            self.sparse.insert(entity.row(), table_row);
186            #[cfg(debug_assertions)]
187            assert_eq!(self.entities.len(), dense_index);
188            #[cfg(not(debug_assertions))]
189            self.entities.push(entity.row());
190            #[cfg(debug_assertions)]
191            self.entities.push(entity);
192        }
193    }
194
195    /// Returns `true` if the sparse set has a component value for the provided `entity`.
196    #[inline]
197    pub fn contains(&self, entity: Entity) -> bool {
198        #[cfg(debug_assertions)]
199        {
200            if let Some(&dense_index) = self.sparse.get(entity.row()) {
201                #[cfg(debug_assertions)]
202                assert_eq!(entity, self.entities[dense_index.index()]);
203                true
204            } else {
205                false
206            }
207        }
208        #[cfg(not(debug_assertions))]
209        self.sparse.contains(entity.row())
210    }
211
212    /// Returns a reference to the entity's component value.
213    ///
214    /// Returns `None` if `entity` does not have a component in the sparse set.
215    #[inline]
216    pub fn get(&self, entity: Entity) -> Option<Ptr<'_>> {
217        self.sparse.get(entity.row()).map(|&dense_index| {
218            #[cfg(debug_assertions)]
219            assert_eq!(entity, self.entities[dense_index.index()]);
220            // SAFETY: if the sparse index points to something in the dense vec, it exists
221            unsafe { self.dense.get_data_unchecked(dense_index) }
222        })
223    }
224
225    /// Returns references to the entity's component value and its added and changed ticks.
226    ///
227    /// Returns `None` if `entity` does not have a component in the sparse set.
228    #[inline]
229    pub fn get_with_ticks(
230        &self,
231        entity: Entity,
232    ) -> Option<(
233        Ptr<'_>,
234        TickCells<'_>,
235        MaybeLocation<&UnsafeCell<&'static Location<'static>>>,
236    )> {
237        let dense_index = *self.sparse.get(entity.row())?;
238        #[cfg(debug_assertions)]
239        assert_eq!(entity, self.entities[dense_index.index()]);
240        // SAFETY: if the sparse index points to something in the dense vec, it exists
241        unsafe {
242            Some((
243                self.dense.get_data_unchecked(dense_index),
244                TickCells {
245                    added: self.dense.get_added_tick_unchecked(dense_index),
246                    changed: self.dense.get_changed_tick_unchecked(dense_index),
247                },
248                self.dense.get_changed_by_unchecked(dense_index),
249            ))
250        }
251    }
252
253    /// Returns a reference to the "added" tick of the entity's component value.
254    ///
255    /// Returns `None` if `entity` does not have a component in the sparse set.
256    #[inline]
257    pub fn get_added_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
258        let dense_index = *self.sparse.get(entity.row())?;
259        #[cfg(debug_assertions)]
260        assert_eq!(entity, self.entities[dense_index.index()]);
261        // SAFETY: if the sparse index points to something in the dense vec, it exists
262        unsafe { Some(self.dense.get_added_tick_unchecked(dense_index)) }
263    }
264
265    /// Returns a reference to the "changed" tick of the entity's component value.
266    ///
267    /// Returns `None` if `entity` does not have a component in the sparse set.
268    #[inline]
269    pub fn get_changed_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
270        let dense_index = *self.sparse.get(entity.row())?;
271        #[cfg(debug_assertions)]
272        assert_eq!(entity, self.entities[dense_index.index()]);
273        // SAFETY: if the sparse index points to something in the dense vec, it exists
274        unsafe { Some(self.dense.get_changed_tick_unchecked(dense_index)) }
275    }
276
277    /// Returns a reference to the "added" and "changed" ticks of the entity's component value.
278    ///
279    /// Returns `None` if `entity` does not have a component in the sparse set.
280    #[inline]
281    pub fn get_ticks(&self, entity: Entity) -> Option<ComponentTicks> {
282        let dense_index = *self.sparse.get(entity.row())?;
283        #[cfg(debug_assertions)]
284        assert_eq!(entity, self.entities[dense_index.index()]);
285        // SAFETY: if the sparse index points to something in the dense vec, it exists
286        unsafe { Some(self.dense.get_ticks_unchecked(dense_index)) }
287    }
288
289    /// Returns a reference to the calling location that last changed the entity's component value.
290    ///
291    /// Returns `None` if `entity` does not have a component in the sparse set.
292    #[inline]
293    pub fn get_changed_by(
294        &self,
295        entity: Entity,
296    ) -> MaybeLocation<Option<&UnsafeCell<&'static Location<'static>>>> {
297        MaybeLocation::new_with_flattened(|| {
298            let dense_index = *self.sparse.get(entity.row())?;
299            #[cfg(debug_assertions)]
300            assert_eq!(entity, self.entities[dense_index.index()]);
301            // SAFETY: if the sparse index points to something in the dense vec, it exists
302            unsafe { Some(self.dense.get_changed_by_unchecked(dense_index)) }
303        })
304    }
305
306    /// Returns the drop function for the component type stored in the sparse set,
307    /// or `None` if it doesn't need to be dropped.
308    #[inline]
309    pub fn get_drop(&self) -> Option<unsafe fn(OwningPtr<'_>)> {
310        self.dense.get_drop()
311    }
312
313    /// Removes the `entity` from this sparse set and returns a pointer to the associated value (if
314    /// it exists).
315    #[must_use = "The returned pointer must be used to drop the removed component."]
316    pub(crate) fn remove_and_forget(&mut self, entity: Entity) -> Option<OwningPtr<'_>> {
317        self.sparse.remove(entity.row()).map(|dense_index| {
318            #[cfg(debug_assertions)]
319            assert_eq!(entity, self.entities[dense_index.index()]);
320            self.entities.swap_remove(dense_index.index());
321            let is_last = dense_index.index() == self.dense.len() - 1;
322            // SAFETY: dense_index was just removed from `sparse`, which ensures that it is valid
323            let (value, _, _) = unsafe { self.dense.swap_remove_and_forget_unchecked(dense_index) };
324            if !is_last {
325                let swapped_entity = self.entities[dense_index.index()];
326                #[cfg(not(debug_assertions))]
327                let index = swapped_entity;
328                #[cfg(debug_assertions)]
329                let index = swapped_entity.row();
330                *self.sparse.get_mut(index).unwrap() = dense_index;
331            }
332            value
333        })
334    }
335
336    /// Removes (and drops) the entity's component value from the sparse set.
337    ///
338    /// Returns `true` if `entity` had a component value in the sparse set.
339    pub(crate) fn remove(&mut self, entity: Entity) -> bool {
340        if let Some(dense_index) = self.sparse.remove(entity.row()) {
341            #[cfg(debug_assertions)]
342            assert_eq!(entity, self.entities[dense_index.index()]);
343            self.entities.swap_remove(dense_index.index());
344            let is_last = dense_index.index() == self.dense.len() - 1;
345            // SAFETY: if the sparse index points to something in the dense vec, it exists
346            unsafe {
347                self.dense.swap_remove_unchecked(dense_index);
348            }
349            if !is_last {
350                let swapped_entity = self.entities[dense_index.index()];
351                #[cfg(not(debug_assertions))]
352                let index = swapped_entity;
353                #[cfg(debug_assertions)]
354                let index = swapped_entity.row();
355                *self.sparse.get_mut(index).unwrap() = dense_index;
356            }
357            true
358        } else {
359            false
360        }
361    }
362
363    pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
364        self.dense.check_change_ticks(check);
365    }
366}
367
368/// A data structure that blends dense and sparse storage
369///
370/// `I` is the type of the indices, while `V` is the type of data stored in the dense storage.
371#[derive(Debug)]
372pub struct SparseSet<I, V: 'static> {
373    dense: Vec<V>,
374    indices: Vec<I>,
375    sparse: SparseArray<I, NonMaxUsize>,
376}
377
378/// A space-optimized version of [`SparseSet`] that cannot be changed
379/// after construction.
380#[derive(Debug)]
381pub(crate) struct ImmutableSparseSet<I, V: 'static> {
382    dense: Box<[V]>,
383    indices: Box<[I]>,
384    sparse: ImmutableSparseArray<I, NonMaxUsize>,
385}
386
387macro_rules! impl_sparse_set {
388    ($ty:ident) => {
389        impl<I: SparseSetIndex, V> $ty<I, V> {
390            /// Returns the number of elements in the sparse set.
391            #[inline]
392            pub fn len(&self) -> usize {
393                self.dense.len()
394            }
395
396            /// Returns `true` if the sparse set contains a value for `index`.
397            #[inline]
398            pub fn contains(&self, index: I) -> bool {
399                self.sparse.contains(index)
400            }
401
402            /// Returns a reference to the value for `index`.
403            ///
404            /// Returns `None` if `index` does not have a value in the sparse set.
405            pub fn get(&self, index: I) -> Option<&V> {
406                self.sparse.get(index).map(|dense_index| {
407                    // SAFETY: if the sparse index points to something in the dense vec, it exists
408                    unsafe { self.dense.get_unchecked(dense_index.get()) }
409                })
410            }
411
412            /// Returns a mutable reference to the value for `index`.
413            ///
414            /// Returns `None` if `index` does not have a value in the sparse set.
415            pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
416                let dense = &mut self.dense;
417                self.sparse.get(index).map(move |dense_index| {
418                    // SAFETY: if the sparse index points to something in the dense vec, it exists
419                    unsafe { dense.get_unchecked_mut(dense_index.get()) }
420                })
421            }
422
423            /// Returns an iterator visiting all keys (indices) in arbitrary order.
424            pub fn indices(&self) -> &[I] {
425                &self.indices
426            }
427
428            /// Returns an iterator visiting all values in arbitrary order.
429            pub fn values(&self) -> impl Iterator<Item = &V> {
430                self.dense.iter()
431            }
432
433            /// Returns an iterator visiting all values mutably in arbitrary order.
434            pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
435                self.dense.iter_mut()
436            }
437
438            /// Returns an iterator visiting all key-value pairs in arbitrary order, with references to the values.
439            pub fn iter(&self) -> impl Iterator<Item = (&I, &V)> {
440                self.indices.iter().zip(self.dense.iter())
441            }
442
443            /// Returns an iterator visiting all key-value pairs in arbitrary order, with mutable references to the values.
444            pub fn iter_mut(&mut self) -> impl Iterator<Item = (&I, &mut V)> {
445                self.indices.iter().zip(self.dense.iter_mut())
446            }
447        }
448    };
449}
450
451impl_sparse_set!(SparseSet);
452impl_sparse_set!(ImmutableSparseSet);
453
454impl<I: SparseSetIndex, V> Default for SparseSet<I, V> {
455    fn default() -> Self {
456        Self::new()
457    }
458}
459
460impl<I, V> SparseSet<I, V> {
461    /// Creates a new [`SparseSet`].
462    pub const fn new() -> Self {
463        Self {
464            dense: Vec::new(),
465            indices: Vec::new(),
466            sparse: SparseArray::new(),
467        }
468    }
469}
470
471impl<I: SparseSetIndex, V> SparseSet<I, V> {
472    /// Creates a new [`SparseSet`] with a specified initial capacity.
473    pub fn with_capacity(capacity: usize) -> Self {
474        Self {
475            dense: Vec::with_capacity(capacity),
476            indices: Vec::with_capacity(capacity),
477            sparse: Default::default(),
478        }
479    }
480
481    /// Returns the total number of elements the [`SparseSet`] can hold without needing to reallocate.
482    #[inline]
483    pub fn capacity(&self) -> usize {
484        self.dense.capacity()
485    }
486
487    /// Inserts `value` at `index`.
488    ///
489    /// If a value was already present at `index`, it will be overwritten.
490    pub fn insert(&mut self, index: I, value: V) {
491        if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
492            // SAFETY: dense indices stored in self.sparse always exist
493            unsafe {
494                *self.dense.get_unchecked_mut(dense_index.get()) = value;
495            }
496        } else {
497            self.sparse
498                .insert(index.clone(), NonMaxUsize::new(self.dense.len()).unwrap());
499            self.indices.push(index);
500            self.dense.push(value);
501        }
502    }
503
504    /// Returns a reference to the value for `index`, inserting one computed from `func`
505    /// if not already present.
506    pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
507        if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
508            // SAFETY: dense indices stored in self.sparse always exist
509            unsafe { self.dense.get_unchecked_mut(dense_index.get()) }
510        } else {
511            let value = func();
512            let dense_index = self.dense.len();
513            self.sparse
514                .insert(index.clone(), NonMaxUsize::new(dense_index).unwrap());
515            self.indices.push(index);
516            self.dense.push(value);
517            // SAFETY: dense index was just populated above
518            unsafe { self.dense.get_unchecked_mut(dense_index) }
519        }
520    }
521
522    /// Returns `true` if the sparse set contains no elements.
523    #[inline]
524    pub fn is_empty(&self) -> bool {
525        self.dense.len() == 0
526    }
527
528    /// Removes and returns the value for `index`.
529    ///
530    /// Returns `None` if `index` does not have a value in the sparse set.
531    pub fn remove(&mut self, index: I) -> Option<V> {
532        self.sparse.remove(index).map(|dense_index| {
533            let index = dense_index.get();
534            let is_last = index == self.dense.len() - 1;
535            let value = self.dense.swap_remove(index);
536            self.indices.swap_remove(index);
537            if !is_last {
538                let swapped_index = self.indices[index].clone();
539                *self.sparse.get_mut(swapped_index).unwrap() = dense_index;
540            }
541            value
542        })
543    }
544
545    /// Clears all of the elements from the sparse set.
546    pub fn clear(&mut self) {
547        self.dense.clear();
548        self.indices.clear();
549        self.sparse.clear();
550    }
551
552    /// Converts the sparse set into its immutable variant.
553    pub(crate) fn into_immutable(self) -> ImmutableSparseSet<I, V> {
554        ImmutableSparseSet {
555            dense: self.dense.into_boxed_slice(),
556            indices: self.indices.into_boxed_slice(),
557            sparse: self.sparse.into_immutable(),
558        }
559    }
560}
561
562/// Represents something that can be stored in a [`SparseSet`] as an integer.
563///
564/// Ideally, the `usize` values should be very small (ie: incremented starting from
565/// zero), as the number of bits needed to represent a `SparseSetIndex` in a `FixedBitSet`
566/// is proportional to the **value** of those `usize`.
567pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
568    /// Gets the sparse set index corresponding to this instance.
569    fn sparse_set_index(&self) -> usize;
570    /// Creates a new instance of this type with the specified index.
571    fn get_sparse_set_index(value: usize) -> Self;
572}
573
574macro_rules! impl_sparse_set_index {
575    ($($ty:ty),+) => {
576        $(impl SparseSetIndex for $ty {
577            #[inline]
578            fn sparse_set_index(&self) -> usize {
579                *self as usize
580            }
581
582            #[inline]
583            fn get_sparse_set_index(value: usize) -> Self {
584                value as $ty
585            }
586        })*
587    };
588}
589
590impl_sparse_set_index!(u8, u16, u32, u64, usize);
591
592/// A collection of [`ComponentSparseSet`] storages, indexed by [`ComponentId`]
593///
594/// Can be accessed via [`Storages`](crate::storage::Storages)
595#[derive(Default)]
596pub struct SparseSets {
597    sets: SparseSet<ComponentId, ComponentSparseSet>,
598}
599
600impl SparseSets {
601    /// Returns the number of [`ComponentSparseSet`]s this collection contains.
602    #[inline]
603    pub fn len(&self) -> usize {
604        self.sets.len()
605    }
606
607    /// Returns true if this collection contains no [`ComponentSparseSet`]s.
608    #[inline]
609    pub fn is_empty(&self) -> bool {
610        self.sets.is_empty()
611    }
612
613    /// An Iterator visiting all ([`ComponentId`], [`ComponentSparseSet`]) pairs.
614    /// NOTE: Order is not guaranteed.
615    pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
616        self.sets.iter().map(|(id, data)| (*id, data))
617    }
618
619    /// Gets a reference to the [`ComponentSparseSet`] of a [`ComponentId`]. This may be `None` if the component has never been spawned.
620    #[inline]
621    pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
622        self.sets.get(component_id)
623    }
624
625    /// Gets a mutable reference of [`ComponentSparseSet`] of a [`ComponentInfo`].
626    /// Create a new [`ComponentSparseSet`] if not exists.
627    pub(crate) fn get_or_insert(
628        &mut self,
629        component_info: &ComponentInfo,
630    ) -> &mut ComponentSparseSet {
631        if !self.sets.contains(component_info.id()) {
632            self.sets.insert(
633                component_info.id(),
634                ComponentSparseSet::new(component_info, 64),
635            );
636        }
637
638        self.sets.get_mut(component_info.id()).unwrap()
639    }
640
641    /// Gets a mutable reference to the [`ComponentSparseSet`] of a [`ComponentId`]. This may be `None` if the component has never been spawned.
642    pub(crate) fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
643        self.sets.get_mut(component_id)
644    }
645
646    /// Clear entities stored in each [`ComponentSparseSet`]
647    pub(crate) fn clear_entities(&mut self) {
648        for set in self.sets.values_mut() {
649            set.clear();
650        }
651    }
652
653    pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
654        for set in self.sets.values_mut() {
655            set.check_change_ticks(check);
656        }
657    }
658}
659
660#[cfg(test)]
661mod tests {
662    use super::SparseSets;
663    use crate::{
664        component::{Component, ComponentDescriptor, ComponentId, ComponentInfo},
665        entity::{Entity, EntityRow},
666        storage::SparseSet,
667    };
668    use alloc::{vec, vec::Vec};
669
670    #[derive(Debug, Eq, PartialEq)]
671    struct Foo(usize);
672
673    #[test]
674    fn sparse_set() {
675        let mut set = SparseSet::<Entity, Foo>::default();
676        let e0 = Entity::from_row(EntityRow::from_raw_u32(0).unwrap());
677        let e1 = Entity::from_row(EntityRow::from_raw_u32(1).unwrap());
678        let e2 = Entity::from_row(EntityRow::from_raw_u32(2).unwrap());
679        let e3 = Entity::from_row(EntityRow::from_raw_u32(3).unwrap());
680        let e4 = Entity::from_row(EntityRow::from_raw_u32(4).unwrap());
681
682        set.insert(e1, Foo(1));
683        set.insert(e2, Foo(2));
684        set.insert(e3, Foo(3));
685
686        assert_eq!(set.get(e0), None);
687        assert_eq!(set.get(e1), Some(&Foo(1)));
688        assert_eq!(set.get(e2), Some(&Foo(2)));
689        assert_eq!(set.get(e3), Some(&Foo(3)));
690        assert_eq!(set.get(e4), None);
691
692        {
693            let iter_results = set.values().collect::<Vec<_>>();
694            assert_eq!(iter_results, vec![&Foo(1), &Foo(2), &Foo(3)]);
695        }
696
697        assert_eq!(set.remove(e2), Some(Foo(2)));
698        assert_eq!(set.remove(e2), None);
699
700        assert_eq!(set.get(e0), None);
701        assert_eq!(set.get(e1), Some(&Foo(1)));
702        assert_eq!(set.get(e2), None);
703        assert_eq!(set.get(e3), Some(&Foo(3)));
704        assert_eq!(set.get(e4), None);
705
706        assert_eq!(set.remove(e1), Some(Foo(1)));
707
708        assert_eq!(set.get(e0), None);
709        assert_eq!(set.get(e1), None);
710        assert_eq!(set.get(e2), None);
711        assert_eq!(set.get(e3), Some(&Foo(3)));
712        assert_eq!(set.get(e4), None);
713
714        set.insert(e1, Foo(10));
715
716        assert_eq!(set.get(e1), Some(&Foo(10)));
717
718        *set.get_mut(e1).unwrap() = Foo(11);
719        assert_eq!(set.get(e1), Some(&Foo(11)));
720    }
721
722    #[test]
723    fn sparse_sets() {
724        let mut sets = SparseSets::default();
725
726        #[derive(Component, Default, Debug)]
727        struct TestComponent1;
728
729        #[derive(Component, Default, Debug)]
730        struct TestComponent2;
731
732        assert_eq!(sets.len(), 0);
733        assert!(sets.is_empty());
734
735        register_component::<TestComponent1>(&mut sets, 1);
736        assert_eq!(sets.len(), 1);
737
738        register_component::<TestComponent2>(&mut sets, 2);
739        assert_eq!(sets.len(), 2);
740
741        // check its shape by iter
742        let mut collected_sets = sets
743            .iter()
744            .map(|(id, set)| (id, set.len()))
745            .collect::<Vec<_>>();
746        collected_sets.sort();
747        assert_eq!(
748            collected_sets,
749            vec![(ComponentId::new(1), 0), (ComponentId::new(2), 0),]
750        );
751
752        fn register_component<T: Component>(sets: &mut SparseSets, id: usize) {
753            let descriptor = ComponentDescriptor::new::<T>();
754            let id = ComponentId::new(id);
755            let info = ComponentInfo::new(id, descriptor);
756            sets.get_or_insert(&info);
757        }
758    }
759}