Skip to content

Commit 9799f87

Browse files
committed
Use nonmax for non-component sparse sets
1 parent caa7ec6 commit 9799f87

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

crates/bevy_ecs/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ rustc-hash = "1.1"
2828
downcast-rs = "1.2"
2929
serde = "1"
3030
thiserror = "1.0"
31+
nonmax = "0.5"
3132

3233
[dev-dependencies]
3334
rand = "0.8"

crates/bevy_ecs/src/storage/sparse_set.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
};
66
use bevy_ptr::{OwningPtr, Ptr};
77
use std::{cell::UnsafeCell, hash::Hash, marker::PhantomData};
8+
use nonmax::NonMaxUsize;
89

910
type EntityIndex = u32;
1011

@@ -335,7 +336,7 @@ impl ComponentSparseSet {
335336
pub struct SparseSet<I, V: 'static> {
336337
dense: Vec<V>,
337338
indices: Vec<I>,
338-
sparse: SparseArray<I, usize>,
339+
sparse: SparseArray<I, NonMaxUsize>,
339340
}
340341

341342
/// A space-optimized version of [`SparseSet`] that cannot be changed
@@ -344,7 +345,7 @@ pub struct SparseSet<I, V: 'static> {
344345
pub(crate) struct ImmutableSparseSet<I, V: 'static> {
345346
dense: Box<[V]>,
346347
indices: Box<[I]>,
347-
sparse: ImmutableSparseArray<I, usize>,
348+
sparse: ImmutableSparseArray<I, NonMaxUsize>,
348349
}
349350

350351
macro_rules! impl_sparse_set {
@@ -368,7 +369,7 @@ macro_rules! impl_sparse_set {
368369
pub fn get(&self, index: I) -> Option<&V> {
369370
self.sparse.get(index).map(|dense_index| {
370371
// SAFETY: if the sparse index points to something in the dense vec, it exists
371-
unsafe { self.dense.get_unchecked(*dense_index) }
372+
unsafe { self.dense.get_unchecked(dense_index.get()) }
372373
})
373374
}
374375

@@ -379,7 +380,7 @@ macro_rules! impl_sparse_set {
379380
let dense = &mut self.dense;
380381
self.sparse.get(index).map(move |dense_index| {
381382
// SAFETY: if the sparse index points to something in the dense vec, it exists
382-
unsafe { dense.get_unchecked_mut(*dense_index) }
383+
unsafe { dense.get_unchecked_mut(dense_index.get()) }
383384
})
384385
}
385386

@@ -454,10 +455,10 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
454455
if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
455456
// SAFETY: dense indices stored in self.sparse always exist
456457
unsafe {
457-
*self.dense.get_unchecked_mut(dense_index) = value;
458+
*self.dense.get_unchecked_mut(dense_index.get()) = value;
458459
}
459460
} else {
460-
self.sparse.insert(index.clone(), self.dense.len());
461+
self.sparse.insert(index.clone(), NonMaxUsize::new(self.dense.len()).unwrap());
461462
self.indices.push(index);
462463
self.dense.push(value);
463464
}
@@ -468,11 +469,11 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
468469
pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
469470
if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
470471
// SAFETY: dense indices stored in self.sparse always exist
471-
unsafe { self.dense.get_unchecked_mut(dense_index) }
472+
unsafe { self.dense.get_unchecked_mut(dense_index.get()) }
472473
} else {
473474
let value = func();
474475
let dense_index = self.dense.len();
475-
self.sparse.insert(index.clone(), dense_index);
476+
self.sparse.insert(index.clone(), NonMaxUsize::new(dense_index).unwrap());
476477
self.indices.push(index);
477478
self.dense.push(value);
478479
// SAFETY: dense index was just populated above
@@ -491,11 +492,12 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
491492
/// Returns `None` if `index` does not have a value in the sparse set.
492493
pub fn remove(&mut self, index: I) -> Option<V> {
493494
self.sparse.remove(index).map(|dense_index| {
494-
let is_last = dense_index == self.dense.len() - 1;
495-
let value = self.dense.swap_remove(dense_index);
496-
self.indices.swap_remove(dense_index);
495+
let index = dense_index.get();
496+
let is_last = index == self.dense.len() - 1;
497+
let value = self.dense.swap_remove(index);
498+
self.indices.swap_remove(index);
497499
if !is_last {
498-
let swapped_index = self.indices[dense_index].clone();
500+
let swapped_index = self.indices[index].clone();
499501
*self.sparse.get_mut(swapped_index).unwrap() = dense_index;
500502
}
501503
value

0 commit comments

Comments
 (0)