mod util;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EntityKey(usize);
pub trait Component: bytemuck::Pod {}
#[derive(Debug)]
struct ComponentColumn {
sparse: util::SparseIndex<256>,
dense: util::BlobStorage,
rev: Vec<usize>,
}
impl ComponentColumn {
#[inline]
fn new<T>() -> Self where T: Component {
Self {
sparse: Default::default(),
dense: util::BlobStorage::new::<T>(),
rev: Default::default(),
}
}
fn insert<T>(&mut self, entity_key: usize, comp: T) -> Option<T> where T: Component {
if let Some(index) = self.sparse.get(entity_key) {
let target = self.dense.get_mut::<T>(*index).unwrap();
let old = std::mem::replace(target, comp);
return Some(old);
}
let index = self.dense.len();
self.dense.push(comp);
self.rev.push(entity_key);
self.sparse.insert(entity_key, index);
None
}
fn remove(&mut self, entity_key: usize) -> Option<()> {
let index = self.sparse.remove(entity_key)?;
self.dense.swap_remove(index);
self.rev.swap_remove(index);
if let Some(entity_key) = self.rev.get(index) {
let target = self.sparse.get_mut(*entity_key).unwrap();
*target = index;
}
Some(())
}
#[inline]
fn get<T>(&self, entity_key: usize) -> Option<&T> where T: Component {
let index = *self.sparse.get(entity_key)?;
let component = self.dense.get(index).unwrap();
Some(component)
}
#[inline]
fn get_mut<T>(&mut self, entity_key: usize) -> Option<&mut T> where T: Component {
let index = *self.sparse.get(entity_key)?;
let component = self.dense.get_mut(index).unwrap();
Some(component)
}
#[inline]
fn iter<T>(&self) -> impl Iterator<Item = &T> where T: Component {
self.dense.iter()
}
#[inline]
fn iter_mut<T>(&mut self) -> impl Iterator<Item = &mut T> where T: Component {
self.dense.iter_mut()
}
}
#[derive(Debug, Default)]
pub struct World {
entities: slab::Slab<()>,
component_table: util::IndexMap<std::any::TypeId, ComponentColumn>,
}
impl World {
#[inline]
pub fn new() -> Self {
Default::default()
}
pub fn insert_entity(&mut self) -> EntityKey {
let entity_key = self.entities.insert(());
EntityKey(entity_key)
}
pub fn remove_entity(&mut self, entity_key: EntityKey) -> Option<()> {
let EntityKey(entity_key) = entity_key;
self.entities.try_remove(entity_key)?;
for component_column in self.component_table.iter_mut() {
component_column.remove(entity_key);
}
Some(())
}
#[inline]
pub fn contains_entity(&self, entity_key: EntityKey) -> bool {
let EntityKey(entity_key) = entity_key;
self.entities.get(entity_key).is_some()
}
#[inline]
pub fn iter_entity(&self) -> impl Iterator<Item = EntityKey> + '_ {
self.entities.iter().map(|(entity_key, _)| EntityKey(entity_key))
}
pub fn insert_component<T>(&mut self, entity_key: EntityKey, component: T) -> Option<()> where T: Component {
let EntityKey(entity_key) = entity_key;
self.entities.get(entity_key)?;
let type_key = std::any::TypeId::of::<T>();
if !self.component_table.contains_key(&type_key) {
self.component_table.insert(type_key, ComponentColumn::new::<T>());
}
let component_column = self.component_table.get_mut(&type_key).unwrap();
component_column.insert(entity_key, component);
Some(())
}
pub fn remove_component<T>(&mut self, entity_key: EntityKey) -> Option<()> where T: Component {
let EntityKey(entity_key) = entity_key;
self.entities.get(entity_key)?;
let type_key = std::any::TypeId::of::<T>();
let component_column = self.component_table.get_mut(&type_key)?;
component_column.remove(entity_key)?;
Some(())
}
#[inline]
pub fn get_component<T>(&self, entity_key: EntityKey) -> Option<&T> where T: Component {
let EntityKey(entity_key) = entity_key;
self.entities.get(entity_key)?;
let type_key = std::any::TypeId::of::<T>();
let component_column = self.component_table.get(&type_key)?;
let component = component_column.get(entity_key)?;
Some(component)
}
#[inline]
pub fn get_component_mut<T>(&mut self, entity_key: EntityKey) -> Option<&mut T> where T: Component {
let EntityKey(entity_key) = entity_key;
self.entities.get(entity_key)?;
let type_key = std::any::TypeId::of::<T>();
let component_column = self.component_table.get_mut(&type_key)?;
let component = component_column.get_mut(entity_key)?;
Some(component)
}
#[inline]
pub fn iter_component<T>(&self) -> impl Iterator<Item = &T> where T: Component {
let type_key = std::any::TypeId::of::<T>();
if let Some(component_column) = self.component_table.get(&type_key) {
return either::Left(component_column.iter());
}
either::Right(std::iter::empty())
}
#[inline]
pub fn iter_component_mut<T>(&mut self) -> impl Iterator<Item = &mut T> where T: Component {
let type_key = std::any::TypeId::of::<T>();
if let Some(component_column) = self.component_table.get_mut(&type_key) {
return either::Left(component_column.iter_mut());
}
either::Right(std::iter::empty())
}
}