Skip to content

Commit a5d70b8

Browse files
committed
Derive Reflect + FromReflect for window event types (#6235)
# Objective The window event types currently don't support reflection. This PR adds support to them (as requested [here](#6223 (comment))). ## Solution Implement `Reflect` + `FromReflect` for window event types. Relevant traits are also being reflected with `#[reflect(...)]` attributes. Additionally, this PR derives `Reflect` + `FromReflect` for `WindowDescriptor` and the types it depends on so that `CreateWindow` events can be fully manipulated through reflection. Finally, this PR adds `FromReflect` for `PathBuf` as a value type, which is needed for `FileDragAndDrop`. This adds the "glam" feature to the `bevy_reflect` dependency for package `bevy_window`. Since `bevy_window` transitively depends on `glam` already, all this brings in are the reflection `impl`s. ## Open questions Should `app.register_type::<PathBuf>();` be moved to `CorePlugin`? I added it to `WindowPlugin` because that's where it's used and `CorePlugin` doesn't seem to register all the missing std types, but it would also make sense in `CorePlugin` I believe since it's a commonly used type. --- ## Changelog Added: - Implemented `Reflect` + `FromReflect` for window events and related types. These types are automatically registered when adding the `WindowPlugin`.
1 parent b58ca87 commit a5d70b8

File tree

4 files changed

+213
-51
lines changed

4 files changed

+213
-51
lines changed

crates/bevy_window/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ serialize = ["serde"]
1717
bevy_app = { path = "../bevy_app", version = "0.9.0" }
1818
bevy_ecs = { path = "../bevy_ecs", version = "0.9.0" }
1919
bevy_math = { path = "../bevy_math", version = "0.9.0" }
20-
bevy_reflect = { path = "../bevy_reflect", version = "0.9.0" }
20+
bevy_reflect = { path = "../bevy_reflect", version = "0.9.0", features = [
21+
"glam",
22+
] }
2123
bevy_utils = { path = "../bevy_utils", version = "0.9.0" }
2224
# Used for close_on_esc
2325
bevy_input = { path = "../bevy_input", version = "0.9.0" }

crates/bevy_window/src/event.rs

Lines changed: 113 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,19 @@ use std::path::PathBuf;
22

33
use super::{WindowDescriptor, WindowId};
44
use bevy_math::{IVec2, Vec2};
5+
use bevy_reflect::{FromReflect, Reflect};
6+
7+
#[cfg(feature = "serialize")]
8+
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
59

610
/// A window event that is sent whenever a window's logical size has changed.
7-
#[derive(Debug, Clone, PartialEq)]
8-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
11+
#[derive(Debug, Clone, PartialEq, Reflect, FromReflect)]
12+
#[reflect(Debug, PartialEq)]
13+
#[cfg_attr(
14+
feature = "serialize",
15+
derive(serde::Serialize, serde::Deserialize),
16+
reflect(Serialize, Deserialize)
17+
)]
918
pub struct WindowResized {
1019
pub id: WindowId,
1120
/// The new logical width of the window.
@@ -15,25 +24,40 @@ pub struct WindowResized {
1524
}
1625

1726
/// An event that indicates that a new window should be created.
18-
#[derive(Debug, Clone, PartialEq)]
19-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
27+
#[derive(Debug, Clone, PartialEq, Reflect, FromReflect)]
28+
#[reflect(Debug, PartialEq)]
29+
#[cfg_attr(
30+
feature = "serialize",
31+
derive(serde::Serialize, serde::Deserialize),
32+
reflect(Serialize, Deserialize)
33+
)]
2034
pub struct CreateWindow {
2135
pub id: WindowId,
2236
pub descriptor: WindowDescriptor,
2337
}
2438

2539
/// An event that indicates the window should redraw, even if its control flow is set to `Wait` and
2640
/// there have been no window events.
27-
#[derive(Debug, Clone, PartialEq, Eq)]
28-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
41+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
42+
#[reflect(Debug, PartialEq)]
43+
#[cfg_attr(
44+
feature = "serialize",
45+
derive(serde::Serialize, serde::Deserialize),
46+
reflect(Serialize, Deserialize)
47+
)]
2948
pub struct RequestRedraw;
3049

