pub struct SparseSet<T> { /* private fields */ }Expand description
A sparse set storing values of type T indexed by Entity.
Provides O(1) access operations while maintaining cache-friendly iteration. This is the primary storage backend for ECS components.
§Type Parameters
T: The value type stored in the set
§Memory Layout
The sparse set trades memory for performance:
- Sparse vec grows to max entity index seen (sparse memory usage)
- Dense and values vecs are tightly packed (no gaps)
For entities with indices 0, 100, 1000, the sparse vec will have 1001 entries, but dense/values will only have 3 entries.
Implementations§
Source§impl<T> SparseSet<T>
impl<T> SparseSet<T>
Sourcepub fn new() -> SparseSet<T>
pub fn new() -> SparseSet<T>
Creates a new, empty sparse set.
§Example
use goud_engine::ecs::SparseSet;
let set: SparseSet<i32> = SparseSet::new();
assert!(set.is_empty());
assert_eq!(set.len(), 0);Sourcepub fn with_capacity(capacity: usize) -> SparseSet<T>
pub fn with_capacity(capacity: usize) -> SparseSet<T>
Creates a sparse set with pre-allocated capacity.
This pre-allocates the dense and values vectors, but not the sparse vector (which grows on demand based on entity indices).
§Arguments
capacity- Number of elements to pre-allocate
§Example
use goud_engine::ecs::SparseSet;
let set: SparseSet<String> = SparseSet::with_capacity(1000);
assert!(set.is_empty());Sourcepub fn insert(&mut self, entity: Entity, value: T) -> Option<T>
pub fn insert(&mut self, entity: Entity, value: T) -> Option<T>
Inserts a value for the given entity.
If the entity already has a value, it is replaced and the old value
is returned. Otherwise, None is returned.
§Arguments
entity- The entity to associate with the valuevalue- The value to store
§Returns
The previous value if one existed, or None.
§Panics
Panics if the entity is a placeholder (Entity::PLACEHOLDER).
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
let entity = Entity::new(0, 1);
assert_eq!(set.insert(entity, 42), None);
assert_eq!(set.insert(entity, 99), Some(42)); // Returns old value
assert_eq!(set.get(entity), Some(&99));Sourcepub fn remove(&mut self, entity: Entity) -> Option<T>
pub fn remove(&mut self, entity: Entity) -> Option<T>
Removes the value for the given entity.
Uses swap-remove to maintain dense packing: the last element is moved to fill the gap, keeping iteration cache-friendly.
§Arguments
entity- The entity whose value to remove
§Returns
The removed value if one existed, or None.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
let entity = Entity::new(0, 1);
set.insert(entity, "hello");
assert_eq!(set.remove(entity), Some("hello"));
assert_eq!(set.remove(entity), None); // Already removedSourcepub fn get(&self, entity: Entity) -> Option<&T>
pub fn get(&self, entity: Entity) -> Option<&T>
Returns a reference to the value for the given entity.
§Arguments
entity- The entity to look up
§Returns
A reference to the value if the entity has one, or None.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
let entity = Entity::new(0, 1);
set.insert(entity, 42);
assert_eq!(set.get(entity), Some(&42));
let missing = Entity::new(999, 1);
assert_eq!(set.get(missing), None);Sourcepub fn get_mut(&mut self, entity: Entity) -> Option<&mut T>
pub fn get_mut(&mut self, entity: Entity) -> Option<&mut T>
Returns a mutable reference to the value for the given entity.
§Arguments
entity- The entity to look up
§Returns
A mutable reference to the value if the entity has one, or None.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
let entity = Entity::new(0, 1);
set.insert(entity, 42);
if let Some(value) = set.get_mut(entity) {
*value = 100;
}
assert_eq!(set.get(entity), Some(&100));Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of entities with values in this set.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
assert_eq!(set.len(), 0);
set.insert(Entity::new(0, 1), "a");
set.insert(Entity::new(5, 1), "b");
assert_eq!(set.len(), 2);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the set contains no values.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set: SparseSet<i32> = SparseSet::new();
assert!(set.is_empty());
set.insert(Entity::new(0, 1), 42);
assert!(!set.is_empty());Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Removes all values from the set.
This clears all three internal arrays. After calling clear(),
len() will return 0.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
set.insert(Entity::new(0, 1), "a");
set.insert(Entity::new(1, 1), "b");
assert_eq!(set.len(), 2);
set.clear();
assert!(set.is_empty());Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Reserves capacity for at least additional more elements.
This affects the dense and values arrays, not the sparse array (which grows based on entity indices).
§Arguments
additional- Number of additional elements to reserve
§Example
use goud_engine::ecs::SparseSet;
let mut set: SparseSet<i32> = SparseSet::new();
set.reserve(1000);Source§impl<T> SparseSet<T>
impl<T> SparseSet<T>
Sourcepub fn iter(&self) -> SparseSetIter<'_, T>
pub fn iter(&self) -> SparseSetIter<'_, T>
Returns an iterator over (Entity, &T) pairs.
Iteration is cache-friendly because it traverses the dense array sequentially.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
set.insert(Entity::new(0, 1), "a");
set.insert(Entity::new(1, 1), "b");
for (entity, value) in set.iter() {
println!("{}: {}", entity, value);
}Sourcepub fn iter_mut(&mut self) -> SparseSetIterMut<'_, T>
pub fn iter_mut(&mut self) -> SparseSetIterMut<'_, T>
Returns a mutable iterator over (Entity, &mut T) pairs.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
set.insert(Entity::new(0, 1), 1);
set.insert(Entity::new(1, 1), 2);
for (_, value) in set.iter_mut() {
*value *= 10;
}
assert_eq!(set.get(Entity::new(0, 1)), Some(&10));
assert_eq!(set.get(Entity::new(1, 1)), Some(&20));Sourcepub fn entities(&self) -> impl Iterator<Item = Entity>
pub fn entities(&self) -> impl Iterator<Item = Entity>
Returns an iterator over all entities in the set.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
set.insert(Entity::new(0, 1), "a");
set.insert(Entity::new(5, 1), "b");
let entities: Vec<_> = set.entities().collect();
assert_eq!(entities.len(), 2);Sourcepub fn values(&self) -> impl Iterator<Item = &T>
pub fn values(&self) -> impl Iterator<Item = &T>
Returns an iterator over all values in the set.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
set.insert(Entity::new(0, 1), 10);
set.insert(Entity::new(5, 1), 20);
let sum: i32 = set.values().sum();
assert_eq!(sum, 30);Sourcepub fn values_mut(&mut self) -> impl Iterator<Item = &mut T>
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T>
Returns a mutable iterator over all values in the set.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
set.insert(Entity::new(0, 1), 10);
set.insert(Entity::new(1, 1), 20);
for value in set.values_mut() {
*value += 1;
}
let sum: i32 = set.values().sum();
assert_eq!(sum, 32); // 11 + 21Sourcepub fn dense(&self) -> &[Entity]
pub fn dense(&self) -> &[Entity]
Returns the raw entity array for direct access.
This is useful for bulk operations or implementing custom iterators.
§Example
use goud_engine::ecs::{Entity, SparseSet};
let mut set = SparseSet::new();
set.insert(Entity::new(0, 1), "a");
set.insert(Entity::new(1, 1), "b");
let dense = set.dense();
assert_eq!(dense.len(), 2);Sourcepub fn dense_index(&self, entity: Entity) -> Option<usize>
pub fn dense_index(&self, entity: Entity) -> Option<usize>
Sourcepub fn get_by_dense_index(&self, dense_index: usize) -> Option<&T>
pub fn get_by_dense_index(&self, dense_index: usize) -> Option<&T>
Sourcepub fn get_mut_by_dense_index(&mut self, dense_index: usize) -> Option<&mut T>
pub fn get_mut_by_dense_index(&mut self, dense_index: usize) -> Option<&mut T>
Returns a mutable reference to the value at the given dense index.
Source§impl<T> SparseSet<T>
impl<T> SparseSet<T>
Sourcepub fn insert_with_tick(
&mut self,
entity: Entity,
value: T,
change_tick: u32,
) -> Option<T>
pub fn insert_with_tick( &mut self, entity: Entity, value: T, change_tick: u32, ) -> Option<T>
Inserts a value for the given entity, recording the given change_tick.
On a new insert both added_tick and changed_tick are set to
change_tick. On a replacement only changed_tick is updated.
If the entity already has a value, the old value is returned.
§Panics
Panics if entity is a placeholder.
Sourcepub fn get_added_tick(&self, entity: Entity) -> Option<u32>
pub fn get_added_tick(&self, entity: Entity) -> Option<u32>
Returns the added tick for the given entity, if present.
Sourcepub fn get_changed_tick(&self, entity: Entity) -> Option<u32>
pub fn get_changed_tick(&self, entity: Entity) -> Option<u32>
Returns the changed tick for the given entity, if present.
Sourcepub fn set_changed_tick(&mut self, entity: Entity, tick: u32)
pub fn set_changed_tick(&mut self, entity: Entity, tick: u32)
Sets the changed tick for the given entity.
Does nothing if the entity is not in the set.
Trait Implementations§
Source§impl<T> AnyComponentStorage for SparseSet<T>where
T: Component,
impl<T> AnyComponentStorage for SparseSet<T>where
T: Component,
Source§fn contains_entity(&self, entity: Entity) -> bool
fn contains_entity(&self, entity: Entity) -> bool
true if the entity has a component in this storage.Source§fn remove_entity(&mut self, entity: Entity) -> bool
fn remove_entity(&mut self, entity: Entity) -> bool
Source§fn storage_len(&self) -> usize
fn storage_len(&self) -> usize
Source§fn storage_is_empty(&self) -> bool
fn storage_is_empty(&self) -> bool
true if this storage contains no components.Source§fn component_type_name(&self) -> &'static str
fn component_type_name(&self) -> &'static str
Source§impl<T> ComponentStorage for SparseSet<T>where
T: Component,
impl<T> ComponentStorage for SparseSet<T>where
T: Component,
Source§fn insert(&mut self, entity: Entity, value: T) -> Option<T>
fn insert(&mut self, entity: Entity, value: T) -> Option<T>
Source§fn remove(&mut self, entity: Entity) -> Option<T>
fn remove(&mut self, entity: Entity) -> Option<T>
Source§fn get(&self, entity: Entity) -> Option<&T>
fn get(&self, entity: Entity) -> Option<&T>
Source§fn get_mut(&mut self, entity: Entity) -> Option<&mut T>
fn get_mut(&mut self, entity: Entity) -> Option<&mut T>
Source§impl<'a, T> IntoIterator for &'a SparseSet<T>
impl<'a, T> IntoIterator for &'a SparseSet<T>
Source§impl<'a, T> IntoIterator for &'a mut SparseSet<T>
impl<'a, T> IntoIterator for &'a mut SparseSet<T>
Auto Trait Implementations§
impl<T> Freeze for SparseSet<T>
impl<T> RefUnwindSafe for SparseSet<T>where
T: RefUnwindSafe,
impl<T> Send for SparseSet<T>where
T: Send,
impl<T> Sync for SparseSet<T>where
T: Sync,
impl<T> Unpin for SparseSet<T>where
T: Unpin,
impl<T> UnsafeUnpin for SparseSet<T>
impl<T> UnwindSafe for SparseSet<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian().