灵符lingfu

ling-game

↓ 4890 downloads

Entity-Component-System + physics for games

Keywords game, ecs, physics, engine
lingfu install ling-game
LicenseApache-2.0 OR MIT
AuthorsLing Lin, Sanny Lin
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (13)

src/entity.rs
//! Entity-Component-System primitives.

use std::collections::HashMap;

pub type EntityId = u32;

/// Sparse-set component storage for one component type.
pub struct ComponentStore<T> {
    dense: Vec<T>,
    sparse: HashMap<EntityId, usize>,
}

impl<T> ComponentStore<T> {
    pub fn new() -> Self {
        Self { dense: vec![], sparse: HashMap::new() }
    }

    pub fn insert(&mut self, entity: EntityId, component: T) {
        if let Some(&idx) = self.sparse.get(&entity) {
            self.dense[idx] = component;
        } else {
            let idx = self.dense.len();
            self.dense.push(component);
            self.sparse.insert(entity, idx);
        }
    }

    pub fn get(&self, entity: EntityId) -> Option<&T> {
        self.sparse.get(&entity).map(|&i| &self.dense[i])
    }

    pub fn get_mut(&mut self, entity: EntityId) -> Option<&mut T> {
        self.sparse.get(&entity).map(|&i| &mut self.dense[i])
    }

    pub fn remove(&mut self, entity: EntityId) {
        self.sparse.remove(&entity);
    }

    pub fn iter(&self) -> impl Iterator<Item = (&EntityId, &T)> {
        self.sparse.iter().map(|(id, &i)| (id, &self.dense[i]))
    }
}

impl<T> Default for ComponentStore<T> {
    fn default() -> Self {
        Self::new()
    }
}

/// Simple entity allocator.
pub struct Entity {
    next: EntityId,
    free: Vec<EntityId>,
}

impl Entity {
    pub fn new() -> Self {
        Self { next: 1, free: vec![] }
    }

    pub fn spawn(&mut self) -> EntityId {
        self.free.pop().unwrap_or_else(|| {
            let id = self.next;
            self.next += 1;
            id
        })
    }

    pub fn despawn(&mut self, id: EntityId) {
        self.free.push(id);
    }
}

impl Default for Entity {
    fn default() -> Self {
        Self::new()
    }
}

← Back to index