summaryrefslogtreecommitdiff
path: root/ecs/src/system
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/system')
-rw-r--r--ecs/src/system/initializable.rs131
-rw-r--r--ecs/src/system/observer.rs280
-rw-r--r--ecs/src/system/stateful.rs269
3 files changed, 0 insertions, 680 deletions
diff --git a/ecs/src/system/initializable.rs b/ecs/src/system/initializable.rs
deleted file mode 100644
index b6ec8e8..0000000
--- a/ecs/src/system/initializable.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-use std::marker::PhantomData;
-
-use seq_macro::seq;
-
-use crate::system::{Input, Param as SystemParam, System};
-use crate::tuple::{Reduce as TupleReduce, ReduceElement as TupleReduceElement, Tuple};
-
-/// A initializable system.
-pub trait Initializable<'world, Impl>: System<'world, Impl>
-{
- type Inputs;
-
- #[must_use]
- fn initialize(self, inputs: Self::Inputs) -> Self;
-}
-
-pub trait Param<'world, SystemT>: SystemParam<'world>
-{
- fn initialize(system: &mut SystemT, input: Self::Input);
-}
-
-pub struct ParamTupleFilter<'world, SystemT>
-{
- _pd: PhantomData<(&'world (), SystemT)>,
-}
-
-impl<'world, SystemT, ParamT, Accumulator>
- TupleReduceElement<Accumulator, ParamTupleFilter<'world, SystemT>> for ParamT
-where
- ParamT: SystemParam<
- 'world,
- Input: AppendInitializableParam<'world, Accumulator, ParamT, SystemT>,
- >,
- Accumulator: Tuple,
-{
- type Return = <ParamT::Input as AppendInitializableParam<
- 'world,
- Accumulator,
- ParamT,
- SystemT,
- >>::Return;
-}
-
-pub trait AppendInitializableParam<'world, Accumulator, ParamT, SystemT>
-{
- type Return;
-}
-
-impl<'world, InputT, ParamT, Accumulator, SystemT>
- AppendInitializableParam<'world, Accumulator, ParamT, SystemT> for InputT
-where
- InputT: Input,
- Accumulator: Tuple,
- ParamT: Param<'world, SystemT>,
-{
- type Return = Accumulator::WithElementAtEnd<ParamT>;
-}
-
-impl<ParamT, Accumulator, SystemT>
- AppendInitializableParam<'_, Accumulator, ParamT, SystemT> for ()
-where
- Accumulator: Tuple,
-{
- type Return = Accumulator;
-}
-
-pub trait ParamTuple<'world, SystemT>
-{
- type Inputs;
-
- fn initialize_all(system: &mut SystemT, inputs: Self::Inputs);
-}
-
-macro_rules! impl_initializable_param_tuple {
- ($c: tt) => {
- seq!(I in 0..$c {
- impl<'world, SystemT, #(Param~I,)*> ParamTuple<'world, SystemT>
- for (#(Param~I,)*)
- where
- #(Param~I: Param<'world, SystemT>,)*
- {
- type Inputs = (#(Param~I::Input,)*);
-
- fn initialize_all(
- system: &mut SystemT,
- inputs: Self::Inputs,
- ) {
- #(
- <Param~I as Param<'world, SystemT>>::initialize(
- system,
- inputs.I
- );
- )*
- }
- }
- });
- };
-}
-
-seq!(C in 1..16 {
- impl_initializable_param_tuple!(C);
-});
-
-impl<SystemT> ParamTuple<'_, SystemT> for ()
-{
- type Inputs = ();
-
- fn initialize_all(_system: &mut SystemT, _inputs: Self::Inputs) {}
-}
-
-/// A tuple of system parameters that may or may not be initializable.
-pub trait MaybeInitializableParamTuple<'world, SystemT>
-{
- /// A tuple of the inputs of the initializable system parameters in this tuple.
- type Inputs;
-
- fn init_initializable(system: &mut SystemT, inputs: Self::Inputs);
-}
-
-impl<'world, SystemT, Params> MaybeInitializableParamTuple<'world, SystemT> for Params
-where
- Params:
- TupleReduce<ParamTupleFilter<'world, SystemT>, Out: ParamTuple<'world, SystemT>>,
-{
- type Inputs = <Params::Out as ParamTuple<'world, SystemT>>::Inputs;
-
- fn init_initializable(system: &mut SystemT, inputs: Self::Inputs)
- {
- Params::Out::initialize_all(system, inputs);
- }
-}
diff --git a/ecs/src/system/observer.rs b/ecs/src/system/observer.rs
deleted file mode 100644
index 6893b0f..0000000
--- a/ecs/src/system/observer.rs
+++ /dev/null
@@ -1,280 +0,0 @@
-use std::any::type_name;
-use std::fmt::Debug;
-use std::marker::PhantomData;
-use std::mem::transmute;
-use std::slice::Iter as SliceIter;
-
-use ecs_macros::Component;
-use seq_macro::seq;
-
-use crate::World;
-use crate::component::Component;
-use crate::entity::Handle as EntityHandle;
-use crate::error::Error;
-use crate::event::Emitted as EmittedEvent;
-use crate::pair::Pair;
-use crate::system::{
- Metadata,
- NoCallbacks,
- Param,
- ReturnValue as SystemReturnValue,
- System,
- TypeErased as TypeErasedSystem,
-};
-use crate::uid::Uid;
-use crate::util::Array;
-
-pub trait Observed
-{
- type Events: Array<Pair<Uid, Uid>>;
-
- fn events() -> Self::Events;
-}
-
-impl<Relation, Target> Observed for Pair<Relation, Target>
-where
- Relation: Component,
- Target: Component,
-{
- type Events = [Pair<Uid, Uid>; 1];
-
- fn events() -> Self::Events
- {
- [Pair::builder()
- .relation::<Relation>()
- .target::<Target>()
- .build()]
- }
-}
-
-/// Observer system.
-pub trait Observer<'world, Impl>: System<'world, Impl>
-{
- type ObservedEvents: Array<Pair<Uid, Uid>>;
-
- fn observed_events() -> Self::ObservedEvents;
-
- fn finish_observer(self) -> (WrapperComponent, Self::Callbacks);
-}
-
-pub struct Observe<'world, ObservedT: Observed>
-{
- _pd: PhantomData<ObservedT>,
- world: &'world World,
- emitted_event: EmittedEvent<'world>,
-}
-
-impl<'world, ObservedT: Observed> Observe<'world, ObservedT>
-{
- pub fn new(world: &'world World, emitted_event: EmittedEvent<'world>) -> Self
- {
- Self {
- _pd: PhantomData,
- world,
- emitted_event,
- }
- }
-
- #[must_use]
- pub fn event(&self) -> Uid
- {
- self.emitted_event.event
- }
-}
-
-impl<ObservedT: Observed> Observe<'_, ObservedT>
-{
- #[must_use]
- pub fn iter(&self) -> ObserveIter<'_, ObservedT>
- {
- ObserveIter {
- world: self.world,
- inner: self.emitted_event.match_ids.iter(),
- _pd: PhantomData,
- }
- }
-}
-
-impl<'a, ObservedT: Observed> IntoIterator for &'a Observe<'_, ObservedT>
-{
- type IntoIter = ObserveIter<'a, ObservedT>;
- type Item = <Self::IntoIter as Iterator>::Item;
-
- fn into_iter(self) -> Self::IntoIter
- {
- self.iter()
- }
-}
-
-pub struct ObserveIter<'observe, ObservedT: Observed>
-{
- world: &'observe World,
- inner: SliceIter<'observe, Uid>,
- _pd: PhantomData<ObservedT>,
-}
-
-impl<'observe, ObservedT: Observed> Iterator for ObserveIter<'observe, ObservedT>
-{
- type Item = EventMatch<'observe, ObservedT>;
-
- fn next(&mut self) -> Option<Self::Item>
- {
- let match_id = *self.inner.next()?;
-
- Some(EventMatch {
- world: self.world,
- id: match_id,
- _pd: PhantomData,
- })
- }
-}
-
-/// A event match.
-#[derive(Debug)]
-pub struct EventMatch<'world, ObservedT: Observed>
-{
- world: &'world World,
- id: Uid,
- _pd: PhantomData<ObservedT>,
-}
-
-impl<'world, ObservedT: Observed> EventMatch<'world, ObservedT>
-{
- #[must_use]
- pub fn entity_id(&self) -> Uid
- {
- self.id
- }
-
- /// Attempts to get the entity with the id of this match.
- #[must_use]
- pub fn try_get_entity(&self) -> Option<EntityHandle<'world>>
- {
- self.world.get_entity(self.id)
- }
-}
-
-macro_rules! impl_observer {
- ($c: tt) => {
- seq!(I in 0..$c {
- impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> System<
- 'world,
- fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret
- > for Func
- where
- ObservedT: Observed,
- Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static,
- Ret: SystemReturnValue,
- #(TParam~I: Param<'world, Input = ()>,)*
- {
- type Callbacks = NoCallbacks;
-
- fn finish(self) -> (TypeErasedSystem, NoCallbacks)
- {
- const {
- panic!("Observers cannot be used as regular systems");
- }
- }
- }
-
- impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> Observer<
- 'world,
- fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret
- > for Func
- where
- ObservedT: Observed,
- Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static,
- Ret: SystemReturnValue,
- #(TParam~I: Param<'world, Input = ()>,)*
- {
- type ObservedEvents = ObservedT::Events;
-
- fn observed_events() -> Self::ObservedEvents
- {
- ObservedT::events()
- }
-
- fn finish_observer(self) -> (WrapperComponent, NoCallbacks)
- {
- #[allow(unused)]
-
- let wrapper_comp = WrapperComponent::new(
- move |world, metadata, emitted_event| {
- // SAFETY: The caller of TypeErased::run ensures the lifetime
- // is correct
- let world = unsafe { &*std::ptr::from_ref(world) };
-
- // SAFETY: The caller of TypeErased::run ensures the lifetime
- // is correct
- let emitted_event = unsafe {
- transmute::<EmittedEvent<'_>, EmittedEvent<'_>>(
- emitted_event
- )
- };
-
- self(Observe::new(world, emitted_event), #({
- TParam~I::new(world, &metadata)
- },)*).into_result()
- },
- type_name::<Func>()
- );
-
- (wrapper_comp, NoCallbacks)
- }
- }
- });
- };
-}
-
-seq!(C in 0..16 {
- impl_observer!(C);
-});
-
-#[derive(Component)]
-pub struct WrapperComponent
-{
- run: Box<RunFn>,
- name: &'static str,
-}
-
-impl WrapperComponent
-{
- pub fn new(
- run: impl Fn(&World, Metadata, EmittedEvent<'_>) -> Result<(), Error> + 'static,
- name: &'static str,
- ) -> Self
- {
- Self { run: Box::new(run), name }
- }
-
- /// Runs the observer system.
- ///
- /// # Safety
- /// `world` must live at least as long as the [`World`] the system belongs to.
- pub unsafe fn run(
- &self,
- world: &World,
- metadata: Metadata,
- emitted_event: EmittedEvent<'_>,
- ) -> Result<(), Error>
- {
- (self.run)(world, metadata, emitted_event)
- }
-
- pub fn name(&self) -> &'static str
- {
- self.name
- }
-}
-
-impl Debug for WrapperComponent
-{
- fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
- {
- formatter
- .debug_struct("WrapperComponent")
- .finish_non_exhaustive()
- }
-}
-
-type RunFn = dyn Fn(&World, Metadata, EmittedEvent<'_>) -> Result<(), Error>;
diff --git a/ecs/src/system/stateful.rs b/ecs/src/system/stateful.rs
deleted file mode 100644
index 3e0076a..0000000
--- a/ecs/src/system/stateful.rs
+++ /dev/null
@@ -1,269 +0,0 @@
-use std::any::type_name;
-use std::mem::transmute;
-
-use seq_macro::seq;
-
-use crate::World;
-use crate::component::Parts as ComponentParts;
-use crate::component::local::SystemWithLocalComponents;
-use crate::event::Emitted as EmittedEvent;
-use crate::system::initializable::{Initializable, MaybeInitializableParamTuple};
-use crate::system::observer::{
- Observe,
- Observed,
- Observer,
- WrapperComponent as ObserverWrapperComponent,
-};
-use crate::system::{
- Into as IntoSystem,
- Metadata,
- Param,
- ReturnValue,
- System,
- TypeErased,
-};
-
-/// A stateful system.
-pub struct Stateful<Func>
-{
- func: Func,
- local_components: Vec<ComponentParts>,
-}
-
-macro_rules! impl_system {
- ($c: tt) => {
- seq!(I in 0..$c {
- impl<'world, Func, Ret, #(TParam~I,)*>
- System<'world, fn(#(TParam~I,)*) -> Ret> for Stateful<Func>
- where
- Func: Fn(#(TParam~I,)*) -> Ret + 'static,
- Ret: ReturnValue,
- #(TParam~I: Param<'world, Input: 'static>,)*
- {
- type Callbacks = Callbacks;
-
- fn finish(self) -> (TypeErased, Self::Callbacks)
- {
- let Self { func, local_components } = self;
-
- let callbacks = Callbacks { local_components };
-
- let type_erased = TypeErased {
- run: Box::new(move |world, metadata| {
- // SAFETY: The caller of TypeErased::run ensures the lifetime
- // is correct
- let world = unsafe { &*std::ptr::from_ref(world) };
-
- func(#({
- TParam~I::new(&world, &metadata)
- },)*);
-
- Ok(())
- }),
- name: type_name::<Func>()
- };
-
-
- (type_erased, callbacks)
- }
- }
-
- impl<'world, Func, Ret, #(TParam~I,)*>
- Initializable<'world, fn(#(TParam~I,)*) -> Ret> for Stateful<Func>
- where
- Func: Fn(#(TParam~I,)*) -> Ret + 'static,
- Ret: ReturnValue,
- #(TParam~I: Param<'world, Input: 'static>,)*
- (#(TParam~I,)*): MaybeInitializableParamTuple<'world, Self>
- {
- type Inputs = <
- (#(TParam~I,)*) as MaybeInitializableParamTuple<'world, Self>
- >::Inputs;
-
- fn initialize(mut self, inputs: Self::Inputs) -> Self
- {
- init_initializable_params::<_, (#(TParam~I,)*)>(&mut self, inputs);
-
- self
- }
- }
-
- impl<'world, Func, Ret, #(TParam~I,)*>
- IntoSystem<'world, fn(#(TParam~I,)*) -> Ret> for Func
- where
- Func: Fn(#(TParam~I,)*) -> Ret + 'static,
- Ret: ReturnValue,
- #(TParam~I: Param<'world>,)*
- {
- type System = Stateful<Func>;
-
- fn into_system(self) -> Self::System
- {
- Self::System {
- func: self,
- local_components: Vec::new(), // TODO: Use Vec::with_capacity
- }
- }
- }
- });
- };
-}
-
-seq!(C in 1..16 {
- impl_system!(C);
-});
-
-impl<Func> SystemWithLocalComponents for Stateful<Func>
-{
- fn add_local_component(&mut self, component_parts: ComponentParts)
- {
- self.local_components.push(component_parts);
- }
-}
-
-#[derive(Debug)]
-pub struct Callbacks
-{
- local_components: Vec<ComponentParts>,
-}
-
-impl crate::system::Callbacks for Callbacks
-{
- fn on_created(&mut self, world: &mut World, metadata: Metadata)
- {
- for local_comp_parts in self.local_components.drain(..) {
- world.add_component(metadata.ent_id, local_comp_parts);
- }
- }
-}
-
-fn init_initializable_params<'world, SystemT, Params>(
- system: &mut SystemT,
- inputs: Params::Inputs,
-) where
- Params: MaybeInitializableParamTuple<'world, SystemT>,
-{
- Params::init_initializable(system, inputs);
-}
-
-macro_rules! impl_observer {
- ($c: tt) => {
- seq!(I in 0..$c {
- impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> System<
- 'world,
- fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret
- > for Stateful<Func>
- where
- ObservedT: Observed,
- Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static,
- Ret: ReturnValue,
- #(TParam~I: Param<'world>,)*
- {
- type Callbacks = Callbacks;
-
- fn finish(self) -> (TypeErased, Callbacks)
- {
- unimplemented!();
- }
- }
-
- impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> Initializable<
- 'world,
- fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret
- > for Stateful<Func>
- where
- ObservedT: Observed,
- Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static,
- Ret: ReturnValue,
- #(TParam~I: Param<'world>,)*
- (#(TParam~I,)*): MaybeInitializableParamTuple<'world, Self>
- {
- type Inputs = <
- (#(TParam~I,)*) as MaybeInitializableParamTuple<'world, Self>
- >::Inputs;
-
- fn initialize(mut self, inputs: Self::Inputs) -> Self
- {
- init_initializable_params::<_, (#(TParam~I,)*)>(&mut self, inputs);
-
- self
- }
- }
-
- impl<'world, ObservedT, Func, Ret, #(TParam~I,)*> Observer<
- 'world,
- fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret
- > for Stateful<Func>
- where
- ObservedT: Observed,
- Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static,
- Ret: ReturnValue,
- #(TParam~I: Param<'world>,)*
- {
- type ObservedEvents = ObservedT::Events;
-
- fn observed_events() -> Self::ObservedEvents
- {
- ObservedT::events()
- }
-
- fn finish_observer(self) -> (ObserverWrapperComponent, Callbacks)
- {
- #![allow(unused)]
-
- let Self { func, local_components } = self;
-
- let callbacks = Callbacks { local_components };
-
- let wrapper_comp = ObserverWrapperComponent::new(
- move |world, metadata, emitted_event| {
- // SAFETY: The caller of TypeErased::run ensures the lifetime
- // is correct
- let world = unsafe { &*std::ptr::from_ref(world) };
-
- // SAFETY: The caller of TypeErased::run ensures the lifetime
- // is correct
- let emitted_event = unsafe {
- transmute::<EmittedEvent<'_>, EmittedEvent<'_>>(
- emitted_event
- )
- };
-
- func(Observe::new(world, emitted_event), #({
- TParam~I::new(world, &metadata)
- },)*).into_result()
- },
- type_name::<Func>()
- );
-
- (wrapper_comp, callbacks)
- }
- }
-
- impl<'world, Func, Ret, ObservedT, #(TParam~I,)*> IntoSystem<
- 'world,
- fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret
- > for Func
- where
- ObservedT: Observed,
- Func: Fn(Observe<'world, ObservedT>, #(TParam~I,)*) -> Ret + 'static,
- Ret: ReturnValue,
- #(TParam~I: Param<'world>,)*
- {
- type System = Stateful<Func>;
-
- fn into_system(self) -> Stateful<Func>
- {
- Stateful {
- func: self,
- local_components: Vec::new(), // TODO: Use Vec::with_capacity
- }
- }
- }
- });
- };
-}
-
-seq!(C in 0..16 {
- impl_observer!(C);
-});