diff --git a/mvp-effects.md b/mvp-effects.md index e148029..13bb610 100644 --- a/mvp-effects.md +++ b/mvp-effects.md @@ -9,7 +9,7 @@ *Need to research.. Could lead to confusing experience about which system the parameter is local to.* # Event Effects -- [ ] `EventSend` +- [x] `EventSend` # Query Effects - [ ] `QueryPut` diff --git a/src/effects/event.rs b/src/effects/event.rs new file mode 100644 index 0000000..d2039f1 --- /dev/null +++ b/src/effects/event.rs @@ -0,0 +1,55 @@ +use bevy::prelude::*; + +use crate::Effect; + +/// [`Effect`] that sends an event `E` to the corresponding `EventWriter`. +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] +pub struct EventSend(pub E) +where + E: Event; + +impl Effect for EventSend +where + E: Event, +{ + type MutParam = EventWriter<'static, E>; + + fn affect(self, param: &mut ::Item<'_, '_>) { + param.send(self.0); + } +} + +#[cfg(test)] +mod tests { + use proptest::prelude::*; + use proptest_derive::Arbitrary; + + use super::*; + use crate::prelude::affect; + + #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Event, Arbitrary)] + struct NumberEvent(u128); + + proptest! { + #[test] + fn event_send_produces_events(events in prop::collection::vec(any::(), 1..10)) { + let mut app = App::new(); + + let mut events_clone = events.clone(); + app.add_event::() + .add_systems(Update, (move || EventSend(events_clone.remove(0))).pipe(affect)); + + for expected in events { + app.update(); + + let events_in_update = app.world().resource::>().iter_current_update_events().collect::>(); + + prop_assert_eq!(events_in_update.len(), 1); + + let event_sent = events_in_update.first().unwrap(); + + prop_assert_eq!(event_sent, &&expected); + } + } + } +} diff --git a/src/effects/mod.rs b/src/effects/mod.rs index 5e7fd3e..5ba210e 100644 --- a/src/effects/mod.rs +++ b/src/effects/mod.rs @@ -4,3 +4,6 @@ mod resource; pub use resource::{ResPut, ResWith}; + +mod event; +pub use event::EventSend; diff --git a/src/prelude.rs b/src/prelude.rs index 07a4f61..04d0923 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,5 +1,5 @@ //! `use bevy_pipe_affect::prelude::*;` to import common items. -pub use crate::effects::{ResPut, ResWith}; +pub use crate::effects::{EventSend, ResPut, ResWith}; pub use crate::system_combinators::{affect, and_compose}; pub use crate::{Effect, EffectOut};