Skip to content

Commit ae0229f

Browse files
committed
add a derive macro for Event
1 parent 1849d5f commit ae0229f

File tree

17 files changed

+79
-39
lines changed

17 files changed

+79
-39
lines changed

crates/bevy_app/src/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,5 +1058,5 @@ fn run_once(mut app: App) {
10581058
/// You can also use this event to detect that an exit was requested. In order to receive it, systems
10591059
/// subscribing to this event should run after it was emitted and before the schedule of the same
10601060
/// frame is over.
1061-
#[derive(Debug, Clone, Default)]
1061+
#[derive(Debug, Clone, Default, Event)]
10621062
pub struct AppExit;

crates/bevy_asset/src/assets.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
};
55
use bevy_app::App;
66
use bevy_ecs::{
7-
event::{EventWriter, Events},
7+
event::{Event, EventWriter, Events},
88
system::ResMut,
99
world::FromWorld,
1010
};
@@ -16,6 +16,7 @@ use std::fmt::Debug;
1616
///
1717
/// Events sent via the [`Assets`] struct will always be sent with a _Weak_ handle, because the
1818
/// asset may not exist by the time the event is handled.
19+
#[derive(Event)]
1920
pub enum AssetEvent<T: Asset> {
2021
#[allow(missing_docs)]
2122
Created { handle: Handle<T> },

crates/bevy_ecs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ Events offer a communication channel between one or more systems. Events can be
287287
```rust
288288
use bevy_ecs::prelude::*;
289289

290+
#[derive(Event)]
290291
struct MyEvent {
291292
message: String,
292293
}

crates/bevy_ecs/examples/events.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ fn main() {
3535
}
3636

3737
// This is our event that we will send and receive in systems
38+
#[derive(Event)]
3839
struct MyEvent {
3940
pub message: String,
4041
pub random_value: f32,

crates/bevy_ecs/macros/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,25 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream {
173173
})
174174
}
175175

176+
#[proc_macro_derive(Event, attributes(event))]
177+
pub fn derive_event(input: TokenStream) -> TokenStream {
178+
let path = bevy_ecs_path();
179+
180+
let input = parse_macro_input!(input as DeriveInput);
181+
let ident = input.ident;
182+
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
183+
let where_clause = where_clause.cloned().unwrap_or_else(|| syn::WhereClause {
184+
where_token: Default::default(),
185+
predicates: Default::default(),
186+
});
187+
188+
quote! {
189+
impl #impl_generics #path::event::Read for #ident #ty_generics #where_clause { }
190+
impl #impl_generics #path::event::Write for #ident #ty_generics #where_clause { }
191+
}
192+
.into()
193+
}
194+
176195
fn get_idents(fmt_string: fn(usize) -> String, count: usize) -> Vec<Ident> {
177196
(0..count)
178197
.map(|i| Ident::new(&fmt_string(i), Span::call_site()))

crates/bevy_ecs/src/event.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use std::{
1717
pub trait Event: Send + Sync + 'static {}
1818
impl<T> Event for T where T: Send + Sync + 'static {}
1919

20+
pub use bevy_ecs_macros::Event;
21+
2022
/// An `EventId` uniquely identifies an event.
2123
///
2224
/// An `EventId` can among other things be used to trace the flow of an event from the point it was
@@ -82,8 +84,9 @@ struct EventInstance<E: Event> {
8284
///
8385
/// # Example
8486
/// ```
85-
/// use bevy_ecs::event::Events;
87+
/// use bevy_ecs::prelude::*;
8688
///
89+
/// #[derive(Event)]
8790
/// struct MyEvent {
8891
/// value: usize
8992
/// }
@@ -239,6 +242,7 @@ where
239242
/// ```
240243
/// # use bevy_ecs::prelude::*;
241244
/// #
245+
/// #[derive(Event)]
242246
/// struct CollisionEvent;
243247
///
244248
/// fn play_collision_sound(events: EventReader<CollisionEvent>) {
@@ -281,7 +285,9 @@ pub trait Write<Vis = ()> {}
281285
/// ```
282286
/// # use bevy_ecs::prelude::*;
283287
///
288+
/// #[derive(Event)]
284289
/// pub struct MyEvent; // Custom event type.
290+
///
285291
/// fn my_system(mut writer: EventWriter<MyEvent>) {
286292
/// writer.send(MyEvent);
287293
/// }
@@ -344,7 +350,7 @@ pub trait Write<Vis = ()> {}
344350
///
345351
/// ```
346352
/// # use bevy_ecs::{prelude::*, event::Events};
347-
///
353+
/// # #[derive(Event)]
348354
/// # pub struct MyEvent;
349355
/// fn send_untyped(mut commands: Commands) {
350356
/// // Send an event of a specific type without having to declare that
@@ -702,7 +708,7 @@ mod tests {
702708

703709
use super::*;
704710

705-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
711+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Event)]
706712
struct TestEvent {
707713
i: usize,
708714
}
@@ -798,14 +804,14 @@ mod tests {
798804
);
799805
}
800806

