@@ -13,6 +13,7 @@ mod system;
13
13
#[ cfg( target_arch = "wasm32" ) ]
14
14
mod web_resize;
15
15
mod winit_config;
16
+ mod winit_handler;
16
17
mod winit_windows;
17
18
18
19
use bevy_a11y:: AccessibilityRequested ;
@@ -22,6 +23,7 @@ use bevy_tasks::tick_global_task_pools_on_main_thread;
22
23
use system:: { changed_window, create_window, despawn_window, CachedWindow } ;
23
24
24
25
pub use winit_config:: * ;
26
+ pub use winit_handler:: * ;
25
27
pub use winit_windows:: * ;
26
28
27
29
use bevy_app:: { App , AppExit , Last , Plugin } ;
@@ -75,7 +77,7 @@ pub struct WinitPlugin;
75
77
76
78
impl Plugin for WinitPlugin {
77
79
fn build ( & self , app : & mut App ) {
78
- let mut event_loop_builder = EventLoopBuilder :: < ( ) > :: with_user_event ( ) ;
80
+ let mut event_loop_builder = EventLoopBuilder :: < HandleEvent > :: with_user_event ( ) ;
79
81
80
82
#[ cfg( target_os = "android" ) ]
81
83
{
@@ -113,7 +115,7 @@ impl Plugin for WinitPlugin {
113
115
#[ cfg( not( target_arch = "wasm32" ) ) ]
114
116
let mut create_window_system_state: SystemState < (
115
117
Commands ,
116
- NonSendMut < EventLoop < ( ) > > ,
118
+ NonSendMut < EventLoop < HandleEvent > > ,
117
119
Query < ( Entity , & mut Window ) > ,
118
120
EventWriter < WindowCreated > ,
119
121
NonSendMut < WinitWindows > ,
@@ -125,7 +127,7 @@ impl Plugin for WinitPlugin {
125
127
#[ cfg( target_arch = "wasm32" ) ]
126
128
let mut create_window_system_state: SystemState < (
127
129
Commands ,
128
- NonSendMut < EventLoop < ( ) > > ,
130
+ NonSendMut < EventLoop < HandleEvent > > ,
129
131
Query < ( Entity , & mut Window ) > ,
130
132
EventWriter < WindowCreated > ,
131
133
NonSendMut < WinitWindows > ,
@@ -185,9 +187,10 @@ impl Plugin for WinitPlugin {
185
187
}
186
188
}
187
189
188
- fn run < F > ( event_loop : EventLoop < ( ) > , event_handler : F ) -> !
190
+ fn run < F > ( event_loop : EventLoop < HandleEvent > , event_handler : F ) -> !
189
191
where
190
- F : ' static + FnMut ( Event < ' _ , ( ) > , & EventLoopWindowTarget < ( ) > , & mut ControlFlow ) ,
192
+ F : ' static
193
+ + FnMut ( Event < ' _ , HandleEvent > , & EventLoopWindowTarget < HandleEvent > , & mut ControlFlow ) ,
191
194
{
192
195
event_loop. run ( event_handler)
193
196
}
@@ -204,9 +207,9 @@ where
204
207
target_os = "netbsd" ,
205
208
target_os = "openbsd"
206
209
) ) ]
207
- fn run_return < F > ( event_loop : & mut EventLoop < ( ) > , event_handler : F )
210
+ fn run_return < F > ( event_loop : & mut EventLoop < HandleEvent > , event_handler : F )
208
211
where
209
- F : FnMut ( Event < ' _ , ( ) > , & EventLoopWindowTarget < ( ) > , & mut ControlFlow ) ,
212
+ F : FnMut ( Event < ' _ , HandleEvent > , & EventLoopWindowTarget < HandleEvent > , & mut ControlFlow ) ,
210
213
{
211
214
use winit:: platform:: run_return:: EventLoopExtRunReturn ;
212
215
event_loop. run_return ( event_handler) ;
@@ -221,9 +224,9 @@ where
221
224
target_os = "netbsd" ,
222
225
target_os = "openbsd"
223
226
) ) ) ]
224
- fn run_return < F > ( _event_loop : & mut EventLoop < ( ) > , _event_handler : F )
227
+ fn run_return < F > ( _event_loop : & mut EventLoop < HandleEvent > , _event_handler : F )
225
228
where
226
- F : FnMut ( Event < ' _ , ( ) > , & EventLoopWindowTarget < ( ) > , & mut ControlFlow ) ,
229
+ F : FnMut ( Event < ' _ , HandleEvent > , & EventLoopWindowTarget < HandleEvent > , & mut ControlFlow ) ,
227
230
{
228
231
panic ! ( "Run return is not supported on this platform!" )
229
232
}
@@ -304,10 +307,9 @@ pub fn winit_runner(mut app: App) {
304
307
// We remove this so that we have ownership over it.
305
308
let mut event_loop = app
306
309
. world
307
- . remove_non_send_resource :: < EventLoop < ( ) > > ( )
310
+ . remove_non_send_resource :: < EventLoop < HandleEvent > > ( )
308
311
. unwrap ( ) ;
309
- app. world
310
- . insert_non_send_resource ( event_loop. create_proxy ( ) ) ;
312
+ app. world . insert_resource ( WinitHandler :: new ( & event_loop) ) ;
311
313
312
314
let mut app_exit_event_reader = ManualEventReader :: < AppExit > :: default ( ) ;
313
315
let mut redraw_event_reader = ManualEventReader :: < RequestRedraw > :: default ( ) ;
@@ -364,8 +366,8 @@ pub fn winit_runner(mut app: App) {
364
366
let mut next_frame = Instant :: now ( ) ;
365
367
let mut frame_semaphore = 0u8 ;
366
368
367
- let event_handler = move |event : Event < ( ) > ,
368
- event_loop : & EventLoopWindowTarget < ( ) > ,
369
+ let event_handler = move |event : Event < HandleEvent > ,
370
+ event_loop : & EventLoopWindowTarget < HandleEvent > ,
369
371
control_flow : & mut ControlFlow | {
370
372
#[ cfg( feature = "trace" ) ]
371
373
let _span = bevy_utils:: tracing:: info_span!( "winit event_handler" ) . entered ( ) ;
@@ -670,6 +672,44 @@ pub fn winit_runner(mut app: App) {
670
672
delta : Vec2 :: new ( x as f32 , y as f32 ) ,
671
673
} ) ;
672
674
}
675
+ Event :: UserEvent ( event) => match event {
676
+ HandleEvent :: Run ( rate_multiplier) => {
677
+ tick_mode = if let TickMode :: Periodic { next_tick, .. } = tick_mode {
678
+ TickMode :: Periodic {
679
+ next_tick,
680
+ rate_multiplier,
681
+ }
682
+ } else {
683
+ TickMode :: Periodic {
684
+ next_tick : Instant :: now ( ) ,
685
+ rate_multiplier,
686
+ }
687
+ } ;
688
+ }
689
+ HandleEvent :: RunFullThrottle => {
690
+ tick_mode = TickMode :: Continuous ;
691
+ }
692
+ HandleEvent :: Pause => {
693
+ tick_mode = TickMode :: Manual { request_steps : 0 } ;
694
+ }
695
+ HandleEvent :: Step ( additional_steps) => {
696
+ tick_mode = if let TickMode :: Manual { request_steps } = tick_mode {
697
+ TickMode :: Manual {
698
+ request_steps : request_steps + additional_steps,
699
+ }
700
+ } else {
701
+ TickMode :: Manual {
702
+ request_steps : additional_steps,
703
+ }
704
+ } ;
705
+ }
706
+ HandleEvent :: Redraw => {
707
+ request_redraw = true ;
708
+ }
709
+ HandleEvent :: Exit ( code) => {
710
+ * control_flow = ControlFlow :: ExitWithCode ( code) ;
711
+ }
712
+ } ,
673
713
Event :: Suspended => {
674
714
app_active = false ;
675
715
#[ cfg( target_os = "android" ) ]
0 commit comments