sparsey 0.13.3

Entity Component System based on sparse sets
Documentation
use crate::entity::{Entity, EntityAllocator, EntitySparseSet};

#[derive(Default, Debug)]
pub(crate) struct EntityStorage {
    allocator: EntityAllocator,
    entities: EntitySparseSet,
}

impl EntityStorage {
    #[must_use]
    pub fn create(&mut self) -> Entity {
        if self.allocator.should_maintain_recyled() {
            self.maintain_recycled();
        }

        let entity = self
            .allocator
            .allocate()
            .expect("No entities left to allocate");

        self.entities.insert(entity);
        entity
    }

    #[must_use]
    pub fn create_atomic(&self) -> Entity {
        self.allocator
            .allocate_atomic()
            .expect("No entities left to allocate")
    }

    pub fn maintain(&mut self) {
        self.maintain_recycled();
        self.maintain_new();
    }

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

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

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

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

    pub fn remove(&mut self, entity: Entity) -> bool {
        if !self.entities.remove(entity) {
            return false;
        }

        self.allocator.recycle(entity);
        true
    }

    pub fn clear(&mut self) {
        let _ = self.allocator.maintain_new();
        let _ = self.allocator.maintain_recycled();
        self.entities.clear();
    }

    pub fn reset(&mut self) {
        self.allocator.reset();
        self.entities.clear();
    }

    #[cold]
    fn maintain_recycled(&mut self) {
        self.allocator
            .maintain_recycled()
            .for_each(|entity| self.entities.insert(entity));
    }

    fn maintain_new(&mut self) {
        self.allocator
            .maintain_new()
            .for_each(|entity| self.entities.insert(entity));
    }
}