801-
fn get_events<E: Event + Clone>(
807+
fn get_events<E: Event + Clone + Read>(
802808
events: &Events<E>,
803809
reader: &mut ManualEventReader<E>,
804810
) -> Vec<E> {
805811
reader.iter(events).cloned().collect::<Vec<E>>()
806812
}
807813

808-
#[derive(PartialEq, Eq, Debug)]
814+
#[derive(Event, PartialEq, Eq, Debug)]
809815
struct E(usize);
810816

811817
fn events_clear_and_read_impl(clear_func: impl FnOnce(&mut Events<E>)) {
@@ -953,7 +959,7 @@ mod tests {
953959
assert!(is_empty, "EventReader should be empty");
954960
}
955961

956-
#[derive(Clone, PartialEq, Debug, Default)]
962+
#[derive(Clone, PartialEq, Debug, Default, Event)]
957963
struct EmptyTestEvent;
958964

959965
#[test]
@@ -970,7 +976,7 @@ mod tests {
970976

971977
#[test]
972978
fn ensure_reader_readonly() {
973-
fn read_for<E: Event>() {
979+
fn read_for<E: Event + Read>() {
974980
let mut world = World::new();
975981
world.init_resource::<Events<E>>();
976982
let mut state = SystemState::<EventReader<E>>::new(&mut world);

crates/bevy_ecs/src/system/function_system.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl SystemMeta {
8181
/// use bevy_ecs::{system::SystemState};
8282
/// use bevy_ecs::event::Events;
8383
///
84+
/// #[derive(Event)]
8485
/// struct MyEvent;
8586
/// struct MyResource(u32);
8687
///
@@ -109,6 +110,7 @@ impl SystemMeta {
109110
/// use bevy_ecs::{system::SystemState};
110111
/// use bevy_ecs::event::Events;
111112
///
113+
/// #[derive(Event)]
112114
/// struct MyEvent;
113115
/// struct CachedSystemState<'w, 's>{
114116
/// event_state: SystemState<EventReader<'w, 's, MyEvent>>

crates/bevy_hierarchy/src/events.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use bevy_ecs::prelude::Entity;
1+
use bevy_ecs::{event::Event, prelude::Entity};
22

33
/// A [`Event`] that is fired whenever there is a change in the world's
44
/// hierarchy.
55
///
66
/// [`Event`]: bevy_ecs::event::Event
7-
#[derive(Debug, Clone)]
7+
#[derive(Debug, Clone, Event)]
88
pub enum HierarchyEvent {
99
/// Fired whenever an [`Entity`] is added as a child to a new parent.
1010
ChildAdded {

crates/bevy_input/src/gamepad.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{Axis, Input};
2-
use bevy_ecs::event::{EventReader, EventWriter};
2+
use bevy_ecs::event::{Event, EventReader, EventWriter};
33
use bevy_ecs::system::{Res, ResMut};
44
use bevy_utils::{tracing::info, HashMap, HashSet};
55

@@ -54,7 +54,7 @@ pub enum GamepadEventType {
5454
AxisChanged(GamepadAxisType, f32),
5555
}
5656

57-
#[derive(Debug, Clone, PartialEq)]
57+
#[derive(Debug, Clone, PartialEq, Event)]
5858
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
5959
pub struct GamepadEvent {
6060
pub gamepad: Gamepad,
@@ -70,7 +70,7 @@ impl GamepadEvent {
7070
}
7171
}
7272

73-
#[derive(Debug, Clone, PartialEq)]
73+
#[derive(Debug, Clone, PartialEq, Event)]
7474
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
7575
pub struct GamepadEventRaw {
7676
pub gamepad: Gamepad,

crates/bevy_input/src/keyboard.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::{ButtonState, Input};
2-
use bevy_ecs::{event::EventReader, system::ResMut};
2+
use bevy_ecs::{
3+
event::{Event, EventReader},
4+
system::ResMut,
5+
};
36

47
/// A keyboard input event.
58
///
@@ -10,7 +13,7 @@ use bevy_ecs::{event::EventReader, system::ResMut};
1013
///
1114
/// The event is consumed inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system)
1215
/// to update the [`Input<KeyCode>`](crate::Input<KeyCode>) resource.
13-
#[derive(Debug, Clone)]
16+
#[derive(Debug, Clone, Event)]
1417
pub struct KeyboardInput {
1518
/// The scan code of the key.
1619
pub scan_code: u32,

crates/bevy_input/src/mouse.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::{ButtonState, Input};
2-
use bevy_ecs::{event::EventReader, system::ResMut};
2+
use bevy_ecs::{
3+
event::{Event, EventReader},
4+
system::ResMut,
5+
};
36
use bevy_math::Vec2;
47

58
/// A mouse button input event.
@@ -10,7 +13,7 @@ use bevy_math::Vec2;
1013
///
1114
/// The event is read inside of the [`mouse_button_input_system`](crate::mouse::mouse_button_input_system)
1215
/// to update the [`Input<MouseButton>`](crate::Input<MouseButton>) resource.
13-
#[derive(Debug, Clone)]
16+
#[derive(Debug, Clone, Event)]
1417
pub struct MouseButtonInput {
1518
/// The mouse button assigned to the event.
1619
pub button: MouseButton,
@@ -50,7 +53,7 @@ pub enum MouseButton {
5053
/// However, the event data does not make it possible to distinguish which device it is referring to.
5154
///
5255
/// [`DeviceEvent::MouseMotion`]: https://docs.rs/winit/latest/winit/event/enum.DeviceEvent.html#variant.MouseMotion
53-
#[derive(Debug, Clone)]
56+
#[derive(Debug, Clone, Event)]
5457
pub struct MouseMotion {
5558
/// The change in the position of the pointing device since the last event was sent.
5659
pub delta: Vec2,
@@ -79,7 +82,7 @@ pub enum MouseScrollUnit {
7982
/// A mouse wheel event.
8083
///
8184
/// This event is the translated version of the `WindowEvent::MouseWheel` from the `winit` crate.
82-
#[derive(Debug, Clone)]
85+
#[derive(Debug, Clone, Event)]
8386
pub struct MouseWheel {
8487
/// The mouse scroll unit.
8588
pub unit: MouseScrollUnit,

crates/bevy_input/src/touch.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bevy_ecs::event::EventReader;
1+
use bevy_ecs::event::{Event, EventReader};
22
use bevy_ecs::system::ResMut;
33
use bevy_math::Vec2;
44
use bevy_utils::HashMap;
@@ -26,7 +26,7 @@ use bevy_utils::HashMap;
2626
///
2727
/// This event is the translated version of the `WindowEvent::Touch` from the `winit` crate.
2828
/// It is available to the end user and can be used for game logic.
29-
#[derive(Debug, Clone, Copy, PartialEq)]
29+
#[derive(Debug, Clone, Copy, PartialEq, Event)]
3030
pub struct TouchInput {
3131
/// The phase of the touch input.
3232
pub phase: TouchPhase,

0 commit comments

Comments
 (0)