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()
}
}