1use crate::{
2 change_detection::MaybeUnsafeCellLocation,
3 component::{ComponentId, ComponentInfo, ComponentTicks, Tick, TickCells},
4 entity::Entity,
5 storage::{Column, TableRow},
6};
7use bevy_ptr::{OwningPtr, Ptr};
8#[cfg(feature = "track_change_detection")]
9use core::panic::Location;
10use core::{cell::UnsafeCell, hash::Hash, marker::PhantomData};
11use nonmax::NonMaxUsize;
12
13type EntityIndex = u32;
14
15#[derive(Debug)]
16pub(crate) struct SparseArray<I, V = I> {
17 values: Vec<Option<V>>,
18 marker: PhantomData<I>,
19}
20
21#[derive(Debug)]
24pub(crate) struct ImmutableSparseArray<I, V = I> {
25 values: Box<[Option<V>]>,
26 marker: PhantomData<I>,
27}
28
29impl<I: SparseSetIndex, V> Default for SparseArray<I, V> {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl<I, V> SparseArray<I, V> {
36 #[inline]
37 pub const fn new() -> Self {
38 Self {
39 values: Vec::new(),
40 marker: PhantomData,
41 }
42 }
43}
44
45macro_rules! impl_sparse_array {
46 ($ty:ident) => {
47 impl<I: SparseSetIndex, V> $ty<I, V> {
48 #[inline]
50 pub fn contains(&self, index: I) -> bool {
51 let index = index.sparse_set_index();
52 self.values.get(index).map(|v| v.is_some()).unwrap_or(false)
53 }
54
55 #[inline]
59 pub fn get(&self, index: I) -> Option<&V> {
60 let index = index.sparse_set_index();
61 self.values.get(index).map(|v| v.as_ref()).unwrap_or(None)
62 }
63 }
64 };
65}
66
67impl_sparse_array!(SparseArray);
68impl_sparse_array!(ImmutableSparseArray);
69
70impl<I: SparseSetIndex, V> SparseArray<I, V> {
71 #[inline]
75 pub fn insert(&mut self, index: I, value: V) {
76 let index = index.sparse_set_index();
77 if index >= self.values.len() {
78 self.values.resize_with(index + 1, || None);
79 }
80 self.values[index] = Some(value);
81 }
82
83 #[inline]
87 pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
88 let index = index.sparse_set_index();
89 self.values
90 .get_mut(index)
91 .map(|v| v.as_mut())
92 .unwrap_or(None)
93 }
94
95 #[inline]
99 pub fn remove(&mut self, index: I) -> Option<V> {
100 let index = index.sparse_set_index();
101 self.values.get_mut(index).and_then(Option::take)
102 }
103
104 pub fn clear(&mut self) {
106 self.values.clear();
107 }
108
109 pub(crate) fn into_immutable(self) -> ImmutableSparseArray<I, V> {
111 ImmutableSparseArray {
112 values: self.values.into_boxed_slice(),
113 marker: PhantomData,
114 }
115 }
116}
117
118#[derive(Debug)]
122pub struct ComponentSparseSet {
123 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 Self {
139 dense: Column::with_capacity(component_info, capacity),
140 entities: Vec::with_capacity(capacity),
141 sparse: Default::default(),
142 }
143 }
144
145 pub(crate) fn clear(&mut self) {
147 self.dense.clear();
148 self.entities.clear();
149 self.sparse.clear();
150 }
151
152 #[inline]
154 pub fn len(&self) -> usize {
155 self.dense.len()
156 }
157
158 #[inline]
160 pub fn is_empty(&self) -> bool {
161 self.dense.len() == 0
162 }
163
164 pub(crate) unsafe fn insert(
171 &mut self,
172 entity: Entity,
173 value: OwningPtr<'_>,
174 change_tick: Tick,
175 #[cfg(feature = "track_change_detection")] caller: &'static Location<'static>,
176 ) {
177 if let Some(&dense_index) = self.sparse.get(entity.index()) {
178 #[cfg(debug_assertions)]
179 assert_eq!(entity, self.entities[dense_index.as_usize()]);
180 self.dense.replace(
181 dense_index,
182 value,
183 change_tick,
184 #[cfg(feature = "track_change_detection")]
185 caller,
186 );
187 } else {
188 let dense_index = self.dense.len();
189 self.dense.push(
190 value,
191 ComponentTicks::new(change_tick),
192 #[cfg(feature = "track_change_detection")]
193 caller,
194 );
195 self.sparse
196 .insert(entity.index(), TableRow::from_usize(dense_index));
197 #[cfg(debug_assertions)]
198 assert_eq!(self.entities.len(), dense_index);
199 #[cfg(not(debug_assertions))]
200 self.entities.push(entity.index());
201 #[cfg(debug_assertions)]
202 self.entities.push(entity);
203 }
204 }
205
206 #[inline]
208 pub fn contains(&self, entity: Entity) -> bool {
209 #[cfg(debug_assertions)]
210 {
211 if let Some(&dense_index) = self.sparse.get(entity.index()) {
212 #[cfg(debug_assertions)]
213 assert_eq!(entity, self.entities[dense_index.as_usize()]);
214 true
215 } else {
216 false
217 }
218 }
219 #[cfg(not(debug_assertions))]
220 self.sparse.contains(entity.index())
221 }
222
223 #[inline]
227 pub fn get(&self, entity: Entity) -> Option<Ptr<'_>> {
228 self.sparse.get(entity.index()).map(|&dense_index| {
229 #[cfg(debug_assertions)]
230 assert_eq!(entity, self.entities[dense_index.as_usize()]);
231 unsafe { self.dense.get_data_unchecked(dense_index) }
233 })
234 }
235
236 #[inline]
240 pub fn get_with_ticks(
241 &self,
242 entity: Entity,
243 ) -> Option<(Ptr<'_>, TickCells<'_>, MaybeUnsafeCellLocation<'_>)> {
244 let dense_index = *self.sparse.get(entity.index())?;
245 #[cfg(debug_assertions)]
246 assert_eq!(entity, self.entities[dense_index.as_usize()]);
247 unsafe {
249 Some((
250 self.dense.get_data_unchecked(dense_index),
251 TickCells {
252 added: self.dense.get_added_tick_unchecked(dense_index),
253 changed: self.dense.get_changed_tick_unchecked(dense_index),
254 },
255 #[cfg(feature = "track_change_detection")]
256 self.dense.get_changed_by_unchecked(dense_index),
257 #[cfg(not(feature = "track_change_detection"))]
258 (),
259 ))
260 }
261 }
262
263 #[inline]
267 pub fn get_added_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
268 let dense_index = *self.sparse.get(entity.index())?;
269 #[cfg(debug_assertions)]
270 assert_eq!(entity, self.entities[dense_index.as_usize()]);
271 unsafe { Some(self.dense.get_added_tick_unchecked(dense_index)) }
273 }
274
275 #[inline]
279 pub fn get_changed_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
280 let dense_index = *self.sparse.get(entity.index())?;
281 #[cfg(debug_assertions)]
282 assert_eq!(entity, self.entities[dense_index.as_usize()]);
283 unsafe { Some(self.dense.get_changed_tick_unchecked(dense_index)) }
285 }
286
287 #[inline]
291 pub fn get_ticks(&self, entity: Entity) -> Option<ComponentTicks> {
292 let dense_index = *self.sparse.get(entity.index())?;
293 #[cfg(debug_assertions)]
294 assert_eq!(entity, self.entities[dense_index.as_usize()]);
295 unsafe { Some(self.dense.get_ticks_unchecked(dense_index)) }
297 }
298
299 #[inline]
303 #[cfg(feature = "track_change_detection")]
304 pub fn get_changed_by(
305 &self,
306 entity: Entity,
307 ) -> Option<&UnsafeCell<&'static Location<'static>>> {
308 let dense_index = *self.sparse.get(entity.index())?;
309 #[cfg(debug_assertions)]
310 assert_eq!(entity, self.entities[dense_index.as_usize()]);
311 unsafe { Some(self.dense.get_changed_by_unchecked(dense_index)) }
313 }
314
315 #[must_use = "The returned pointer must be used to drop the removed component."]
318 pub(crate) fn remove_and_forget(&mut self, entity: Entity) -> Option<OwningPtr<'_>> {
319 self.sparse.remove(entity.index()).map(|dense_index| {
320 #[cfg(debug_assertions)]
321 assert_eq!(entity, self.entities[dense_index.as_usize()]);
322 self.entities.swap_remove(dense_index.as_usize());
323 let is_last = dense_index.as_usize() == self.dense.len() - 1;
324 let (value, _, _) = unsafe { self.dense.swap_remove_and_forget_unchecked(dense_index) };
326 if !is_last {
327 let swapped_entity = self.entities[dense_index.as_usize()];
328 #[cfg(not(debug_assertions))]
329 let index = swapped_entity;
330 #[cfg(debug_assertions)]
331 let index = swapped_entity.index();
332 *self.sparse.get_mut(index).unwrap() = dense_index;
333 }
334 value
335 })
336 }
337
338 pub(crate) fn remove(&mut self, entity: Entity) -> bool {
342 if let Some(dense_index) = self.sparse.remove(entity.index()) {
343 #[cfg(debug_assertions)]
344 assert_eq!(entity, self.entities[dense_index.as_usize()]);
345 self.entities.swap_remove(dense_index.as_usize());
346 let is_last = dense_index.as_usize() == self.dense.len() - 1;
347 unsafe {
349 self.dense.swap_remove_unchecked(dense_index);
350 }
351 if !is_last {
352 let swapped_entity = self.entities[dense_index.as_usize()];
353 #[cfg(not(debug_assertions))]
354 let index = swapped_entity;
355 #[cfg(debug_assertions)]
356 let index = swapped_entity.index();
357 *self.sparse.get_mut(index).unwrap() = dense_index;
358 }
359 true
360 } else {
361 false
362 }
363 }
364
365 pub(crate) fn check_change_ticks(&mut self, change_tick: Tick) {
366 self.dense.check_change_ticks(change_tick);
367 }
368}
369
370#[derive(Debug)]
374pub struct SparseSet<I, V: 'static> {
375 dense: Vec<V>,
376 indices: Vec<I>,
377 sparse: SparseArray<I, NonMaxUsize>,
378}
379
380#[derive(Debug)]
383pub(crate) struct ImmutableSparseSet<I, V: 'static> {
384 dense: Box<[V]>,
385 indices: Box<[I]>,
386 sparse: ImmutableSparseArray<I, NonMaxUsize>,
387}
388
389macro_rules! impl_sparse_set {
390 ($ty:ident) => {
391 impl<I: SparseSetIndex, V> $ty<I, V> {
392 #[inline]
394 pub fn len(&self) -> usize {
395 self.dense.len()
396 }
397
398 #[inline]
400 pub fn contains(&self, index: I) -> bool {
401 self.sparse.contains(index)
402 }
403
404 pub fn get(&self, index: I) -> Option<&V> {
408 self.sparse.get(index).map(|dense_index| {
409 unsafe { self.dense.get_unchecked(dense_index.get()) }
411 })
412 }
413
414 pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
418 let dense = &mut self.dense;
419 self.sparse.get(index).map(move |dense_index| {
420 unsafe { dense.get_unchecked_mut(dense_index.get()) }
422 })
423 }
424
425 pub fn indices(&self) -> impl Iterator<Item = I> + Clone + '_ {
427 self.indices.iter().cloned()
428 }
429
430 pub fn values(&self) -> impl Iterator<Item = &V> {
432 self.dense.iter()
433 }
434
435 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
437 self.dense.iter_mut()
438 }
439
440 pub fn iter(&self) -> impl Iterator<Item = (&I, &V)> {
442 self.indices.iter().zip(self.dense.iter())
443 }
444
445 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&I, &mut V)> {
447 self.indices.iter().zip(self.dense.iter_mut())
448 }
449 }
450 };
451}
452
453impl_sparse_set!(SparseSet);
454impl_sparse_set!(ImmutableSparseSet);
455
456impl<I: SparseSetIndex, V> Default for SparseSet<I, V> {
457 fn default() -> Self {
458 Self::new()
459 }
460}
461
462impl<I, V> SparseSet<I, V> {
463 pub const fn new() -> Self {
465 Self {
466 dense: Vec::new(),
467 indices: Vec::new(),
468 sparse: SparseArray::new(),
469 }
470 }
471}
472
473impl<I: SparseSetIndex, V> SparseSet<I, V> {
474 pub fn with_capacity(capacity: usize) -> Self {
476 Self {
477 dense: Vec::with_capacity(capacity),
478 indices: Vec::with_capacity(capacity),
479 sparse: Default::default(),
480 }
481 }
482
483 #[inline]
485 pub fn capacity(&self) -> usize {
486 self.dense.capacity()
487 }
488
489 pub fn insert(&mut self, index: I, value: V) {
493 if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
494 unsafe {
496 *self.dense.get_unchecked_mut(dense_index.get()) = value;
497 }
498 } else {
499 self.sparse
500 .insert(index.clone(), NonMaxUsize::new(self.dense.len()).unwrap());
501 self.indices.push(index);
502 self.dense.push(value);
503 }
504 }
505
506 pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
509 if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
510 unsafe { self.dense.get_unchecked_mut(dense_index.get()) }
512 } else {
513 let value = func();
514 let dense_index = self.dense.len();
515 self.sparse
516 .insert(index.clone(), NonMaxUsize::new(dense_index).unwrap());
517 self.indices.push(index);
518 self.dense.push(value);
519 unsafe { self.dense.get_unchecked_mut(dense_index) }
521 }
522 }
523
524 #[inline]
526 pub fn is_empty(&self) -> bool {
527 self.dense.len() == 0
528 }
529
530 pub fn remove(&mut self, index: I) -> Option<V> {
534 self.sparse.remove(index).map(|dense_index| {
535 let index = dense_index.get();
536 let is_last = index == self.dense.len() - 1;
537 let value = self.dense.swap_remove(index);
538 self.indices.swap_remove(index);
539 if !is_last {
540 let swapped_index = self.indices[index].clone();
541 *self.sparse.get_mut(swapped_index).unwrap() = dense_index;
542 }
543 value
544 })
545 }
546
547 pub fn clear(&mut self) {
549 self.dense.clear();
550 self.indices.clear();
551 self.sparse.clear();
552 }
553
554 pub(crate) fn into_immutable(self) -> ImmutableSparseSet<I, V> {
556 ImmutableSparseSet {
557 dense: self.dense.into_boxed_slice(),
558 indices: self.indices.into_boxed_slice(),
559 sparse: self.sparse.into_immutable(),
560 }
561 }
562}
563
564pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
570 fn sparse_set_index(&self) -> usize;
572 fn get_sparse_set_index(value: usize) -> Self;
574}
575
576macro_rules! impl_sparse_set_index {
577 ($($ty:ty),+) => {
578 $(impl SparseSetIndex for $ty {
579 #[inline]
580 fn sparse_set_index(&self) -> usize {
581 *self as usize
582 }
583
584 #[inline]
585 fn get_sparse_set_index(value: usize) -> Self {
586 value as $ty
587 }
588 })*
589 };
590}
591
592impl_sparse_set_index!(u8, u16, u32, u64, usize);
593
594#[derive(Default)]
598pub struct SparseSets {
599 sets: SparseSet<ComponentId, ComponentSparseSet>,
600}
601
602impl SparseSets {
603 #[inline]
605 pub fn len(&self) -> usize {
606 self.sets.len()
607 }
608
609 #[inline]
611 pub fn is_empty(&self) -> bool {
612 self.sets.is_empty()
613 }
614
615 pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
618 self.sets.iter().map(|(id, data)| (*id, data))
619 }
620
621 #[inline]
623 pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
624 self.sets.get(component_id)
625 }
626
627 pub(crate) fn get_or_insert(
630 &mut self,
631 component_info: &ComponentInfo,
632 ) -> &mut ComponentSparseSet {
633 if !self.sets.contains(component_info.id()) {
634 self.sets.insert(
635 component_info.id(),
636 ComponentSparseSet::new(component_info, 64),
637 );
638 }
639
640 self.sets.get_mut(component_info.id()).unwrap()
641 }
642
643 pub(crate) fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
645 self.sets.get_mut(component_id)
646 }
647
648 pub(crate) fn clear_entities(&mut self) {
650 for set in self.sets.values_mut() {
651 set.clear();
652 }
653 }
654
655 pub(crate) fn check_change_ticks(&mut self, change_tick: Tick) {
656 for set in self.sets.values_mut() {
657 set.check_change_ticks(change_tick);
658 }
659 }
660}
661
662#[cfg(test)]
663mod tests {
664 use super::SparseSets;
665 use crate::{
666 self as bevy_ecs,
667 component::{Component, ComponentDescriptor, ComponentId, ComponentInfo},
668 entity::Entity,
669 storage::SparseSet,
670 };
671
672 #[derive(Debug, Eq, PartialEq)]
673 struct Foo(usize);
674
675 #[test]
676 fn sparse_set() {
677 let mut set = SparseSet::<Entity, Foo>::default();
678 let e0 = Entity::from_raw(0);
679 let e1 = Entity::from_raw(1);
680 let e2 = Entity::from_raw(2);
681 let e3 = Entity::from_raw(3);
682 let e4 = Entity::from_raw(4);
683
684 set.insert(e1, Foo(1));
685 set.insert(e2, Foo(2));
686 set.insert(e3, Foo(3));
687
688 assert_eq!(set.get(e0), None);
689 assert_eq!(set.get(e1), Some(&Foo(1)));
690 assert_eq!(set.get(e2), Some(&Foo(2)));
691 assert_eq!(set.get(e3), Some(&Foo(3)));
692 assert_eq!(set.get(e4), None);
693
694 {
695 let iter_results = set.values().collect::<Vec<_>>();
696 assert_eq!(iter_results, vec![&Foo(1), &Foo(2), &Foo(3)]);
697 }
698
699 assert_eq!(set.remove(e2), Some(Foo(2)));
700 assert_eq!(set.remove(e2), None);
701
702 assert_eq!(set.get(e0), None);
703 assert_eq!(set.get(e1), Some(&Foo(1)));
704 assert_eq!(set.get(e2), None);
705 assert_eq!(set.get(e3), Some(&Foo(3)));
706 assert_eq!(set.get(e4), None);
707
708 assert_eq!(set.remove(e1), Some(Foo(1)));
709
710 assert_eq!(set.get(e0), None);
711 assert_eq!(set.get(e1), None);
712 assert_eq!(set.get(e2), None);
713 assert_eq!(set.get(e3), Some(&Foo(3)));
714 assert_eq!(set.get(e4), None);
715
716 set.insert(e1, Foo(10));
717
718 assert_eq!(set.get(e1), Some(&Foo(10)));
719
720 *set.get_mut(e1).unwrap() = Foo(11);
721 assert_eq!(set.get(e1), Some(&Foo(11)));
722 }
723
724 #[test]
725 fn sparse_sets() {
726 let mut sets = SparseSets::default();
727
728 #[derive(Component, Default, Debug)]
729 struct TestComponent1;
730
731 #[derive(Component, Default, Debug)]
732 struct TestComponent2;
733
734 assert_eq!(sets.len(), 0);
735 assert!(sets.is_empty());
736
737 init_component::<TestComponent1>(&mut sets, 1);
738 assert_eq!(sets.len(), 1);
739
740 init_component::<TestComponent2>(&mut sets, 2);
741 assert_eq!(sets.len(), 2);
742
743 let mut collected_sets = sets
745 .iter()
746 .map(|(id, set)| (id, set.len()))
747 .collect::<Vec<_>>();
748 collected_sets.sort();
749 assert_eq!(
750 collected_sets,
751 vec![(ComponentId::new(1), 0), (ComponentId::new(2), 0),]
752 );
753
754 fn init_component<T: Component>(sets: &mut SparseSets, id: usize) {
755 let descriptor = ComponentDescriptor::new::<T>();
756 let id = ComponentId::new(id);
757 let info = ComponentInfo::new(id, descriptor);
758 sets.get_or_insert(&info);
759 }
760 }
761}