use std::collections::HashMap;
use std::fmt::Debug;
use std::iter::Iterator;
use crate::{KeyType, Storage, Component};
#[macro_export]
macro_rules! entity
{
[ $( $cmpt:expr ),* $(,)? ] => {{
let mut entity = $crate::Entity::new();
$(
entity.add( $cmpt );
)*
entity
}};
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Entity<'a, S>
where
S : Storage<'a>,
S::Id: KeyType,
{
components: HashMap<S::Id, S>,
}
impl<'a, S> Entity<'a, S>
where
S : Storage<'a>,
S::Id: KeyType,
{
#[must_use]
pub fn new() -> Self {
Self {
components: HashMap::new(),
}
}
#[must_use]
pub fn from_components(components: Vec<S>) -> Self
{
let mut entity = Self::new();
for component in components {
entity.add(component);
}
entity
}
pub fn add(&mut self, storage: S) -> Option<S>
{
self.components.insert(storage.id(), storage)
}
pub fn remove<C: Component<'a, S>>(&mut self) -> Option<S>
{
self.remove_id( &C::id() )
}
pub fn remove_id(&mut self, id: &S::Id) -> Option<S>
{
self.components.remove(id)
}
#[must_use]
pub fn get<C: Component<'a, S>>(&self) -> Option<&C>
{
self.get_id( &C::id() )
.map(C::get)
.flatten()
}
#[must_use]
pub fn get_mut<C: Component<'a, S>>(&mut self) -> Option<&mut C>
{
self.get_mut_id( &C::id() )
.map(C::get_mut)
.flatten()
}
#[must_use]
pub fn get_id(&self, id: &S::Id) -> Option<&S> {
self.components.get(id)
}
#[must_use]
pub fn get_mut_id(&mut self, id: &S::Id) -> Option<&mut S> {
self.components.get_mut(id)
}
pub fn ids(&self) -> impl Iterator<Item = &<S as Storage<'a>>::Id> {
self.components.keys()
}
#[must_use]
pub fn components(&self) -> std::collections::hash_map::Values<'_, S::Id, S> {
self.components.values()
}
#[must_use]
pub fn components_mut(&mut self) -> std::collections::hash_map::ValuesMut<'_, S::Id, S> {
self.components.values_mut()
}
#[must_use]
pub fn has<C: Component<'a, S>>(&self) -> bool {
self.has_id( &C::id() )
}
#[must_use]
pub fn has_id(&self, id: &S::Id) -> bool {
self.components.contains_key(id)
}
}
impl<'a, S> Default for Entity<'a, S>
where
S : Storage<'a>,
S::Id: KeyType,
{
#[must_use]
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "serde-serialize")]
impl<'a, S> serde::Serialize for Entity<'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.components.len()) )?;
for component in self.components.values() {
seq.serialize_element(component)?;
}
seq.end()
}
}
#[cfg(feature = "serde-serialize")]
impl<'a, 'de, S> serde::Deserialize<'de> for Entity<'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 components = Vec::deserialize(deserializer)?;
Ok( Self::from_components(components) )
}
}