use std::any::{Any, TypeId};
use std::collections::HashMap;
pub type EntityId = u32;
pub trait Component: 'static + Send + Sync {}
pub struct World {
next_entity_id: EntityId,
entities: Vec<EntityId>,
components: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
}
impl Default for World {
fn default() -> Self {
Self::new()
}
}
impl World {
pub fn new() -> Self {
Self {
next_entity_id: 0,
entities: Vec::new(),
components: HashMap::new(),
}
}
pub fn create_entity(&mut self) -> EntityId {
let id = self.next_entity_id;
self.next_entity_id += 1;
self.entities.push(id);
id
}
pub fn spawn(&mut self) -> EntityBuilder<'_> {
let id = self.create_entity();
EntityBuilder {
world: self,
entity: id,
}
}
pub fn add_component<T: Component>(&mut self, entity: EntityId, component: T) {
let type_id = TypeId::of::<T>();
let storage = self
.components
.entry(type_id)
.or_insert_with(|| Box::new(HashMap::<EntityId, T>::new()));
if let Some(storage) = storage.downcast_mut::<HashMap<EntityId, T>>() {
storage.insert(entity, component);
}
}
pub fn get_component<T: Component>(&self, entity: EntityId) -> Option<&T> {
let type_id = TypeId::of::<T>();
self.components
.get(&type_id)?
.downcast_ref::<HashMap<EntityId, T>>()?
.get(&entity)
}
pub fn get_component_mut<T: Component>(&mut self, entity: EntityId) -> Option<&mut T> {
let type_id = TypeId::of::<T>();
self.components
.get_mut(&type_id)?
.downcast_mut::<HashMap<EntityId, T>>()?
.get_mut(&entity)
}
pub fn remove_component<T: Component>(&mut self, entity: EntityId) -> Option<T> {
let type_id = TypeId::of::<T>();
self.components
.get_mut(&type_id)?
.downcast_mut::<HashMap<EntityId, T>>()?
.remove(&entity)
}
pub fn query<T: Component>(&self) -> impl Iterator<Item = (EntityId, &T)> {
let type_id = TypeId::of::<T>();
self.components
.get(&type_id)
.and_then(|storage| storage.downcast_ref::<HashMap<EntityId, T>>())
.map(|storage| storage.iter().map(|(&id, component)| (id, component)))
.into_iter()
.flatten()
}
pub fn query_mut<T: Component>(&mut self) -> impl Iterator<Item = (EntityId, &mut T)> {
let type_id = TypeId::of::<T>();
self.components
.get_mut(&type_id)
.and_then(|storage| storage.downcast_mut::<HashMap<EntityId, T>>())
.map(|storage| storage.iter_mut().map(|(&id, component)| (id, component)))
.into_iter()
.flatten()
}
pub fn has_component<T: Component>(&self, entity: EntityId) -> bool {
self.get_component::<T>(entity).is_some()
}
pub fn despawn(&mut self, entity: EntityId) {
self.entities.retain(|&e| e != entity);
for _storage in self.components.values_mut() {
}
}
pub fn entities(&self) -> &[EntityId] {
&self.entities
}
}
pub struct EntityBuilder<'a> {
world: &'a mut World,
entity: EntityId,
}
impl<'a> EntityBuilder<'a> {
pub fn with<T: Component>(self, component: T) -> Self {
self.world.add_component(self.entity, component);
self
}
pub fn id(&self) -> EntityId {
self.entity
}
pub fn build(self) -> EntityId {
self.entity
}
}
impl<'a> Drop for EntityBuilder<'a> {
fn drop(&mut self) {
}
}