1use crate::{
2 change_detection::MaybeLocation,
3 component::{ComponentId, ComponentInfo, ComponentTicks, Tick, TickCells},
4 entity::Entity,
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::NonMaxUsize;
11
12type EntityIndex = u32;
13
14#[derive(Debug)]
15pub(crate) struct SparseArray<I, V = I> {
16 values: Vec<Option<V>>,
17 marker: PhantomData<I>,
18}
19
20#[derive(Debug)]
23pub(crate) struct ImmutableSparseArray<I, V = I> {
24 values: Box<[Option<V>]>,
25 marker: PhantomData<I>,
26}
27
28impl<I: SparseSetIndex, V> Default for SparseArray<I, V> {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl<I, V> SparseArray<I, V> {
35 #[inline]
36 pub const fn new() -> Self {
37 Self {
38 values: Vec::new(),
39 marker: PhantomData,
40 }
41 }
42}
43
44macro_rules! impl_sparse_array {
45 ($ty:ident) => {
46 impl<I: SparseSetIndex, V> $ty<I, V> {
47 #[inline]
49 pub fn contains(&self, index: I) -> bool {
50 let index = index.sparse_set_index();
51 self.values.get(index).is_some_and(Option::is_some)
52 }
53
54 #[inline]
58 pub fn get(&self, index: I) -> Option<&V> {
59 let index = index.sparse_set_index();
60 self.values.get(index).and_then(Option::as_ref)
61 }
62 }
63 };
64}
65
66impl_sparse_array!(SparseArray);
67impl_sparse_array!(ImmutableSparseArray);
68
69impl<I: SparseSetIndex, V> SparseArray<I, V> {
70 #[inline]
74 pub fn insert(&mut self, index: I, value: V) {
75 let index = index.sparse_set_index();
76 if index >= self.values.len() {
77 self.values.resize_with(index + 1, || None);
78 }
79 self.values[index] = Some(value);
80 }
81
82 #[inline]
86 pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
87 let index = index.sparse_set_index();
88 self.values.get_mut(index).and_then(Option::as_mut)
89 }
90
91 #[inline]
95 pub fn remove(&mut self, index: I) -> Option<V> {
96 let index = index.sparse_set_index();
97 self.values.get_mut(index).and_then(Option::take)
98 }
99
100 pub fn clear(&mut self) {
102 self.values.clear();
103 }
104
105 pub(crate) fn into_immutable(self) -> ImmutableSparseArray<I, V> {
107 ImmutableSparseArray {
108 values: self.values.into_boxed_slice(),
109 marker: PhantomData,
110 }
111 }
112}
113
114#[derive(Debug)]
118pub struct ComponentSparseSet {
119 dense: Column,
120 #[cfg(not(debug_assertions))]
124 entities: Vec<EntityIndex>,
125 #[cfg(debug_assertions)]
126 entities: Vec<Entity>,
127 sparse: SparseArray<EntityIndex, TableRow>,
128}
129
130impl ComponentSparseSet {
131 pub(crate) fn new(component_info: &ComponentInfo, capacity: usize) -> Self {
134 Self {
135 dense: Column::with_capacity(component_info, capacity),
136 entities: Vec::with_capacity(capacity),
137 sparse: Default::default(),
138 }
139 }
140
141 pub(crate) fn clear(&mut self) {
143 self.dense.clear();
144 self.entities.clear();
145 self.sparse.clear();
146 }
147
148 #[inline]
150 pub fn len(&self) -> usize {
151 self.dense.len()
152 }
153
154 #[inline]
156 pub fn is_empty(&self) -> bool {
157 self.dense.len() == 0
158 }
159
160 pub(crate) unsafe fn insert(
167 &mut self,
168 entity: Entity,
169 value: OwningPtr<'_>,
170 change_tick: Tick,
171 caller: MaybeLocation,
172 ) {
173 if let Some(&dense_index) = self.sparse.get(entity.index()) {
174 #[cfg(debug_assertions)]
175 assert_eq!(entity, self.entities[dense_index.as_usize()]);
176 self.dense.replace(dense_index, value, change_tick, caller);
177 } else {
178 let dense_index = self.dense.len();
179 self.dense
180 .push(value, ComponentTicks::new(change_tick), caller);
181 self.sparse
182 .insert(entity.index(), TableRow::from_usize(dense_index));
183 #[cfg(debug_assertions)]
184 assert_eq!(self.entities.len(), dense_index);
185 #[cfg(not(debug_assertions))]
186 self.entities.push(entity.index());
187 #[cfg(debug_assertions)]
188 self.entities.push(entity);
189 }
190 }
191
192 #[inline]
194 pub fn contains(&self, entity: Entity) -> bool {
195 #[cfg(debug_assertions)]
196 {
197 if let Some(&dense_index) = self.sparse.get(entity.index()) {
198 #[cfg(debug_assertions)]
199 assert_eq!(entity, self.entities[dense_index.as_usize()]);
200 true
201 } else {
202 false
203 }
204 }
205 #[cfg(not(debug_assertions))]
206 self.sparse.contains(entity.index())
207 }
208
209 #[inline]
213 pub fn get(&self, entity: Entity) -> Option<Ptr<'_>> {
214 self.sparse.get(entity.index()).map(|&dense_index| {
215 #[cfg(debug_assertions)]
216 assert_eq!(entity, self.entities[dense_index.as_usize()]);
217 unsafe { self.dense.get_data_unchecked(dense_index) }
219 })
220 }
221
222 #[inline]
226 pub fn get_with_ticks(
227 &self,
228 entity: Entity,
229 ) -> Option<(
230 Ptr<'_>,
231 TickCells<'_>,
232 MaybeLocation<&UnsafeCell<&'static Location<'static>>>,
233 )> {
234 let dense_index = *self.sparse.get(entity.index())?;
235 #[cfg(debug_assertions)]
236 assert_eq!(entity, self.entities[dense_index.as_usize()]);
237 unsafe {
239 Some((
240 self.dense.get_data_unchecked(dense_index),
241 TickCells {
242 added: self.dense.get_added_tick_unchecked(dense_index),
243 changed: self.dense.get_changed_tick_unchecked(dense_index),
244 },
245 self.dense.get_changed_by_unchecked(dense_index),
246 ))
247 }
248 }
249
250 #[inline]
254 pub fn get_added_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
255 let dense_index = *self.sparse.get(entity.index())?;
256 #[cfg(debug_assertions)]
257 assert_eq!(entity, self.entities[dense_index.as_usize()]);
258 unsafe { Some(self.dense.get_added_tick_unchecked(dense_index)) }
260 }
261
262 #[inline]
266 pub fn get_changed_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
267 let dense_index = *self.sparse.get(entity.index())?;
268 #[cfg(debug_assertions)]
269 assert_eq!(entity, self.entities[dense_index.as_usize()]);
270 unsafe { Some(self.dense.get_changed_tick_unchecked(dense_index)) }
272 }
273
274 #[inline]
278 pub fn get_ticks(&self, entity: Entity) -> Option<ComponentTicks> {
279 let dense_index = *self.sparse.get(entity.index())?;
280 #[cfg(debug_assertions)]
281 assert_eq!(entity, self.entities[dense_index.as_usize()]);
282 unsafe { Some(self.dense.get_ticks_unchecked(dense_index)) }
284 }
285
286 #[inline]
290 pub fn get_changed_by(
291 &self,
292 entity: Entity,
293 ) -> MaybeLocation<Option<&UnsafeCell<&'static Location<'static>>>> {
294 MaybeLocation::new_with_flattened(|| {
295 let dense_index = *self.sparse.get(entity.index())?;
296 #[cfg(debug_assertions)]
297 assert_eq!(entity, self.entities[dense_index.as_usize()]);
298 unsafe { Some(self.dense.get_changed_by_unchecked(dense_index)) }
300 })
301 }
302
303 #[must_use = "The returned pointer must be used to drop the removed component."]
306 pub(crate) fn remove_and_forget(&mut self, entity: Entity) -> Option<OwningPtr<'_>> {
307 self.sparse.remove(entity.index()).map(|dense_index| {
308 #[cfg(debug_assertions)]
309 assert_eq!(entity, self.entities[dense_index.as_usize()]);
310 self.entities.swap_remove(dense_index.as_usize());
311 let is_last = dense_index.as_usize() == self.dense.len() - 1;
312 let (value, _, _) = unsafe { self.dense.swap_remove_and_forget_unchecked(dense_index) };
314 if !is_last {
315 let swapped_entity = self.entities[dense_index.as_usize()];
316 #[cfg(not(debug_assertions))]
317 let index = swapped_entity;
318 #[cfg(debug_assertions)]
319 let index = swapped_entity.index();
320 *self.sparse.get_mut(index).unwrap() = dense_index;
321 }
322 value
323 })
324 }
325
326 pub(crate) fn remove(&mut self, entity: Entity) -> bool {
330 if let Some(dense_index) = self.sparse.remove(entity.index()) {
331 #[cfg(debug_assertions)]
332 assert_eq!(entity, self.entities[dense_index.as_usize()]);
333 self.entities.swap_remove(dense_index.as_usize());
334 let is_last = dense_index.as_usize() == self.dense.len() - 1;
335 unsafe {
337 self.dense.swap_remove_unchecked(dense_index);
338 }
339 if !is_last {
340 let swapped_entity = self.entities[dense_index.as_usize()];
341 #[cfg(not(debug_assertions))]
342 let index = swapped_entity;
343 #[cfg(debug_assertions)]
344 let index = swapped_entity.index();
345 *self.sparse.get_mut(index).unwrap() = dense_index;
346 }
347 true
348 } else {
349 false
350 }
351 }
352
353 pub(crate) fn check_change_ticks(&mut self, change_tick: Tick) {
354 self.dense.check_change_ticks(change_tick);
355 }
356}
357
358#[derive(Debug)]
362pub struct SparseSet<I, V: 'static> {
363 dense: Vec<V>,
364 indices: Vec<I>,
365 sparse: SparseArray<I, NonMaxUsize>,
366}
367
368#[derive(Debug)]
371pub(crate) struct ImmutableSparseSet<I, V: 'static> {
372 dense: Box<[V]>,
373 indices: Box<[I]>,
374 sparse: ImmutableSparseArray<I, NonMaxUsize>,
375}
376
377macro_rules! impl_sparse_set {
378 ($ty:ident) => {
379 impl<I: SparseSetIndex, V> $ty<I, V> {
380 #[inline]
382 pub fn len(&self) -> usize {
383 self.dense.len()
384 }
385
386 #[inline]
388 pub fn contains(&self, index: I) -> bool {
389 self.sparse.contains(index)
390 }
391
392 pub fn get(&self, index: I) -> Option<&V> {
396 self.sparse.get(index).map(|dense_index| {
397 unsafe { self.dense.get_unchecked(dense_index.get()) }
399 })
400 }
401
402 pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
406 let dense = &mut self.dense;
407 self.sparse.get(index).map(move |dense_index| {
408 unsafe { dense.get_unchecked_mut(dense_index.get()) }
410 })
411 }
412
413 pub fn indices(&self) -> impl Iterator<Item = I> + Clone + '_ {
415 self.indices.iter().cloned()
416 }
417
418 pub fn values(&self) -> impl Iterator<Item = &V> {
420 self.dense.iter()
421 }
422
423 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
425 self.dense.iter_mut()
426 }
427
428 pub fn iter(&self) -> impl Iterator<Item = (&I, &V)> {
430 self.indices.iter().zip(self.dense.iter())
431 }
432
433 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&I, &mut V)> {
435 self.indices.iter().zip(self.dense.iter_mut())
436 }
437 }
438 };
439}
440
441impl_sparse_set!(SparseSet);
442impl_sparse_set!(ImmutableSparseSet);
443
444impl<I: SparseSetIndex, V> Default for SparseSet<I, V> {
445 fn default() -> Self {
446 Self::new()
447 }
448}
449
450impl<I, V> SparseSet<I, V> {
451 pub const fn new() -> Self {
453 Self {
454 dense: Vec::new(),
455 indices: Vec::new(),
456 sparse: SparseArray::new(),
457 }
458 }
459}
460
461impl<I: SparseSetIndex, V> SparseSet<I, V> {
462 pub fn with_capacity(capacity: usize) -> Self {
464 Self {
465 dense: Vec::with_capacity(capacity),
466 indices: Vec::with_capacity(capacity),
467 sparse: Default::default(),
468 }
469 }
470
471 #[inline]
473 pub fn capacity(&self) -> usize {
474 self.dense.capacity()
475 }
476
477 pub fn insert(&mut self, index: I, value: V) {
481 if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
482 unsafe {
484 *self.dense.get_unchecked_mut(dense_index.get()) = value;
485 }
486 } else {
487 self.sparse
488 .insert(index.clone(), NonMaxUsize::new(self.dense.len()).unwrap());
489 self.indices.push(index);
490 self.dense.push(value);
491 }
492 }
493
494 pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
497 if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
498 unsafe { self.dense.get_unchecked_mut(dense_index.get()) }
500 } else {
501 let value = func();
502 let dense_index = self.dense.len();
503 self.sparse
504 .insert(index.clone(), NonMaxUsize::new(dense_index).unwrap());
505 self.indices.push(index);
506 self.dense.push(value);
507 unsafe { self.dense.get_unchecked_mut(dense_index) }
509 }
510 }
511
512 #[inline]
514 pub fn is_empty(&self) -> bool {
515 self.dense.len() == 0
516 }
517
518 pub fn remove(&mut self, index: I) -> Option<V> {
522 self.sparse.remove(index).map(|dense_index| {
523 let index = dense_index.get();
524 let is_last = index == self.dense.len() - 1;
525 let value = self.dense.swap_remove(index);
526 self.indices.swap_remove(index);
527 if !is_last {
528 let swapped_index = self.indices[index].clone();
529 *self.sparse.get_mut(swapped_index).unwrap() = dense_index;
530 }
531 value
532 })
533 }
534
535 pub fn clear(&mut self) {
537 self.dense.clear();
538 self.indices.clear();
539 self.sparse.clear();
540 }
541
542 pub(crate) fn into_immutable(self) -> ImmutableSparseSet<I, V> {
544 ImmutableSparseSet {
545 dense: self.dense.into_boxed_slice(),
546 indices: self.indices.into_boxed_slice(),
547 sparse: self.sparse.into_immutable(),
548 }
549 }
550}
551
552pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
558 fn sparse_set_index(&self) -> usize;
560 fn get_sparse_set_index(value: usize) -> Self;
562}
563
564macro_rules! impl_sparse_set_index {
565 ($($ty:ty),+) => {
566 $(impl SparseSetIndex for $ty {
567 #[inline]
568 fn sparse_set_index(&self) -> usize {
569 *self as usize
570 }
571
572 #[inline]
573 fn get_sparse_set_index(value: usize) -> Self {
574 value as $ty
575 }
576 })*
577 };
578}
579
580impl_sparse_set_index!(u8, u16, u32, u64, usize);
581
582#[derive(Default)]
586pub struct SparseSets {
587 sets: SparseSet<ComponentId, ComponentSparseSet>,
588}
589
590impl SparseSets {
591 #[inline]
593 pub fn len(&self) -> usize {
594 self.sets.len()
595 }
596
597 #[inline]
599 pub fn is_empty(&self) -> bool {
600 self.sets.is_empty()
601 }
602
603 pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
606 self.sets.iter().map(|(id, data)| (*id, data))
607 }
608
609 #[inline]
611 pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
612 self.sets.get(component_id)
613 }
614
615 pub(crate) fn get_or_insert(
618 &mut self,
619 component_info: &ComponentInfo,
620 ) -> &mut ComponentSparseSet {
621 if !self.sets.contains(component_info.id()) {
622 self.sets.insert(
623 component_info.id(),
624 ComponentSparseSet::new(component_info, 64),
625 );
626 }
627
628 self.sets.get_mut(component_info.id()).unwrap()
629 }
630
631 pub(crate) fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
633 self.sets.get_mut(component_id)
634 }
635
636 pub(crate) fn clear_entities(&mut self) {
638 for set in self.sets.values_mut() {
639 set.clear();
640 }
641 }
642
643 pub(crate) fn check_change_ticks(&mut self, change_tick: Tick) {
644 for set in self.sets.values_mut() {
645 set.check_change_ticks(change_tick);
646 }
647 }
648}
649
650#[cfg(test)]
651mod tests {
652 use super::SparseSets;
653 use crate::{
654 component::{Component, ComponentDescriptor, ComponentId, ComponentInfo},
655 entity::Entity,
656 storage::SparseSet,
657 };
658 use alloc::{vec, vec::Vec};
659
660 #[derive(Debug, Eq, PartialEq)]
661 struct Foo(usize);
662
663 #[test]
664 fn sparse_set() {
665 let mut set = SparseSet::<Entity, Foo>::default();
666 let e0 = Entity::from_raw(0);
667 let e1 = Entity::from_raw(1);
668 let e2 = Entity::from_raw(2);
669 let e3 = Entity::from_raw(3);
670 let e4 = Entity::from_raw(4);
671
672 set.insert(e1, Foo(1));
673 set.insert(e2, Foo(2));
674 set.insert(e3, Foo(3));
675
676 assert_eq!(set.get(e0), None);
677 assert_eq!(set.get(e1), Some(&Foo(1)));
678 assert_eq!(set.get(e2), Some(&Foo(2)));
679 assert_eq!(set.get(e3), Some(&Foo(3)));
680 assert_eq!(set.get(e4), None);
681
682 {
683 let iter_results = set.values().collect::<Vec<_>>();
684 assert_eq!(iter_results, vec![&Foo(1), &Foo(2), &Foo(3)]);
685 }
686
687 assert_eq!(set.remove(e2), Some(Foo(2)));
688 assert_eq!(set.remove(e2), None);
689
690 assert_eq!(set.get(e0), None);
691 assert_eq!(set.get(e1), Some(&Foo(1)));
692 assert_eq!(set.get(e2), None);
693 assert_eq!(set.get(e3), Some(&Foo(3)));
694 assert_eq!(set.get(e4), None);
695
696 assert_eq!(set.remove(e1), Some(Foo(1)));
697
698 assert_eq!(set.get(e0), None);
699 assert_eq!(set.get(e1), None);
700 assert_eq!(set.get(e2), None);
701 assert_eq!(set.get(e3), Some(&Foo(3)));
702 assert_eq!(set.get(e4), None);
703
704 set.insert(e1, Foo(10));
705
706 assert_eq!(set.get(e1), Some(&Foo(10)));
707
708 *set.get_mut(e1).unwrap() = Foo(11);
709 assert_eq!(set.get(e1), Some(&Foo(11)));
710 }
711
712 #[test]
713 fn sparse_sets() {
714 let mut sets = SparseSets::default();
715
716 #[derive(Component, Default, Debug)]
717 struct TestComponent1;
718
719 #[derive(Component, Default, Debug)]
720 struct TestComponent2;
721
722 assert_eq!(sets.len(), 0);
723 assert!(sets.is_empty());
724
725 register_component::<TestComponent1>(&mut sets, 1);
726 assert_eq!(sets.len(), 1);
727
728 register_component::<TestComponent2>(&mut sets, 2);
729 assert_eq!(sets.len(), 2);
730
731 let mut collected_sets = sets
733 .iter()
734 .map(|(id, set)| (id, set.len()))
735 .collect::<Vec<_>>();
736 collected_sets.sort();
737 assert_eq!(
738 collected_sets,
739 vec![(ComponentId::new(1), 0), (ComponentId::new(2), 0),]
740 );
741
742 fn register_component<T: Component>(sets: &mut SparseSets, id: usize) {
743 let descriptor = ComponentDescriptor::new::<T>();
744 let id = ComponentId::new(id);
745 let info = ComponentInfo::new(id, descriptor);
746 sets.get_or_insert(&info);
747 }
748 }
749}