use crate::EntityID;
use std::collections::HashMap;
pub trait ComponentStorage {
fn as_any(&self) -> &dyn std::any::Any;
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
fn serialize(&self) -> Result<Vec<u8>, postcard::Error>;
fn type_name(&self) -> &'static str;
}
pub struct ComponentPool<T> {
pub dense_data: Vec<T>,
pub dense_entities: Vec<EntityID>,
pub sparse_map: HashMap<EntityID, usize>,
}
impl<T: 'static + serde::Serialize> ComponentStorage for ComponentPool<T> {
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn serialize(&self) -> Result<Vec<u8>, postcard::Error> {
postcard::to_allocvec(&(&self.sparse_map, &self.dense_entities, &self.dense_data))
}
fn type_name(&self) -> &'static str {
std::any::type_name::<T>()
}
}
impl<T> ComponentPool<T> {
pub fn iter_entities(&self) -> impl Iterator<Item = (EntityID, &T)> {
self.sparse_map
.iter()
.map(move |(&entity_id, &dense_index)| (entity_id, &self.dense_data[dense_index]))
}
pub fn iter_entities_mut(&mut self) -> impl Iterator<Item = (EntityID, &mut T)> {
let dense_ptr = self.dense_data.as_mut_ptr();
self.sparse_map
.iter()
.map(move |(&entity_id, &dense_index)| unsafe {
(entity_id, &mut *dense_ptr.add(dense_index))
})
}
}