sparsey 0.13.3

Entity Component System based on sparse sets
Documentation
use crate::entity::{Entity, SparseVec, SparseVecSlot};
use alloc::vec::Vec;
use core::fmt;

#[derive(Clone, Default)]
pub(crate) struct EntitySparseSet {
    sparse: SparseVec,
    entities: Vec<Entity>,
}

impl EntitySparseSet {
    pub fn insert(&mut self, entity: Entity) {
        let slot = self.sparse.get_mut_or_allocate_at(entity.sparse());

        debug_assert!(slot.is_none());

        *slot = Some(SparseVecSlot {
            index: self.entities.len() as u32,
            version: entity.version,
        });

        self.entities.push(entity);
    }

    pub fn remove(&mut self, entity: Entity) -> bool {
        let Some(raw_dense) = self.sparse.remove(entity) else {
            return false;
        };

        let dense = raw_dense as usize;
        self.entities.swap_remove(dense);

        if let Some(entity) = self.entities.get(dense) {
            unsafe {
                *self.sparse.get_unchecked_mut(entity.sparse()) = Some(SparseVecSlot {
                    index: raw_dense,
                    version: entity.version,
                });
            }
        }

        true
    }

    #[inline]
    #[must_use]
    pub fn contains(&self, entity: Entity) -> bool {
        self.sparse.contains(entity)
    }

    #[inline]
    #[must_use]
    pub fn len(&self) -> usize {
        self.entities.len()
    }

    #[inline]
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.entities.is_empty()
    }

    #[inline]
    #[must_use]
    pub fn as_slice(&self) -> &[Entity] {
        &self.entities
    }

    #[inline]
    pub fn clear(&mut self) {
        self.sparse.clear();
        self.entities.clear();
    }
}

impl fmt::Debug for EntitySparseSet {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_set().entries(&self.entities).finish()
    }
}