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#[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 #[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 #[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 #[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 #[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 #[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 pub fn clear(&mut self) {
100 self.values.clear();
101 }
102
103 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#[derive(Debug)]
116pub struct ComponentSparseSet {
117 dense: Column,
118 #[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 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 pub(crate) fn clear(&mut self) {
141 self.dense.clear();
142 self.entities.clear();
143 self.sparse.clear();
144 }
145
146 #[inline]
148 pub fn len(&self) -> usize {
149 self.dense.len()
150 }
151
152 #[inline]
154 pub fn is_empty(&self) -> bool {
155 self.dense.len() == 0
156 }
157
158 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 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 #[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 #[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 unsafe { self.dense.get_data_unchecked(dense_index) }
222 })
223 }
224
225 #[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 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 #[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 unsafe { Some(self.dense.get_added_tick_unchecked(dense_index)) }
263 }
264
265 #[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 unsafe { Some(self.dense.get_changed_tick_unchecked(dense_index)) }
275 }
276
277 #[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 unsafe { Some(self.dense.get_ticks_unchecked(dense_index)) }
287 }
288
289 #[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 unsafe { Some(self.dense.get_changed_by_unchecked(dense_index)) }
303 })
304 }
305
306 #[inline]
309 pub fn get_drop(&self) -> Option<unsafe fn(OwningPtr<'_>)> {
310 self.dense.get_drop()
311 }
312
313 #[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 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 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 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#[derive(Debug)]
372pub struct SparseSet<I, V: 'static> {
373 dense: Vec<V>,
374 indices: Vec<I>,
375 sparse: SparseArray<I, NonMaxUsize>,
376}
377
378#[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 #[inline]
392 pub fn len(&self) -> usize {
393 self.dense.len()
394 }
395
396 #[inline]
398 pub fn contains(&self, index: I) -> bool {
399 self.sparse.contains(index)
400 }
401
402 pub fn get(&self, index: I) -> Option<&V> {
406 self.sparse.get(index).map(|dense_index| {
407 unsafe { self.dense.get_unchecked(dense_index.get()) }
409 })
410 }
411
412 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 unsafe { dense.get_unchecked_mut(dense_index.get()) }
420 })
421 }
422
423 pub fn indices(&self) -> &[I] {
425 &self.indices
426 }
427
428 pub fn values(&self) -> impl Iterator<Item = &V> {
430 self.dense.iter()
431 }
432
433 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
435 self.dense.iter_mut()
436 }
437
438 pub fn iter(&self) -> impl Iterator<Item = (&I, &V)> {
440 self.indices.iter().zip(self.dense.iter())
441 }
442
443 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 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 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 #[inline]
483 pub fn capacity(&self) -> usize {
484 self.dense.capacity()
485 }
486
487 pub fn insert(&mut self, index: I, value: V) {
491 if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
492 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 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 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 unsafe { self.dense.get_unchecked_mut(dense_index) }
519 }
520 }
521
522 #[inline]
524 pub fn is_empty(&self) -> bool {
525 self.dense.len() == 0
526 }
527
528 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 pub fn clear(&mut self) {
547 self.dense.clear();
548 self.indices.clear();
549 self.sparse.clear();
550 }
551
552 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
562pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
568 fn sparse_set_index(&self) -> usize;
570 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#[derive(Default)]
596pub struct SparseSets {
597 sets: SparseSet<ComponentId, ComponentSparseSet>,
598}
599
600impl SparseSets {
601 #[inline]
603 pub fn len(&self) -> usize {
604 self.sets.len()
605 }
606
607 #[inline]
609 pub fn is_empty(&self) -> bool {
610 self.sets.is_empty()
611 }
612
613 pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
616 self.sets.iter().map(|(id, data)| (*id, data))
617 }
618
619 #[inline]
621 pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
622 self.sets.get(component_id)
623 }
624
625 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 pub(crate) fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
643 self.sets.get_mut(component_id)
644 }
645
646 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 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}