bevy_ecs/event/writer.rs
1use crate as bevy_ecs;
2use bevy_ecs::{
3 event::{Event, EventId, Events, SendBatchIds},
4 system::{ResMut, SystemParam},
5};
6
7/// Sends events of type `T`.
8///
9/// # Usage
10///
11/// `EventWriter`s are usually declared as a [`SystemParam`].
12/// ```
13/// # use bevy_ecs::prelude::*;
14///
15/// #[derive(Event)]
16/// pub struct MyEvent; // Custom event type.
17/// fn my_system(mut writer: EventWriter<MyEvent>) {
18/// writer.send(MyEvent);
19/// }
20///
21/// # bevy_ecs::system::assert_is_system(my_system);
22/// ```
23/// # Observers
24///
25/// "Buffered" Events, such as those sent directly in [`Events`] or sent using [`EventWriter`], do _not_ automatically
26/// trigger any [`Observer`]s watching for that event, as each [`Event`] has different requirements regarding _if_ it will
27/// be triggered, and if so, _when_ it will be triggered in the schedule.
28///
29/// # Concurrency
30///
31/// `EventWriter` param has [`ResMut<Events<T>>`](Events) inside. So two systems declaring `EventWriter<T>` params
32/// for the same event type won't be executed concurrently.
33///
34/// # Untyped events
35///
36/// `EventWriter` can only send events of one specific type, which must be known at compile-time.
37/// This is not a problem most of the time, but you may find a situation where you cannot know
38/// ahead of time every kind of event you'll need to send. In this case, you can use the "type-erased event" pattern.
39///
40/// ```
41/// # use bevy_ecs::{prelude::*, event::Events};
42/// # #[derive(Event)]
43/// # pub struct MyEvent;
44/// fn send_untyped(mut commands: Commands) {
45/// // Send an event of a specific type without having to declare that
46/// // type as a SystemParam.
47/// //
48/// // Effectively, we're just moving the type parameter from the /type/ to the /method/,
49/// // which allows one to do all kinds of clever things with type erasure, such as sending
50/// // custom events to unknown 3rd party plugins (modding API).
51/// //
52/// // NOTE: the event won't actually be sent until commands get applied during
53/// // apply_deferred.
54/// commands.queue(|w: &mut World| {
55/// w.send_event(MyEvent);
56/// });
57/// }
58/// ```
59/// Note that this is considered *non-idiomatic*, and should only be used when `EventWriter` will not work.
60///
61/// [`Observer`]: crate::observer::Observer
62#[derive(SystemParam)]
63pub struct EventWriter<'w, E: Event> {
64 events: ResMut<'w, Events<E>>,
65}
66
67impl<'w, E: Event> EventWriter<'w, E> {
68 /// Sends an `event`, which can later be read by [`EventReader`](super::EventReader)s.
69 /// This method returns the [ID](`EventId`) of the sent `event`.
70 ///
71 /// See [`Events`] for details.
72 pub fn send(&mut self, event: E) -> EventId<E> {
73 self.events.send(event)
74 }
75
76 /// Sends a list of `events` all at once, which can later be read by [`EventReader`](super::EventReader)s.
77 /// This is more efficient than sending each event individually.
78 /// This method returns the [IDs](`EventId`) of the sent `events`.
79 ///
80 /// See [`Events`] for details.
81 pub fn send_batch(&mut self, events: impl IntoIterator<Item = E>) -> SendBatchIds<E> {
82 self.events.send_batch(events)
83 }
84
85 /// Sends the default value of the event. Useful when the event is an empty struct.
86 /// This method returns the [ID](`EventId`) of the sent `event`.
87 ///
88 /// See [`Events`] for details.
89 pub fn send_default(&mut self) -> EventId<E>
90 where
91 E: Default,
92 {
93 self.events.send_default()
94 }
95}