@@ -13,6 +13,7 @@ mod system;
1313#[ cfg( target_arch = "wasm32" ) ]
1414mod web_resize;
1515mod winit_config;
16+ mod winit_handler;
1617mod winit_windows;
1718
1819use bevy_a11y:: AccessibilityRequested ;
@@ -22,6 +23,7 @@ use bevy_tasks::tick_global_task_pools_on_main_thread;
2223use system:: { changed_window, create_window, despawn_window, CachedWindow } ;
2324
2425pub use winit_config:: * ;
26+ pub use winit_handler:: * ;
2527pub use winit_windows:: * ;
2628
2729use bevy_app:: { App , AppExit , Last , Plugin } ;
@@ -75,7 +77,7 @@ pub struct WinitPlugin;
7577
7678impl Plugin for WinitPlugin {
7779 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 ( ) ;
7981
8082 #[ cfg( target_os = "android" ) ]
8183 {
@@ -113,7 +115,7 @@ impl Plugin for WinitPlugin {
113115 #[ cfg( not( target_arch = "wasm32" ) ) ]
114116 let mut create_window_system_state: SystemState < (
115117 Commands ,
116- NonSendMut < EventLoop < ( ) > > ,
118+ NonSendMut < EventLoop < HandleEvent > > ,
117119 Query < ( Entity , & mut Window ) > ,
118120 EventWriter < WindowCreated > ,
119121 NonSendMut < WinitWindows > ,
@@ -125,7 +127,7 @@ impl Plugin for WinitPlugin {
125127 #[ cfg( target_arch = "wasm32" ) ]
126128 let mut create_window_system_state: SystemState < (
127129 Commands ,
128- NonSendMut < EventLoop < ( ) > > ,
130+ NonSendMut < EventLoop < HandleEvent > > ,
129131 Query < ( Entity , & mut Window ) > ,
130132 EventWriter < WindowCreated > ,
131133 NonSendMut < WinitWindows > ,
@@ -185,9 +187,10 @@ impl Plugin for WinitPlugin {
185187 }
186188}
187189
188- fn run < F > ( event_loop : EventLoop < ( ) > , event_handler : F ) -> !
190+ fn run < F > ( event_loop : EventLoop < HandleEvent > , event_handler : F ) -> !
189191where
190- F : ' static + FnMut ( Event < ' _ , ( ) > , & EventLoopWindowTarget < ( ) > , & mut ControlFlow ) ,
192+ F : ' static
193+ + FnMut ( Event < ' _ , HandleEvent > , & EventLoopWindowTarget < HandleEvent > , & mut ControlFlow ) ,
191194{
192195 event_loop. run ( event_handler)
193196}
@@ -204,9 +207,9 @@ where
204207 target_os = "netbsd" ,
205208 target_os = "openbsd"
206209) ) ]
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 )
208211where
209- F : FnMut ( Event < ' _ , ( ) > , & EventLoopWindowTarget < ( ) > , & mut ControlFlow ) ,
212+ F : FnMut ( Event < ' _ , HandleEvent > , & EventLoopWindowTarget < HandleEvent > , & mut ControlFlow ) ,
210213{
211214 use winit:: platform:: run_return:: EventLoopExtRunReturn ;
212215 event_loop. run_return ( event_handler) ;
@@ -221,9 +224,9 @@ where
221224 target_os = "netbsd" ,
222225 target_os = "openbsd"
223226) ) ) ]
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 )
225228where
226- F : FnMut ( Event < ' _ , ( ) > , & EventLoopWindowTarget < ( ) > , & mut ControlFlow ) ,
229+ F : FnMut ( Event < ' _ , HandleEvent > , & EventLoopWindowTarget < HandleEvent > , & mut ControlFlow ) ,
227230{
228231 panic ! ( "Run return is not supported on this platform!" )
229232}
@@ -304,10 +307,9 @@ pub fn winit_runner(mut app: App) {
304307 // We remove this so that we have ownership over it.
305308 let mut event_loop = app
306309 . world
307- . remove_non_send_resource :: < EventLoop < ( ) > > ( )
310+ . remove_non_send_resource :: < EventLoop < HandleEvent > > ( )
308311 . unwrap ( ) ;
309- app. world
310- . insert_non_send_resource ( event_loop. create_proxy ( ) ) ;
312+ app. world . insert_resource ( WinitHandler :: new ( & event_loop) ) ;
311313
312314 let mut app_exit_event_reader = ManualEventReader :: < AppExit > :: default ( ) ;
313315 let mut redraw_event_reader = ManualEventReader :: < RequestRedraw > :: default ( ) ;
@@ -364,8 +366,8 @@ pub fn winit_runner(mut app: App) {
364366 let mut next_frame = Instant :: now ( ) ;
365367 let mut frame_semaphore = 0u8 ;
366368
367- let event_handler = move |event : Event < ( ) > ,
368- event_loop : & EventLoopWindowTarget < ( ) > ,
369+ let event_handler = move |event : Event < HandleEvent > ,
370+ event_loop : & EventLoopWindowTarget < HandleEvent > ,
369371 control_flow : & mut ControlFlow | {
370372 #[ cfg( feature = "trace" ) ]
371373 let _span = bevy_utils:: tracing:: info_span!( "winit event_handler" ) . entered ( ) ;
@@ -670,6 +672,44 @@ pub fn winit_runner(mut app: App) {
670672 delta : Vec2 :: new ( x as f32 , y as f32 ) ,
671673 } ) ;
672674 }
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+ } ,
673713 Event :: Suspended => {
674714 app_active = false ;
675715 #[ cfg( target_os = "android" ) ]
0 commit comments