pub mod entity_id;
pub mod iter;
mod pred;
pub use entity_id::EntityId;
pub use iter::{PredIter, PredIterMut};
use pred::{Predicate, PredicateIds};
use std::collections::HashMap;
use std::iter::Iterator;
use std::cell::Cell;
use crate::{KeyType, Storage, Entity};
pub struct World<'a, S>
where
S : Storage<'a>,
S::Id: KeyType,
{
pub(in self) entities: HashMap<EntityId, Entity<'a, S>>,
next_entity_id: EntityId,
pub(in self) predicates: HashMap<usize, PredicateIds<'a, S>>,
next_pred_id: usize,
}
impl<'a, S> World<'a, S>
where
S : Storage<'a>,
S::Id: KeyType,
{
#[must_use]
pub fn new() -> Self
{
Self {
entities: HashMap::new(),
next_entity_id : EntityId::new(1),
predicates: HashMap::new(),
next_pred_id: 1,
}
}
#[must_use]
pub fn from_entities(entities: Vec< Entity<'a, S> >) -> Self
{
let mut world = Self::new();
for entity in entities {
world.add(entity);
}
world
}
pub fn add(&mut self, entity: Entity<'a, S>) -> EntityId
{
let id = self.next_entity_id;
self.next_entity_id.inc();
for PredicateIds { pred, ids } in self.predicates.values_mut()
{
ids.retain(|id| !id.get().is_null());
if pred(&entity) {
ids.push( Cell::new(id) )
}
}
self.entities.insert(id, entity);
id
}
pub fn remove(&mut self, id: EntityId) -> Option< Entity<'a, S> >
{
self.entities.remove(&id)
}
#[must_use]
pub fn get(&self, id: EntityId) -> Option<&Entity<'a, S>> {
self.entities.get(&id)
}
#[must_use]
pub fn get_mut(&mut self, id: EntityId) -> Option<&mut Entity<'a, S>> {
self.entities.get_mut(&id)
}
#[allow(clippy::integer_arithmetic)] pub fn add_pred<F>(&mut self, f: F) -> usize
where
F: Fn(&Entity<'a, S>) -> bool + 'static
{
let id = self.next_pred_id;
self.next_pred_id += 1;
let mut ids = vec![];
for (&entity_id, entity) in &self.entities
{
if f(entity) {
ids.push( Cell::new(entity_id) );
}
}
self.predicates.insert(id, PredicateIds{ pred: Predicate( Box::new(f) ), ids });
id
}
pub fn iter_all(&self) -> impl Iterator<Item = &Entity<'a, S>> {
self.entities.values()
}
pub fn iter_mut_all(&mut self) -> impl Iterator<Item = &mut Entity<'a, S>> {
self.entities.values_mut()
}
#[must_use]
pub fn iter_pred(&self, id: usize) -> Option< PredIter<'a, '_, S> > {
if self.predicates.get(&id).is_some() {
Some( PredIter {
world: self,
id,
cur_idx: 0,
})
} else {
None
}
}
#[must_use]
pub fn iter_pred_mut(&mut self, id: usize) -> Option< PredIterMut<'a, '_, S> > {
if self.predicates.get(&id).is_some() {
Some( PredIterMut {
world: self,
id,
cur_idx: 0,
})
} else {
None
}
}
}
impl<'a, S> Default for World<'a, S>
where
S : Storage<'a>,
S::Id: KeyType,
{
#[must_use]
fn default() -> Self {
Self::new()
}
}
impl<'a, S> PartialEq for World<'a, S>
where
S : Storage<'a> + PartialEq,
S::Id: KeyType,
{
#[must_use]
fn eq(&self, other: &Self) -> bool
{
self.entities == other.entities
}
}
impl<'a, S> Eq for World<'a, S>
where
S : Storage<'a> + Eq,
S::Id: KeyType,
{}
#[cfg(feature = "serde-serialize")]
impl<'a, S> serde::Serialize for World<'a, S>
where
S : Storage<'a> + serde::Serialize,
S::Id: KeyType,
{
fn serialize<SS>(&self, serializer: SS) -> Result<SS::Ok, SS::Error>
where
SS: serde::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq( Some(self.entities.len()) )?;
for entity in self.entities.values() {
seq.serialize_element(entity)?;
}
seq.end()
}
}
#[cfg(feature = "serde-serialize")]
impl<'a, 'de, S> serde::Deserialize<'de> for World<'a, S>
where
S : Storage<'a> + serde::Deserialize<'de>,
S::Id: KeyType,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let entities = Vec::deserialize(deserializer)?;
Ok( Self::from_entities(entities) )
}
}