Skip to content

Commit 3180b1c

Browse files
committed
add a derive macro for Event
1 parent e9879a1 commit 3180b1c

File tree

12 files changed

+67
-36
lines changed

12 files changed

+67
-36
lines changed

crates/bevy_app/src/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,5 +1011,5 @@ fn run_once(mut app: App) {
10111011
/// You can also use this event to detect that an exit was requested. In order to receive it, systems
10121012
/// subscribing to this event should run after it was emitted and before the schedule of the same
10131013
/// frame is over.
1014-
#[derive(Debug, Clone, Default)]
1014+
#[derive(Debug, Clone, Default, Event)]
10151015
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/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: 7 additions & 5 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
@@ -702,7 +704,7 @@ mod tests {
702704

703705
use super::*;
704706

705-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
707+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Event)]
706708
struct TestEvent {
707709
i: usize,
708710
}
@@ -798,14 +800,14 @@ mod tests {
798800
);
799801
}
800802

801-
fn get_events<E: Event + Clone>(
803+
fn get_events<E: Event + Clone + Read>(
802804
events: &Events<E>,
803805
reader: &mut ManualEventReader<E>,
804806
) -> Vec<E> {
805807
reader.iter(events).cloned().collect::<Vec<E>>()
806808
}
807809

808-
#[derive(PartialEq, Eq, Debug)]
810+
#[derive(Event, PartialEq, Eq, Debug)]
809811
struct E(usize);
810812

811813
fn events_clear_and_read_impl(clear_func: impl FnOnce(&mut Events<E>)) {
@@ -953,7 +955,7 @@ mod tests {
953955
assert!(is_empty, "EventReader should be empty");
954956
}
955957

956-
#[derive(Clone, PartialEq, Debug, Default)]
958+
#[derive(Clone, PartialEq, Debug, Default, Event)]
957959
struct EmptyTestEvent;
958960

959961
#[test]
@@ -970,7 +972,7 @@ mod tests {
970972

971973
#[test]
972974
fn ensure_reader_readonly() {
973-
fn read_for<E: Event>() {
975+
fn read_for<E: Event + Read>() {
974976
let mut world = World::new();
975977
world.init_resource::<Events<E>>();
976978
let mut state = SystemState::<EventReader<E>>::new(&mut world);

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,

crates/bevy_window/src/event.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use std::path::PathBuf;
22

33
use super::{WindowDescriptor, WindowId};
4+
use bevy_ecs::event::Event;
45
use bevy_math::{IVec2, Vec2};
56

67
/// A window event that is sent whenever a window's logical size has changed.
7-
#[derive(Debug, Clone)]
8+
#[derive(Debug, Clone, Event)]
89
pub struct WindowResized {
910
pub id: WindowId,
1011
/// The new logical width of the window.
@@ -14,22 +15,22 @@ pub struct WindowResized {
1415
}
1516

1617
/// An event that indicates that a new window should be created.
17-
#[derive(Debug, Clone)]
18+
#[derive(Debug, Clone, Event)]
1819
pub struct CreateWindow {
1920
pub id: WindowId,
2021
pub descriptor: WindowDescriptor,
2122
}
2223

2324
/// An event that indicates the window should redraw, even if its control flow is set to `Wait` and
2425
/// there have been no window events.
25-
#[derive(Debug, Clone)]
26+
#[derive(Debug, Clone, Event)]
2627
pub struct RequestRedraw;
2728

2829
/// An event that is sent whenever a new window is created.
2930
///
3031
/// To create a new window, send a [`CreateWindow`] event - this
3132
/// event will be sent in the handler for that event.
32-
#[derive(Debug, Clone)]
33+
#[derive(Debug, Clone, Event)]
3334
pub struct WindowCreated {
3435
pub id: WindowId,
3536
}
@@ -45,7 +46,7 @@ pub struct WindowCreated {
4546
/// [`WindowPlugin`]: crate::WindowPlugin
4647
/// [`Window`]: crate::Window
4748
/// [closing]: crate::Window::close
48-
#[derive(Debug, Clone)]
49+
#[derive(Debug, Clone, Event)]
4950
pub struct WindowCloseRequested {
5051
pub id: WindowId,
5152
}
@@ -54,7 +55,7 @@ pub struct WindowCloseRequested {
5455
/// handler for [`Window::close`].
5556
///
5657
/// [`Window::close`]: crate::Window::close
57-
#[derive(Debug, Clone)]
58+
#[derive(Debug, Clone, Event)]
5859
pub struct WindowClosed {
5960
pub id: WindowId,
6061
}
@@ -67,7 +68,7 @@ pub struct WindowClosed {
6768
///
6869
/// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved
6970
/// [`MouseMotion`]: bevy_input::mouse::MouseMotion
70-
#[derive(Debug, Clone)]
71+
#[derive(Debug, Clone, Event)]
7172
pub struct CursorMoved {
7273
/// The identifier of the window the cursor has moved on.
7374
pub id: WindowId,
@@ -76,45 +77,45 @@ pub struct CursorMoved {
7677
pub position: Vec2,
7778
}
7879
/// An event that is sent whenever the user's cursor enters a window.
79-
#[derive(Debug, Clone)]
80+
#[derive(Debug, Clone, Event)]
8081
pub struct CursorEntered {
8182
pub id: WindowId,
8283
}
8384
/// An event that is sent whenever the user's cursor leaves a window.
84-
#[derive(Debug, Clone)]
85+
#[derive(Debug, Clone, Event)]
8586
pub struct CursorLeft {
8687
pub id: WindowId,
8788
}
8889

8990
/// An event that is sent whenever a window receives a character from the OS or underlying system.
90-
#[derive(Debug, Clone)]
91+
#[derive(Debug, Clone, Event)]
9192
pub struct ReceivedCharacter {
9293
pub id: WindowId,
9394
pub char: char,
9495
}
9596

9697
/// An event that indicates a window has received or lost focus.
97-
#[derive(Debug, Clone)]
98+
#[derive(Debug, Clone, Event)]
9899
pub struct WindowFocused {
99100
pub id: WindowId,
100101
pub focused: bool,
101102
}
102103

103104
/// An event that indicates a window's scale factor has changed.
104-
#[derive(Debug, Clone)]
105+
#[derive(Debug, Clone, Event)]
105106
pub struct WindowScaleFactorChanged {
106107
pub id: WindowId,
107108
pub scale_factor: f64,
108109
}
109110
/// An event that indicates a window's OS-reported scale factor has changed.
110-
#[derive(Debug, Clone)]
111+
#[derive(Debug, Clone, Event)]
111112
pub struct WindowBackendScaleFactorChanged {
112113
pub id: WindowId,
113114
pub scale_factor: f64,
114115
}
115116

116117
/// Events related to files being dragged and dropped on a window.
117-
#[derive(Debug, Clone)]
118+
#[derive(Debug, Clone, Event)]
118119
pub enum FileDragAndDrop {
119120
DroppedFile { id: WindowId, path_buf: PathBuf },
120121

@@ -124,7 +125,7 @@ pub enum FileDragAndDrop {
124125
}
125126

126127
/// An event that is sent when a window is repositioned in physical pixels.
127-
#[derive(Debug, Clone)]
128+
#[derive(Debug, Clone, Event)]
128129
pub struct WindowMoved {
129130
pub id: WindowId,
130131
pub position: IVec2,

examples/ecs/event.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ fn main() {
1515
.run();
1616
}
1717

18+
#[derive(Event)]
1819
struct MyEvent {
1920
pub message: String,
2021
}
2122

22-
#[derive(Default)]
23+
#[derive(Default, Event)]
2324
struct PlaySound;
2425

2526
struct EventTriggerState {

0 commit comments

Comments
 (0)