diff --git a/crates/bevy_ecs/src/observer/mod.rs b/crates/bevy_ecs/src/observer/mod.rs index 600384d478438..8e4faebf761b8 100644 --- a/crates/bevy_ecs/src/observer/mod.rs +++ b/crates/bevy_ecs/src/observer/mod.rs @@ -7,9 +7,14 @@ mod trigger_event; pub use runner::*; pub use trigger_event::*; -use crate::observer::entity_observer::ObservedBy; -use crate::{archetype::ArchetypeFlags, system::IntoObserverSystem, world::*}; -use crate::{component::ComponentId, prelude::*, world::DeferredWorld}; +use crate::{ + archetype::ArchetypeFlags, + component::ComponentId, + observer::entity_observer::ObservedBy, + prelude::*, + system::{IntoObserverSystem, ObserverSystem}, + world::DeferredWorld, +}; use bevy_ptr::Ptr; use bevy_utils::{EntityHashMap, HashMap}; use std::marker::PhantomData; @@ -427,6 +432,65 @@ impl World { } } +/// Returns an [`Observer`] that watches for an input event, maps it to a new event type, and triggers +/// that event. +/// +/// # Examples +/// +/// ``` +/// # use bevy_ecs::prelude::*; +/// # use bevy_ecs::observer::trigger_map; +/// # let mut world = World::new(); +/// +/// #[derive(Event, Clone, Debug)] +/// struct Foo(usize); +/// +/// #[derive(Event, Clone, Debug)] +/// struct Bar(bool); +/// +/// #[derive(Event, Debug)] +/// enum Combined { +/// Foo(Foo), +/// Bar(Bar), +/// } +/// +/// world.observe(trigger_map(Combined::Foo)); +/// world.observe(trigger_map(Combined::Bar)); +/// world.observe(|trigger: Trigger| { +/// println!("Combined Event: {:?}", trigger.event()); +/// }); +/// ``` +/// +/// ``` +/// # use bevy_ecs::prelude::*; +/// # use bevy_ecs::observer::trigger_map; +/// # let mut world = World::new(); +/// +/// #[derive(Event, Clone, Debug)] +/// struct Foo(usize); +/// +/// #[derive(Event, Clone, Debug)] +/// struct Bar(bool); +/// +/// // If you don't care about capturing the original event context, +/// // you can just use a unit struct. +/// #[derive(Event, Debug)] +/// struct Combined; +/// +/// world.observe(trigger_map(|event: Foo| Combined)); +/// world.observe(trigger_map(|event: Bar| Combined)); +/// world.observe(|trigger: Trigger| { +/// println!("Combined Event"); +/// }); +/// ``` +pub fn trigger_map U + Send + Sync + 'static>( + map: F, +) -> impl ObserverSystem { + IntoObserverSystem::into_system(move |trigger: Trigger, mut commands: Commands| { + commands.trigger(map(trigger.event().clone())); + }) +} + #[cfg(test)] mod tests { use bevy_ptr::OwningPtr;