shadow_engine_2d 2.0.1

A modern, high-performance 2D game engine built in Rust with ECS, physics, particles, audio, and more
Documentation
use std::any::{Any, TypeId};
use std::collections::HashMap;

pub type EntityId = u64;

pub trait Component: Any + Send + Sync {}

pub struct Entity {
    id: EntityId,
    components: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
}

impl Entity {
    fn new(id: EntityId) -> Self {
        Self {
            id,
            components: HashMap::new(),
        }
    }

    pub fn id(&self) -> EntityId {
        self.id
    }

    pub fn add<T: Component>(&mut self, component: T) {
        self.components
            .insert(TypeId::of::<T>(), Box::new(component));
    }

    pub fn get<T: Component>(&self) -> Option<&T> {
        self.components
            .get(&TypeId::of::<T>())
            .and_then(|c| c.downcast_ref::<T>())
    }

    pub fn get_mut<T: Component>(&mut self) -> Option<&mut T> {
        self.components
            .get_mut(&TypeId::of::<T>())
            .and_then(|c| c.downcast_mut::<T>())
    }

    pub fn has<T: Component>(&self) -> bool {
        self.components.contains_key(&TypeId::of::<T>())
    }

    pub fn remove<T: Component>(&mut self) -> Option<T> {
        self.components
            .remove(&TypeId::of::<T>())
            .and_then(|c| c.downcast::<T>().ok())
            .map(|c| *c)
    }
}

pub struct World {
    entities: HashMap<EntityId, Entity>,
    next_id: EntityId,
}

impl World {
    pub fn new() -> Self {
        Self {
            entities: HashMap::new(),
            next_id: 0,
        }
    }

    pub fn spawn(&mut self) -> EntityId {
        let id = self.next_id;
        self.next_id += 1;
        self.entities.insert(id, Entity::new(id));
        id
    }

    pub fn entity(&self, id: EntityId) -> Option<&Entity> {
        self.entities.get(&id)
    }

    pub fn entity_mut(&mut self, id: EntityId) -> Option<&mut Entity> {
        self.entities.get_mut(&id)
    }

    pub fn despawn(&mut self, id: EntityId) -> bool {
        self.entities.remove(&id).is_some()
    }

    pub fn query<T: Component>(&self) -> Vec<(EntityId, &T)> {
        self.entities
            .iter()
            .filter_map(|(id, entity)| entity.get::<T>().map(|c| (*id, c)))
            .collect()
    }

    pub fn query_mut<T: Component>(&mut self) -> Vec<(EntityId, &mut T)> {
        self.entities
            .iter_mut()
            .filter_map(|(id, entity)| entity.get_mut::<T>().map(|c| (*id, c)))
            .collect()
    }

    pub fn entities(&self) -> impl Iterator<Item = &Entity> {
        self.entities.values()
    }

    pub fn entities_mut(&mut self) -> impl Iterator<Item = &mut Entity> {
        self.entities.values_mut()
    }
}

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