3150
/// An event that is sent whenever a new window is created.
3251
///
3352
/// To create a new window, send a [`CreateWindow`] event - this
3453
/// event will be sent in the handler for that event.
35-
#[derive(Debug, Clone, PartialEq, Eq)]
36-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
54+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
55+
#[reflect(Debug, PartialEq)]
56+
#[cfg_attr(
57+
feature = "serialize",
58+
derive(serde::Serialize, serde::Deserialize),
59+
reflect(Serialize, Deserialize)
60+
)]
3761
pub struct WindowCreated {
3862
pub id: WindowId,
3963
}
@@ -49,8 +73,13 @@ pub struct WindowCreated {
4973
/// [`WindowPlugin`]: crate::WindowPlugin
5074
/// [`Window`]: crate::Window
5175
/// [closing]: crate::Window::close
52-
#[derive(Debug, Clone, PartialEq, Eq)]
53-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
76+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
77+
#[reflect(Debug, PartialEq)]
78+
#[cfg_attr(
79+
feature = "serialize",
80+
derive(serde::Serialize, serde::Deserialize),
81+
reflect(Serialize, Deserialize)
82+
)]
5483
pub struct WindowCloseRequested {
5584
pub id: WindowId,
5685
}
@@ -59,11 +88,17 @@ pub struct WindowCloseRequested {
5988
/// handler for [`Window::close`].
6089
///
6190
/// [`Window::close`]: crate::Window::close
62-
#[derive(Debug, Clone, PartialEq, Eq)]
63-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
91+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
92+
#[reflect(Debug, PartialEq)]
93+
#[cfg_attr(
94+
feature = "serialize",
95+
derive(serde::Serialize, serde::Deserialize),
96+
reflect(Serialize, Deserialize)
97+
)]
6498
pub struct WindowClosed {
6599
pub id: WindowId,
66100
}
101+
67102
/// An event reporting that the mouse cursor has moved on a window.
68103
///
69104
/// The event is sent only if the cursor is over one of the application's windows.
@@ -73,62 +108,105 @@ pub struct WindowClosed {
73108
///
74109
/// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved
75110
/// [`MouseMotion`]: bevy_input::mouse::MouseMotion
76-
#[derive(Debug, Clone, PartialEq)]
77-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
111+
#[derive(Debug, Clone, PartialEq, Reflect, FromReflect)]
112+
#[reflect(Debug, PartialEq)]
113+
#[cfg_attr(
114+
feature = "serialize",
115+
derive(serde::Serialize, serde::Deserialize),
116+
reflect(Serialize, Deserialize)
117+
)]
78118
pub struct CursorMoved {
79119
/// The identifier of the window the cursor has moved on.
80120
pub id: WindowId,
81121

82122
/// The position of the cursor, in window coordinates.
83123
pub position: Vec2,
84124
}
125+
85126
/// An event that is sent whenever the user's cursor enters a window.
86-
#[derive(Debug, Clone, PartialEq, Eq)]
87-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
127+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
128+
#[reflect(Debug, PartialEq)]
129+
#[cfg_attr(
130+
feature = "serialize",
131+
derive(serde::Serialize, serde::Deserialize),
132+
reflect(Serialize, Deserialize)
133+
)]
88134
pub struct CursorEntered {
89135
pub id: WindowId,
90136
}
137+
91138
/// An event that is sent whenever the user's cursor leaves a window.
92-
#[derive(Debug, Clone, PartialEq, Eq)]
93-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
139+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
140+
#[reflect(Debug, PartialEq)]
141+
#[cfg_attr(
142+
feature = "serialize",
143+
derive(serde::Serialize, serde::Deserialize),
144+
reflect(Serialize, Deserialize)
145+
)]
94146
pub struct CursorLeft {
95147
pub id: WindowId,
96148
}
97149

98150
/// An event that is sent whenever a window receives a character from the OS or underlying system.
99-
#[derive(Debug, Clone, PartialEq, Eq)]
100-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
151+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
152+
#[reflect(Debug, PartialEq)]
153+
#[cfg_attr(
154+
feature = "serialize",
155+
derive(serde::Serialize, serde::Deserialize),
156+
reflect(Serialize, Deserialize)
157+
)]
101158
pub struct ReceivedCharacter {
102159
pub id: WindowId,
103160
pub char: char,
104161
}
105162

106163
/// An event that indicates a window has received or lost focus.
107-
#[derive(Debug, Clone, PartialEq, Eq)]
108-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
164+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
165+
#[reflect(Debug, PartialEq)]
166+
#[cfg_attr(
167+
feature = "serialize",
168+
derive(serde::Serialize, serde::Deserialize),
169+
reflect(Serialize, Deserialize)
170+
)]
109171
pub struct WindowFocused {
110172
pub id: WindowId,
111173
pub focused: bool,
112174
}
113175

