summaryrefslogtreecommitdiff
path: root/ecs/src/system/observer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/system/observer.rs')
-rw-r--r--ecs/src/system/observer.rs280
1 files changed, 0 insertions, 280 deletions
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>;