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