114176
/// An event that indicates a window's scale factor has changed.
115-
#[derive(Debug, Clone, PartialEq)]
116-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
177+
#[derive(Debug, Clone, PartialEq, Reflect, FromReflect)]
178+
#[reflect(Debug, PartialEq)]
179+
#[cfg_attr(
180+
feature = "serialize",
181+
derive(serde::Serialize, serde::Deserialize),
182+
reflect(Serialize, Deserialize)
183+
)]
117184
pub struct WindowScaleFactorChanged {
118185
pub id: WindowId,
119186
pub scale_factor: f64,
120187
}
188+
121189
/// An event that indicates a window's OS-reported scale factor has changed.
122-
#[derive(Debug, Clone, PartialEq)]
123-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
190+
#[derive(Debug, Clone, PartialEq, Reflect, FromReflect)]
191+
#[reflect(Debug, PartialEq)]
192+
#[cfg_attr(
193+
feature = "serialize",
194+
derive(serde::Serialize, serde::Deserialize),
195+
reflect(Serialize, Deserialize)
196+
)]
124197
pub struct WindowBackendScaleFactorChanged {
125198
pub id: WindowId,
126199
pub scale_factor: f64,
127200
}
128201

129202
/// Events related to files being dragged and dropped on a window.
130-
#[derive(Debug, Clone, PartialEq, Eq)]
131-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
203+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
204+
#[reflect(Debug, PartialEq)]
205+
#[cfg_attr(
206+
feature = "serialize",
207+
derive(serde::Serialize, serde::Deserialize),
208+
reflect(Serialize, Deserialize)
209+
)]
132210
pub enum FileDragAndDrop {
133211
DroppedFile { id: WindowId, path_buf: PathBuf },
134212

@@ -138,8 +216,13 @@ pub enum FileDragAndDrop {
138216
}
139217

140218
/// An event that is sent when a window is repositioned in physical pixels.
141-
#[derive(Debug, Clone, PartialEq, Eq)]
142-
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
219+
#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)]
220+
#[reflect(Debug, PartialEq)]
221+
#[cfg_attr(
222+
feature = "serialize",
223+
derive(serde::Serialize, serde::Deserialize),
224+
reflect(Serialize, Deserialize)
225+
)]
143226
pub struct WindowMoved {
144227
pub id: WindowId,
145228
pub position: IVec2,

crates/bevy_window/src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub mod prelude {
2424

2525
use bevy_app::prelude::*;
2626
use bevy_ecs::schedule::{IntoSystemDescriptor, SystemLabel};
27+
use std::path::PathBuf;
2728

2829
impl Default for WindowPlugin {
2930
fn default() -> Self {
@@ -97,6 +98,35 @@ impl Plugin for WindowPlugin {
9798
if self.close_when_requested {
9899
app.add_system(close_when_requested);
99100
}
101+
102+
// Register event types
103+
app.register_type::<WindowResized>()
104+
.register_type::<CreateWindow>()
105+
.register_type::<RequestRedraw>()
106+
.register_type::<WindowCreated>()
107+
.register_type::<WindowCloseRequested>()
108+
.register_type::<WindowClosed>()
109+
.register_type::<CursorMoved>()
110+
.register_type::<CursorEntered>()
111+
.register_type::<CursorLeft>()
112+
.register_type::<ReceivedCharacter>()
113+
.register_type::<WindowFocused>()
114+
.register_type::<WindowScaleFactorChanged>()
115+
.register_type::<WindowBackendScaleFactorChanged>()
116+
.register_type::<FileDragAndDrop>()
117+
.register_type::<WindowMoved>();
118+
119+
// Register window descriptor and related types
120+
app.register_type::<WindowId>()
121+
.register_type::<PresentMode>()
122+
.register_type::<WindowResizeConstraints>()
123+
.register_type::<WindowMode>()
124+
.register_type::<WindowPosition>()
125+
.register_type::<MonitorSelection>()
126+
.register_type::<WindowDescriptor>();
127+
128+
// Register `PathBuf` as it's used by `FileDragAndDrop`
129+
app.register_type::<PathBuf>();
100130
}
101131
}
102132

0 commit comments

Comments
 (0)