mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Commands::send_event (#14933)
# Objective sending events tends to be low-frequency so ergonomics can be prioritized over efficiency. add `Commands::send_event` to send any type of event without needing a writer in hand. i don't know how we feel about these kind of ergonomic things, i add this to all my projects and find it useful. adding `mut this_particular_event_writer: EventWriter<ThisParticularEvent>` every time i want to send something is unnecessarily cumbersome. it also simplifies the "send and receive in the same system" pattern significantly. basic example before: ```rs fn my_func( q: Query<(Entity, &State)>, mut damage_event_writer: EventWriter<DamageEvent>, mut heal_event_writer: EventWriter<HealEvent>, ) { for (entity, state) in q.iter() { if let Some(damage) = state.get_damage() { damage_event_writer.send(DamageEvent { entity, damage }); } if let Some(heal) = state.get_heal() { heal_event_writer.send(HealEvent { entity, heal }); } } } ``` basic example after: ```rs import bevy::ecs::event::SendEventEx; fn my_func( mut commands: Commands, q: Query<(Entity, &State)>, ) { for (entity, state) in q.iter() { if let Some(damage) = state.get_damage() { commands.send_event(DamageEvent { entity, damage }); } if let Some(heal) = state.get_heal() { commands.send_event(HealEvent { entity, heal }); } } } ``` send/receive in the same system before: ```rs fn send_and_receive_param_set( mut param_set: ParamSet<(EventReader<DebugEvent>, EventWriter<DebugEvent>)>, ) { // We must collect the events to resend, because we can't access the writer while we're iterating over the reader. let mut events_to_resend = Vec::new(); // This is p0, as the first parameter in the `ParamSet` is the reader. for event in param_set.p0().read() { if event.resend_from_param_set { events_to_resend.push(event.clone()); } } // This is p1, as the second parameter in the `ParamSet` is the writer. for mut event in events_to_resend { event.times_sent += 1; param_set.p1().send(event); } } ``` after: ```rs use bevy::ecs::event::SendEventEx; fn send_via_commands_and_receive( mut reader: EventReader<DebugEvent>, mut commands: Commands, ) { for event in reader.read() { if event.resend_via_commands { commands.send_event(DebugEvent { times_sent: event.times_sent + 1, ..event.clone() }); } } } ``` --------- Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
This commit is contained in:
parent
e63d7c340f
commit
45281e62d7
3 changed files with 33 additions and 1 deletions
|
@ -7,6 +7,7 @@ mod mut_iterators;
|
|||
mod mutator;
|
||||
mod reader;
|
||||
mod registry;
|
||||
mod send_event;
|
||||
mod update;
|
||||
mod writer;
|
||||
|
||||
|
@ -24,6 +25,7 @@ pub use mut_iterators::{EventMutIterator, EventMutIteratorWithId};
|
|||
pub use mutator::EventMutator;
|
||||
pub use reader::EventReader;
|
||||
pub use registry::{EventRegistry, ShouldUpdateEvents};
|
||||
pub use send_event::SendEvent;
|
||||
pub use update::{
|
||||
event_update_condition, event_update_system, signal_event_update_system, EventUpdates,
|
||||
};
|
||||
|
|
15
crates/bevy_ecs/src/event/send_event.rs
Normal file
15
crates/bevy_ecs/src/event/send_event.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use super::{Event, Events};
|
||||
use crate::world::{Command, World};
|
||||
|
||||
/// A command to send an arbitrary [`Event`], used by [`Commands::send_event`](crate::system::Commands::send_event).
|
||||
pub struct SendEvent<E: Event> {
|
||||
/// The event to send.
|
||||
pub event: E,
|
||||
}
|
||||
|
||||
impl<E: Event> Command for SendEvent<E> {
|
||||
fn apply(self, world: &mut World) {
|
||||
let mut events = world.resource_mut::<Events<E>>();
|
||||
events.send(self.event);
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ use crate::{
|
|||
bundle::{Bundle, InsertMode},
|
||||
component::{ComponentId, ComponentInfo},
|
||||
entity::{Entities, Entity},
|
||||
event::Event,
|
||||
event::{Event, SendEvent},
|
||||
observer::{Observer, TriggerEvent, TriggerTargets},
|
||||
system::{RunSystemWithInput, SystemId},
|
||||
world::{
|
||||
|
@ -788,6 +788,21 @@ impl<'w, 's> Commands<'w, 's> {
|
|||
) -> EntityCommands {
|
||||
self.spawn(Observer::new(observer))
|
||||
}
|
||||
|
||||
/// Sends an arbitrary [`Event`].
|
||||
///
|
||||
/// This is a convenience method for sending events without requiring an [`EventWriter`].
|
||||
/// ## Performance
|
||||
/// Since this is a command, exclusive world access is used, which means that it will not profit from
|
||||
/// system-level parallelism on supported platforms.
|
||||
/// If these events are performance-critical or very frequently
|
||||
/// sent, consider using a typed [`EventWriter`] instead.
|
||||
///
|
||||
/// [`EventWriter`]: crate::event::EventWriter
|
||||
pub fn send_event<E: Event>(&mut self, event: E) -> &mut Self {
|
||||
self.add(SendEvent { event });
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`Command`] which gets executed for a given [`Entity`].
|
||||
|
|
Loading…
Reference in a new issue