use std::ops::{Deref, DerefMut};
use crate::aspect::Aspect;
use crate::entity::{EntityData, EntityIter};
use crate::system::watcher::Watcher;
use crate::system::{Process, System};
use crate::world::DataHelper;
pub trait EntityProcess: FilteredEntitySystem {
fn process<'a>(
&mut self,
entities: EntityIter<'a, Self::Components>,
data: &mut DataHelper<Self::Components, Self::Services>,
);
}
pub trait FilteredEntitySystem: System {
fn create_aspect() -> Aspect<Self::Components>;
}
#[derive(Debug)]
pub struct EntitySystem<T>
where
T: EntityProcess,
{
pub inner: T,
pub watcher: Watcher<T::Components>,
}
impl<T> Deref for EntitySystem<T>
where
T: EntityProcess,
{
type Target = T;
fn deref(&self) -> &T {
&self.inner
}
}
impl<T> DerefMut for EntitySystem<T>
where
T: EntityProcess,
{
fn deref_mut(&mut self) -> &mut T {
&mut self.inner
}
}
impl<T> EntitySystem<T>
where
T: EntityProcess,
{
pub fn new() -> EntitySystem<T> {
EntitySystem {
inner: T::build_system(),
watcher: Watcher::new(T::create_aspect()),
}
}
}
impl<T> System for EntitySystem<T>
where
T: EntityProcess,
{
type Components = T::Components;
type Services = T::Services;
fn build_system() -> Self {
EntitySystem::new()
}
fn activated(
&mut self,
entity: EntityData<T::Components>,
components: &T::Components,
services: &mut T::Services,
) {
self.watcher
.activated(entity, components, services, &mut self.inner);
}
fn reactivated(
&mut self,
entity: EntityData<T::Components>,
components: &T::Components,
services: &mut T::Services,
) {
self.watcher
.reactivated(entity, components, services, &mut self.inner);
}
fn deactivated(
&mut self,
entity: EntityData<T::Components>,
components: &T::Components,
services: &mut T::Services,
) {
self.watcher
.deactivated(entity, components, services, &mut self.inner);
}
}
impl<T> Process for EntitySystem<T>
where
T: EntityProcess,
{
fn process(&mut self, data: &mut DataHelper<T::Components, T::Services>) {
self.inner.process(self.watcher.iter(), data);
}
}