1use crate::{
2 change_detection::{CheckChangeTicks, ComponentTickCells, ComponentTicks, MaybeLocation, Tick},
3 component::{ComponentId, ComponentInfo},
4 entity::{Entity, EntityIndex},
5 query::DebugCheckedUnwrap,
6 storage::{AbortOnPanic, Column, TableRow, VecExtensions},
7};
8use alloc::{boxed::Box, vec::Vec};
9use bevy_ptr::{OwningPtr, Ptr};
10use core::{cell::UnsafeCell, hash::Hash, marker::PhantomData, num::NonZero, panic::Location};
11use nonmax::{NonMaxU32, NonMaxUsize};
12
13#[derive(Debug)]
14pub(crate) struct SparseArray<I, V = I> {
15 values: Vec<Option<V>>,
16 marker: PhantomData<I>,
17}
18
19#[derive(Debug)]
22pub(crate) struct ImmutableSparseArray<I, V = I> {
23 values: Box<[Option<V>]>,
24 marker: PhantomData<I>,
25}
26
27impl<I: SparseSetIndex, V> Default for SparseArray<I, V> {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33impl<I, V> SparseArray<I, V> {
34 #[inline]
35 pub const fn new() -> Self {
36 Self {
37 values: Vec::new(),
38 marker: PhantomData,
39 }
40 }
41}
42
43macro_rules! impl_sparse_array {
44 ($ty:ident) => {
45 impl<I: SparseSetIndex, V> $ty<I, V> {
46 #[inline]
48 pub fn contains(&self, index: I) -> bool {
49 let index = index.sparse_set_index();
50 self.values.get(index).is_some_and(Option::is_some)
51 }
52
53 #[inline]
57 pub fn get(&self, index: I) -> Option<&V> {
58 let index = index.sparse_set_index();
59 self.values.get(index).and_then(Option::as_ref)
60 }
61 }
62 };
63}
64
65impl_sparse_array!(SparseArray);
66impl_sparse_array!(ImmutableSparseArray);
67
68impl<I: SparseSetIndex, V> SparseArray<I, V> {
69 #[inline]
77 pub fn insert(&mut self, index: I, value: V) {
78 let index = index.sparse_set_index();
79 if index >= self.values.len() {
80 self.values.resize_with(index + 1, || None);
81 }
82 self.values[index] = Some(value);
83 }
84
85 #[inline]
89 pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
90 let index = index.sparse_set_index();
91 self.values.get_mut(index).and_then(Option::as_mut)
92 }
93
94 #[inline]
98 pub fn remove(&mut self, index: I) -> Option<V> {
99 let index = index.sparse_set_index();
100 self.values.get_mut(index).and_then(Option::take)
101 }
102
103 pub fn clear(&mut self) {
105 self.values.clear();
106 }
107
108 pub(crate) fn into_immutable(self) -> ImmutableSparseArray<I, V> {
110 ImmutableSparseArray {
111 values: self.values.into_boxed_slice(),
112 marker: PhantomData,
113 }
114 }
115}
116
117#[derive(Debug)]
121pub struct ComponentSparseSet {
122 dense: Column,
124 #[cfg(not(debug_assertions))]
128 entities: Vec<EntityIndex>,
129 #[cfg(debug_assertions)]
130 entities: Vec<Entity>,
131 sparse: SparseArray<EntityIndex, TableRow>,
132}
133
134impl ComponentSparseSet {
135 pub(crate) fn new(component_info: &ComponentInfo, capacity: usize) -> Self {
138 let entities = Vec::with_capacity(capacity);
139 Self {
140 dense: Column::with_capacity(component_info, entities.capacity()),
141 entities,
142 sparse: Default::default(),
143 }
144 }
145
146 pub(crate) fn clear(&mut self) {
148 unsafe { self.dense.clear(self.len()) };
150 self.entities.clear();
151 self.sparse.clear();
152 }
153
154 #[inline]
156 pub fn len(&self) -> usize {
157 self.entities.len()
158 }
159
160 #[inline]
162 pub fn is_empty(&self) -> bool {
163 self.entities.is_empty()
164 }
165
166 pub(crate) unsafe fn insert(
177 &mut self,
178 entity: Entity,
179 value: OwningPtr<'_>,
180 change_tick: Tick,
181 caller: MaybeLocation,
182 ) {
183 if let Some(&dense_index) = self.sparse.get(entity.index()) {
184 #[cfg(debug_assertions)]
185 assert_eq!(entity, self.entities[dense_index.index()]);
186 self.dense.replace(dense_index, value, change_tick, caller);
187 } else {
188 let dense_index = self.entities.len();
189 let capacity = self.entities.capacity();
190
191 #[cfg(not(debug_assertions))]
192 self.entities.push(entity.index());
193 #[cfg(debug_assertions)]
194 self.entities.push(entity);
195
196 let _guard = AbortOnPanic;
200 if capacity != self.entities.capacity() {
201 let new_capacity = unsafe { NonZero::new_unchecked(self.entities.capacity()) };
203 if let Some(capacity) = NonZero::new(capacity) {
204 unsafe { self.dense.realloc(capacity, new_capacity) };
206 } else {
207 self.dense.alloc(new_capacity);
208 }
209 }
210
211 let table_row = unsafe { TableRow::new(NonMaxU32::new_unchecked(dense_index as u32)) };
214 self.dense.initialize(table_row, value, change_tick, caller);
215 self.sparse.insert(entity.index(), table_row);
216
217 core::mem::forget(_guard);
218 }
219 }
220
221 #[inline]
223 pub fn contains(&self, entity: Entity) -> bool {
224 #[cfg(debug_assertions)]
225 {
226 if let Some(&dense_index) = self.sparse.get(entity.index()) {
227 #[cfg(debug_assertions)]
228 assert_eq!(entity, self.entities[dense_index.index()]);
229 true
230 } else {
231 false
232 }
233 }
234 #[cfg(not(debug_assertions))]
235 self.sparse.contains(entity.index())
236 }
237
238 #[inline]
242 pub fn get(&self, entity: Entity) -> Option<Ptr<'_>> {
243 self.sparse.get(entity.index()).map(|&dense_index| {
244 #[cfg(debug_assertions)]
245 assert_eq!(entity, self.entities[dense_index.index()]);
246 unsafe { self.dense.get_data_unchecked(dense_index) }
248 })
249 }
250
251 #[inline]
255 pub fn get_with_ticks(&self, entity: Entity) -> Option<(Ptr<'_>, ComponentTickCells<'_>)> {
256 let dense_index = *self.sparse.get(entity.index())?;
257 #[cfg(debug_assertions)]
258 assert_eq!(entity, self.entities[dense_index.index()]);
259 unsafe {
261 Some((
262 self.dense.get_data_unchecked(dense_index),
263 ComponentTickCells {
264 added: self.dense.get_added_tick_unchecked(dense_index),
265 changed: self.dense.get_changed_tick_unchecked(dense_index),
266 changed_by: self.dense.get_changed_by_unchecked(dense_index),
267 },
268 ))
269 }
270 }
271
272 #[inline]
276 pub fn get_added_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
277 let dense_index = *self.sparse.get(entity.index())?;
278 #[cfg(debug_assertions)]
279 assert_eq!(entity, self.entities[dense_index.index()]);
280 unsafe { Some(self.dense.get_added_tick_unchecked(dense_index)) }
282 }
283
284 #[inline]
288 pub fn get_changed_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
289 let dense_index = *self.sparse.get(entity.index())?;
290 #[cfg(debug_assertions)]
291 assert_eq!(entity, self.entities[dense_index.index()]);
292 unsafe { Some(self.dense.get_changed_tick_unchecked(dense_index)) }
294 }
295
296 #[inline]
300 pub fn get_ticks(&self, entity: Entity) -> Option<ComponentTicks> {
301 let dense_index = *self.sparse.get(entity.index())?;
302 #[cfg(debug_assertions)]
303 assert_eq!(entity, self.entities[dense_index.index()]);
304 unsafe { Some(self.dense.get_ticks_unchecked(dense_index)) }
306 }
307
308 #[inline]
312 pub fn get_changed_by(
313 &self,
314 entity: Entity,
315 ) -> MaybeLocation<Option<&UnsafeCell<&'static Location<'static>>>> {
316 MaybeLocation::new_with_flattened(|| {
317 let dense_index = *self.sparse.get(entity.index())?;
318 #[cfg(debug_assertions)]
319 assert_eq!(entity, self.entities[dense_index.index()]);
320 unsafe { Some(self.dense.get_changed_by_unchecked(dense_index)) }
322 })
323 }
324
325 #[inline]
328 pub fn get_drop(&self) -> Option<unsafe fn(OwningPtr<'_>)> {
329 self.dense.get_drop()
330 }
331
332 #[must_use = "The returned pointer must be used to drop the removed component."]
335 pub(crate) fn remove_and_forget(&mut self, entity: Entity) -> Option<OwningPtr<'_>> {
336 self.sparse.remove(entity.index()).map(|dense_index| {
337 #[cfg(debug_assertions)]
338 assert_eq!(entity, self.entities[dense_index.index()]);
339 let last = self.entities.len() - 1;
340 if dense_index.index() >= last {
341 #[cfg(debug_assertions)]
342 assert_eq!(dense_index.index(), last);
343 unsafe { self.entities.set_len(last) };
346 unsafe {
349 self.dense
350 .get_data_unchecked(dense_index)
351 .assert_unique()
352 .promote()
353 }
354 } else {
355 unsafe {
358 self.entities
359 .swap_remove_nonoverlapping_unchecked(dense_index.index());
360 };
361 let swapped_entity = unsafe { self.entities.get_unchecked(dense_index.index()) };
363 #[cfg(not(debug_assertions))]
364 let index = *swapped_entity;
365 #[cfg(debug_assertions)]
366 let index = swapped_entity.index();
367 unsafe {
370 *self.sparse.get_mut(index).debug_checked_unwrap() = dense_index;
371 }
372 unsafe {
375 self.dense
376 .swap_remove_and_forget_unchecked_nonoverlapping(last, dense_index)
377 }
378 }
379 })
380 }
381
382 pub(crate) fn remove(&mut self, entity: Entity) -> bool {
386 self.sparse
387 .remove(entity.index())
388 .map(|dense_index| {
389 #[cfg(debug_assertions)]
390 assert_eq!(entity, self.entities[dense_index.index()]);
391 let last = self.entities.len() - 1;
392 if dense_index.index() >= last {
393 #[cfg(debug_assertions)]
394 assert_eq!(dense_index.index(), last);
395 unsafe { self.entities.set_len(last) };
398 unsafe { self.dense.drop_last_component(last) };
401 } else {
402 unsafe {
405 self.entities
406 .swap_remove_nonoverlapping_unchecked(dense_index.index());
407 };
408 let swapped_entity =
409 unsafe { self.entities.get_unchecked(dense_index.index()) };
411 #[cfg(not(debug_assertions))]
412 let index = *swapped_entity;
413 #[cfg(debug_assertions)]
414 let index = swapped_entity.index();
415 unsafe {
418 *self.sparse.get_mut(index).debug_checked_unwrap() = dense_index;
419 }
420 unsafe {
423 self.dense
424 .swap_remove_and_drop_unchecked_nonoverlapping(last, dense_index);
425 }
426 }
427 })
428 .is_some()
429 }
430
431 pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
432 unsafe { self.dense.check_change_ticks(self.len(), check) };
434 }
435}
436
437impl Drop for ComponentSparseSet {
438 fn drop(&mut self) {
439 let len = self.entities.len();
440 self.entities.clear();
441 unsafe {
443 self.dense.drop(self.entities.capacity(), len);
444 }
445 }
446}
447
448#[derive(Debug)]
452pub struct SparseSet<I, V: 'static> {
453 dense: Vec<V>,
454 indices: Vec<I>,
455 sparse: SparseArray<I, NonMaxUsize>,
456}
457
458#[derive(Debug)]
461pub(crate) struct ImmutableSparseSet<I, V: 'static> {
462 dense: Box<[V]>,
463 indices: Box<[I]>,
464 sparse: ImmutableSparseArray<I, NonMaxUsize>,
465}
466
467macro_rules! impl_sparse_set {
468 ($ty:ident) => {
469 impl<I: SparseSetIndex, V> $ty<I, V> {
470 #[inline]
472 pub fn len(&self) -> usize {
473 self.dense.len()
474 }
475
476 #[inline]
478 pub fn contains(&self, index: I) -> bool {
479 self.sparse.contains(index)
480 }
481
482 pub fn get(&self, index: I) -> Option<&V> {
486 self.sparse.get(index).map(|dense_index| {
487 unsafe { self.dense.get_unchecked(dense_index.get()) }
489 })
490 }
491
492 pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
496 let dense = &mut self.dense;
497 self.sparse.get(index).map(move |dense_index| {
498 unsafe { dense.get_unchecked_mut(dense_index.get()) }
500 })
501 }
502
503 pub fn indices(&self) -> &[I] {
505 &self.indices
506 }
507
508 pub fn values(&self) -> impl Iterator<Item = &V> {
510 self.dense.iter()
511 }
512
513 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
515 self.dense.iter_mut()
516 }
517
518 pub fn iter(&self) -> impl Iterator<Item = (&I, &V)> {
520 self.indices.iter().zip(self.dense.iter())
521 }
522
523 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&I, &mut V)> {
525 self.indices.iter().zip(self.dense.iter_mut())
526 }
527 }
528 };
529}
530
531impl_sparse_set!(SparseSet);
532impl_sparse_set!(ImmutableSparseSet);
533
534impl<I: SparseSetIndex, V> Default for SparseSet<I, V> {
535 fn default() -> Self {
536 Self::new()
537 }
538}
539
540impl<I, V> SparseSet<I, V> {
541 pub const fn new() -> Self {
543 Self {
544 dense: Vec::new(),
545 indices: Vec::new(),
546 sparse: SparseArray::new(),
547 }
548 }
549}
550
551impl<I: SparseSetIndex, V> SparseSet<I, V> {
552 pub fn with_capacity(capacity: usize) -> Self {
558 Self {
559 dense: Vec::with_capacity(capacity),
560 indices: Vec::with_capacity(capacity),
561 sparse: Default::default(),
562 }
563 }
564
565 #[inline]
567 pub fn capacity(&self) -> usize {
568 self.dense.capacity()
569 }
570
571 pub fn insert(&mut self, index: I, value: V) {
579 if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
580 unsafe {
582 *self.dense.get_unchecked_mut(dense_index.get()) = value;
583 }
584 } else {
585 self.sparse
586 .insert(index.clone(), NonMaxUsize::new(self.dense.len()).unwrap());
587 self.indices.push(index);
588 self.dense.push(value);
589 }
590 }
591
592 pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
599 if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
600 unsafe { self.dense.get_unchecked_mut(dense_index.get()) }
602 } else {
603 let value = func();
604 let dense_index = self.dense.len();
605 self.sparse
606 .insert(index.clone(), NonMaxUsize::new(dense_index).unwrap());
607 self.indices.push(index);
608 self.dense.push(value);
609 unsafe { self.dense.get_unchecked_mut(dense_index) }
611 }
612 }
613
614 #[inline]
616 pub fn is_empty(&self) -> bool {
617 self.dense.len() == 0
618 }
619
620 pub fn remove(&mut self, index: I) -> Option<V> {
624 self.sparse.remove(index).map(|dense_index| {
625 let index = dense_index.get();
626 let is_last = index == self.dense.len() - 1;
627 let value = self.dense.swap_remove(index);
628 self.indices.swap_remove(index);
629 if !is_last {
630 let swapped_index = self.indices[index].clone();
631 *self.sparse.get_mut(swapped_index).unwrap() = dense_index;
632 }
633 value
634 })
635 }
636
637 pub fn clear(&mut self) {
642 self.dense.clear();
643 self.indices.clear();
644 self.sparse.clear();
645 }
646
647 pub(crate) fn into_immutable(self) -> ImmutableSparseSet<I, V> {
649 ImmutableSparseSet {
650 dense: self.dense.into_boxed_slice(),
651 indices: self.indices.into_boxed_slice(),
652 sparse: self.sparse.into_immutable(),
653 }
654 }
655}
656
657pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
663 fn sparse_set_index(&self) -> usize;
665 fn get_sparse_set_index(value: usize) -> Self;
667}
668
669macro_rules! impl_sparse_set_index {
670 ($($ty:ty),+) => {
671 $(impl SparseSetIndex for $ty {
672 #[inline]
673 fn sparse_set_index(&self) -> usize {
674 *self as usize
675 }
676
677 #[inline]
678 fn get_sparse_set_index(value: usize) -> Self {
679 value as $ty
680 }
681 })*
682 };
683}
684
685impl_sparse_set_index!(u8, u16, u32, u64, usize);
686
687#[derive(Default)]
691pub struct SparseSets {
692 sets: SparseSet<ComponentId, ComponentSparseSet>,
693}
694
695impl SparseSets {
696 #[inline]
698 pub fn len(&self) -> usize {
699 self.sets.len()
700 }
701
702 #[inline]
704 pub fn is_empty(&self) -> bool {
705 self.sets.is_empty()
706 }
707
708 pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
711 self.sets.iter().map(|(id, data)| (*id, data))
712 }
713
714 #[inline]
716 pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
717 self.sets.get(component_id)
718 }
719
720 pub(crate) fn get_or_insert(
727 &mut self,
728 component_info: &ComponentInfo,
729 ) -> &mut ComponentSparseSet {
730 if !self.sets.contains(component_info.id()) {
731 self.sets.insert(
732 component_info.id(),
733 ComponentSparseSet::new(component_info, 64),
734 );
735 }
736
737 self.sets.get_mut(component_info.id()).unwrap()
738 }
739
740 pub(crate) fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
742 self.sets.get_mut(component_id)
743 }
744
745 pub(crate) fn clear_entities(&mut self) {
750 for set in self.sets.values_mut() {
751 set.clear();
752 }
753 }
754
755 pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
756 for set in self.sets.values_mut() {
757 set.check_change_ticks(check);
758 }
759 }
760}
761
762#[cfg(test)]
763mod tests {
764 use super::SparseSets;
765 use crate::{
766 component::{Component, ComponentDescriptor, ComponentId, ComponentInfo},
767 entity::{Entity, EntityIndex},
768 storage::SparseSet,
769 };
770 use alloc::{vec, vec::Vec};
771
772 #[derive(Debug, Eq, PartialEq)]
773 struct Foo(usize);
774
775 #[test]
776 fn sparse_set() {
777 let mut set = SparseSet::<Entity, Foo>::default();
778 let e0 = Entity::from_index(EntityIndex::from_raw_u32(0).unwrap());
779 let e1 = Entity::from_index(EntityIndex::from_raw_u32(1).unwrap());
780 let e2 = Entity::from_index(EntityIndex::from_raw_u32(2).unwrap());
781 let e3 = Entity::from_index(EntityIndex::from_raw_u32(3).unwrap());
782 let e4 = Entity::from_index(EntityIndex::from_raw_u32(4).unwrap());
783
784 set.insert(e1, Foo(1));
785 set.insert(e2, Foo(2));
786 set.insert(e3, Foo(3));
787
788 assert_eq!(set.get(e0), None);
789 assert_eq!(set.get(e1), Some(&Foo(1)));
790 assert_eq!(set.get(e2), Some(&Foo(2)));
791 assert_eq!(set.get(e3), Some(&Foo(3)));
792 assert_eq!(set.get(e4), None);
793
794 {
795 let iter_results = set.values().collect::<Vec<_>>();
796 assert_eq!(iter_results, vec![&Foo(1), &Foo(2), &Foo(3)]);
797 }
798
799 assert_eq!(set.remove(e2), Some(Foo(2)));
800 assert_eq!(set.remove(e2), None);
801
802 assert_eq!(set.get(e0), None);
803 assert_eq!(set.get(e1), Some(&Foo(1)));
804 assert_eq!(set.get(e2), None);
805 assert_eq!(set.get(e3), Some(&Foo(3)));
806 assert_eq!(set.get(e4), None);
807
808 assert_eq!(set.remove(e1), Some(Foo(1)));
809
810 assert_eq!(set.get(e0), None);
811 assert_eq!(set.get(e1), None);
812 assert_eq!(set.get(e2), None);
813 assert_eq!(set.get(e3), Some(&Foo(3)));
814 assert_eq!(set.get(e4), None);
815
816 set.insert(e1, Foo(10));
817
818 assert_eq!(set.get(e1), Some(&Foo(10)));
819
820 *set.get_mut(e1).unwrap() = Foo(11);
821 assert_eq!(set.get(e1), Some(&Foo(11)));
822 }
823
824 #[test]
825 fn sparse_sets() {
826 let mut sets = SparseSets::default();
827
828 #[derive(Component, Default, Debug)]
829 struct TestComponent1;
830
831 #[derive(Component, Default, Debug)]
832 struct TestComponent2;
833
834 assert_eq!(sets.len(), 0);
835 assert!(sets.is_empty());
836
837 register_component::<TestComponent1>(&mut sets, 1);
838 assert_eq!(sets.len(), 1);
839
840 register_component::<TestComponent2>(&mut sets, 2);
841 assert_eq!(sets.len(), 2);
842
843 let mut collected_sets = sets
845 .iter()
846 .map(|(id, set)| (id, set.len()))
847 .collect::<Vec<_>>();
848 collected_sets.sort();
849 assert_eq!(
850 collected_sets,
851 vec![(ComponentId::new(1), 0), (ComponentId::new(2), 0),]
852 );
853
854 fn register_component<T: Component>(sets: &mut SparseSets, id: usize) {
855 let descriptor = ComponentDescriptor::new::<T>();
856 let id = ComponentId::new(id);
857 let info = ComponentInfo::new(id, descriptor);
858 sets.get_or_insert(&info);
859 }
860 }
861}