mod errors;
pub use crate::errors::*;
use hashbrown::HashMap;
pub use persist_o_vec::Persist;
use std::any::{Any, TypeId};
use std::cell::{Ref, RefCell, RefMut};
use std::ops::{Deref, DerefMut};
#[cfg(feature = "component_max_31")]
type BitMaskType = u32;
#[cfg(feature = "component_max_63")]
type BitMaskType = u64;
#[cfg(feature = "component_max_127")]
type BitMaskType = u128;
#[cfg(feature = "component_max_31")]
const BIT_MASK_MAX: BitMaskType = 31;
#[cfg(feature = "component_max_63")]
const BIT_MASK_MAX: BitMaskType = 63;
#[cfg(feature = "component_max_127")]
const BIT_MASK_MAX: BitMaskType = 127;
const EMPTY: BitMaskType = 0;
pub struct MapRef<'a, T> {
_borrow: Ref<'a, dyn Any>,
value: &'a Persist<T>,
}
impl<'a, T: 'static> MapRef<'a, T> {
fn new(value: &'a RefCell<Box<dyn Any>>) -> Result<MapRef<'a, T>, ECSError> {
let borrow = value.try_borrow().or(Err(ECSError::Borrow))?;
let v = (unsafe { value.as_ptr().as_ref() })
.ok_or(ECSError::PtrRef)?
.downcast_ref::<Persist<T>>()
.ok_or(ECSError::Downcast)?;
Ok(MapRef {
value: v,
_borrow: borrow,
})
}
}
impl<'a, T> Deref for MapRef<'a, T> {
type Target = Persist<T>;
#[inline]
fn deref(&self) -> &Persist<T> {
self.value
}
}
pub struct MapRefMut<'a, T> {
_borrow: RefMut<'a, dyn Any>,
value: &'a mut Persist<T>,
}
impl<'a, T: 'static> MapRefMut<'a, T> {
#[inline]
fn new(value: &'a RefCell<Box<dyn Any>>) -> Result<MapRefMut<'a, T>, ECSError> {
let borrow = value.try_borrow_mut().or(Err(ECSError::BorrowMut))?;
let v = (unsafe { value.as_ptr().as_mut() })
.ok_or(ECSError::PtrMut)?
.downcast_mut::<Persist<T>>()
.ok_or(ECSError::DowncastMut)?;
Ok(MapRefMut {
value: v,
_borrow: borrow,
})
}
}
impl<'a, T> Deref for MapRefMut<'a, T> {
type Target = Persist<T>;
#[inline]
fn deref(&self) -> &Persist<T> {
self.value
}
}
impl<'a, T> DerefMut for MapRefMut<'a, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Persist<T> {
self.value
}
}
#[derive(Debug)]
pub struct Entities {
entity_masks: Vec<BitMaskType>,
components: Vec<RefCell<Box<dyn Any>>>,
next_free_entity: usize,
current_entity: Option<usize>,
vacated_slots: Vec<usize>,
type_masks: HashMap<TypeId, (BitMaskType, usize)>,
next_typemask: BitMaskType,
}
impl Default for Entities {
fn default() -> Self {
Entities::new(None, None)
}
}
impl Entities {
pub fn new(entity_count: Option<usize>, component_count: Option<usize>) -> Entities {
if let Some(count) = component_count {
if count as BitMaskType > BIT_MASK_MAX {
panic!(
"Initial part count too large. Maximum of {} allowed",
BIT_MASK_MAX
);
}
}
Entities {
entity_masks: vec![EMPTY; entity_count.unwrap_or(0)],
components: Vec::with_capacity(component_count.unwrap_or(0)),
next_free_entity: 0,
current_entity: None,
vacated_slots: Vec::new(),
type_masks: HashMap::with_capacity(component_count.unwrap_or(0)),
next_typemask: 1,
}
}
#[inline]
pub fn new_entity(&mut self) -> &mut Self {
if let Some(slot) = self.vacated_slots.pop() {
self.current_entity = Some(slot);
} else {
self.current_entity = Some(self.next_free_entity);
self.next_free_entity += 1;
}
self
}
#[inline]
pub fn with<T: 'static>(&mut self, part: T) -> Result<&mut Self, ECSError> {
if self.current_entity.is_none() {
return Err(ECSError::WithAfterFinalise);
}
let type_id = TypeId::of::<T>();
let (type_mask, type_index) = {
if !self.type_masks.contains_key(&type_id) {
if (self.type_masks.len() as BitMaskType) >= BIT_MASK_MAX {
return Err(ECSError::BitMasksExhausted);
}
self.components
.push(RefCell::new(Box::new(Persist::<T>::with_capacity(
self.entity_masks.len() + self.vacated_slots.len(),
))));
self.type_masks
.insert(type_id, (self.next_typemask, self.components.len() - 1));
self.next_typemask <<= 1;
}
self.type_masks[&type_id]
};
let entity_mask = self.entity_masks[self.current_entity.unwrap()];
if entity_mask & type_mask == type_mask {
return Err(ECSError::AddDupeComponent);
}
let id = self.current_entity.unwrap();
if let Some(col) = self.components.get_mut(type_index) {
col.borrow_mut()
.downcast_mut::<Persist<T>>()
.ok_or(ECSError::DowncastMut)?
.insert(id, part);
let old = self.entity_masks[id];
self.entity_masks[id] = old | type_mask;
}
Ok(self)
}
#[inline]
pub fn finalise(&mut self) -> Result<usize, ECSError> {
if let Some(entity) = self.current_entity {
self.current_entity = None;
return Ok(entity);
}
Err(ECSError::FinaliseNonEntity)
}
#[inline]
pub fn entity_exists(&self, id: usize) -> bool {
if let Some(ent) = self.entity_masks.get(id) {
return *ent > 0;
}
false
}
#[inline]
pub fn entity_contains<T: 'static>(&self, id: usize) -> bool {
if let Some(entity_mask) = self.entity_masks.get(id) {
if let Some((type_mask, _)) = self.type_masks.get(&TypeId::of::<T>()) {
if entity_mask & type_mask == *type_mask {
return true;
}
}
}
false
}
#[deprecated]
pub fn rm_component<T: 'static>(&mut self, id: usize) -> Result<(), ECSError> {
self.rm_component_from::<T>(id)
}
#[inline]
pub fn rm_component_from<T: 'static>(&mut self, id: usize) -> Result<(), ECSError> {
let type_id = TypeId::of::<T>();
if let Some((type_mask, type_index)) = self.type_masks.get(&type_id) {
if let Some(map) = self.components.get_mut(*type_index) {
map.borrow_mut()
.downcast_mut::<Persist<T>>()
.ok_or(ECSError::DowncastMut)?
.remove(id);
self.entity_masks[id] ^= *type_mask;
if self.entity_masks[id] == EMPTY {
self.vacated_slots.push(id)
}
return Ok(());
}
}
Err(ECSError::NoComponentMap)
}
#[deprecated]
pub fn add_component<T: 'static>(&mut self, id: usize, component: T) -> Result<(), ECSError> {
self.add_component_to(id, component)
}
#[inline]
pub fn add_component_to<T: 'static>(
&mut self,
id: usize,
component: T,
) -> Result<(), ECSError> {
if let Some(ent) = self.entity_masks.get(id) {
if *ent == 0 {
return Err(ECSError::WithAfterFinalise);
}
}
self.current_entity = Some(id);
self.with(component)?.finalise()?;
Ok(())
}
#[inline(always)]
pub fn borrow<T: 'static>(&self) -> Result<MapRef<T>, ECSError> {
let type_id = TypeId::of::<T>();
if let Some((_, type_index)) = self.type_masks.get(&type_id) {
if let Some(components) = self.components.get(*type_index) {
return Ok(MapRef::new(components)?);
}
}
Err(ECSError::NoComponentMap)
}
#[inline(always)]
pub unsafe fn borrow_unchecked<T: 'static>(&self) -> Result<&Persist<T>, ECSError> {
let type_id = TypeId::of::<T>();
if let Some((_, type_index)) = self.type_masks.get(&type_id) {
if let Some(components) = self.components.get(*type_index) {
let components = (&*components.as_ptr())
.downcast_ref::<Persist<T>>()
.ok_or(ECSError::Downcast)?;
return Ok(components);
}
}
Err(ECSError::NoComponentMap)
}
#[inline(always)]
pub fn borrow_mut<T: 'static>(&self) -> Result<MapRefMut<T>, ECSError> {
let type_id = TypeId::of::<T>();
if let Some((_, type_index)) = self.type_masks.get(&type_id) {
if let Some(components) = self.components.get(*type_index) {
return Ok(MapRefMut::new(components)?);
}
}
Err(ECSError::NoComponentMap)
}
#[inline(always)]
pub unsafe fn borrow_mut_unchecked<T: 'static>(&self) -> Result<&mut Persist<T>, ECSError> {
let type_id = TypeId::of::<T>();
if let Some((_, type_index)) = self.type_masks.get(&type_id) {
if let Some(components) = self.components.get(*type_index) {
let components = (&mut *components.as_ptr())
.downcast_mut::<Persist<T>>()
.ok_or(ECSError::Downcast)?;
return Ok(components);
}
}
Err(ECSError::NoComponentMap)
}
}