pub(crate) mod channel;
use std::{any::TypeId, collections::HashMap, hash::Hash};
use super::query::*;
use channel::{ComponentChannel, ComponentMap, ErasedComponentChannel};
#[derive(Default)]
pub struct Components {
components: HashMap<TypeId, Box<dyn ErasedComponentChannel>>,
}
impl Components {
pub fn spawn<C>(&mut self, component: C)
where
C: 'static,
{
let id = TypeId::of::<C>();
self.components
.entry(id)
.or_insert(ComponentChannel::<C>::new_box())
.as_any_mut()
.downcast_mut::<ComponentChannel<C>>()
.map(|c| c.push(component));
}
pub fn spawn_indexed<K, C>(&mut self, key: K, component: C)
where
K: Eq + Hash + 'static,
C: 'static,
{
let id = TypeId::of::<(K, C)>();
self.components
.entry(id)
.or_insert(ComponentMap::<K, C>::new_box())
.as_any_mut()
.downcast_mut::<ComponentMap<K, C>>()
.map(|c| c.insert(key, component));
}
pub fn query<'c, C>(&'c self) -> Query<'c, C>
where
C: 'static,
{
let id = TypeId::of::<C>();
let channel = self.components
.get(&id)
.map(|c| c.as_any())
.and_then(|c| c.downcast_ref::<ComponentChannel::<C>>());
Query::<C>::from_channel(channel)
}
pub fn query_mut<'c, C>(&'c mut self) -> QueryMut<'c, C>
where
C: 'static,
{
let id = TypeId::of::<C>();
let channel = self.components
.get_mut(&id)
.map(|c| c.as_any_mut())
.and_then(|c| c.downcast_mut::<ComponentChannel::<C>>());
QueryMut::<C>::from_channel(channel)
}
pub fn query_indexed<'c, K, C>(&'c self) -> QueryIndexed<'c, K, C>
where
K: Eq + Hash + 'static,
C: 'static,
{
let id = TypeId::of::<(K, C)>();
let channel = self.components
.get(&id)
.map(|c| c.as_any())
.and_then(|c| c.downcast_ref::<ComponentMap<K, C>>());
QueryIndexed::from_channel(channel)
}
pub fn query_indexed_mut<'c, K, C>(&'c mut self) -> QueryIndexedMut<'c, K, C>
where
K: Eq + Hash + 'static,
C: 'static,
{
let id = TypeId::of::<(K, C)>();
let channel = self.components
.get_mut(&id)
.map(|c| c.as_any_mut())
.and_then(|c| c.downcast_mut::<ComponentMap<K, C>>());
QueryIndexedMut::from_channel(channel)
}
}