Skip to main content

SparseSet

Struct SparseSet 

Source
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>

Source

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);
Source

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());
Source

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 value
  • value - 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));
Source

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 removed
Source

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);
Source

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));
Source

pub fn contains(&self, entity: Entity) -> bool

Returns true if the entity has a value in this set.

§Arguments
  • entity - The entity to check
§Example
use goud_engine::ecs::{Entity, SparseSet};

let mut set = SparseSet::new();
let entity = Entity::new(0, 1);

assert!(!set.contains(entity));
set.insert(entity, "value");
assert!(set.contains(entity));
Source

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);
Source

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());
Source

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());
Source

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>

Source

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);
}
Source

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));
Source

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);
Source

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);
Source

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 + 21
Source

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);
Source

pub fn dense_index(&self, entity: Entity) -> Option<usize>

Returns the dense index for an entity, if it exists.

This is an advanced method for implementing custom storage operations.

§Arguments
  • entity - The entity to look up
§Returns

The index in the dense array, or None if the entity has no value.

Source

pub fn get_by_dense_index(&self, dense_index: usize) -> Option<&T>

Returns the value at the given dense index.

§Safety

This method does not validate the index. Use dense_index() to get a valid index first.

§Arguments
  • dense_index - Index into the dense/values arrays
Source

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>

Source

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.

Source

pub fn get_added_tick(&self, entity: Entity) -> Option<u32>

Returns the added tick for the given entity, if present.

Source

pub fn get_changed_tick(&self, entity: Entity) -> Option<u32>

Returns the changed tick for the given entity, if present.

Source

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,

Source§

fn contains_entity(&self, entity: Entity) -> bool

Returns true if the entity has a component in this storage.
Source§

fn remove_entity(&mut self, entity: Entity) -> bool

Removes the component for the given entity (dropping the value). Read more
Source§

fn storage_len(&self) -> usize

Returns the number of components in this storage.
Source§

fn storage_is_empty(&self) -> bool

Returns true if this storage contains no components.
Source§

fn clear(&mut self)

Clears all components from this storage.
Source§

fn component_type_name(&self) -> &'static str

Returns the type name of the stored component (for debugging).
Source§

impl<T> Clone for SparseSet<T>
where T: Clone,

Source§

fn clone(&self) -> SparseSet<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> ComponentStorage for SparseSet<T>
where T: Component,

Source§

type Item = T

The component type stored in this storage.
Source§

fn insert(&mut self, entity: Entity, value: T) -> Option<T>

Inserts a component for the given entity. Read more
Source§

fn remove(&mut self, entity: Entity) -> Option<T>

Removes the component for the given entity. Read more
Source§

fn get(&self, entity: Entity) -> Option<&T>

Returns a reference to the component for the given entity. Read more
Source§

fn get_mut(&mut self, entity: Entity) -> Option<&mut T>

Returns a mutable reference to the component for the given entity. Read more
Source§

fn contains(&self, entity: Entity) -> bool

Returns true if the entity has a component in this storage. Read more
Source§

fn len(&self) -> usize

Returns the number of components in this storage.
Source§

fn is_empty(&self) -> bool

Returns true if this storage contains no components.
Source§

impl<T> Debug for SparseSet<T>
where T: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<T> Default for SparseSet<T>

Source§

fn default() -> SparseSet<T>

Returns the “default value” for a type. Read more
Source§

impl<'a, T> IntoIterator for &'a SparseSet<T>

Source§

type Item = (Entity, &'a T)

The type of the elements being iterated over.
Source§

type IntoIter = SparseSetIter<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'a SparseSet<T> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'a, T> IntoIterator for &'a mut SparseSet<T>

Source§

type Item = (Entity, &'a mut T)

The type of the elements being iterated over.
Source§

type IntoIter = SparseSetIterMut<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'a mut SparseSet<T> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> Event for T
where T: Send + Sync + 'static,

Source§

impl<T> QueryState for T
where T: Send + Sync + Clone + 'static,

Source§

impl<T> Resource for T
where T: Send + Sync + 'static,