Update winit_runner to use spawn_app for wasm32 target (#16630)
# Objective - Fixes #12562 - Fixes #12195 ## Solution - Use `spawn_app` instead of `run_app` for web platform in `winit_runner` as suggested in the [document](https://docs.rs/winit/latest/winit/platform/web/trait.EventLoopExtWebSys.html#tymethod.spawn_app) ## Testing - Did you test these changes? If so, how? Tested on web. Created a react app which renders the bevy WASM app and returns the disposer to JS. Js will call the disposer on component unmount to stop the app, the disposer sends a signal to a `signal` receiver in rust which exits the app like this: ```rust fn handle_stop_signal( signal: NonSendMut<StopSignalReceiver>, window_entities: Query<(Entity, &Window)>, mut event_writer: EventWriter<WindowCloseRequested>, ) { if let Ok(_) = signal.try_recv() { for (entity, _window) in window_entities.iter() { info!("closing window entity: {:x}", entity.to_bits()); event_writer.send(WindowCloseRequested { window: entity }); } } } ``` - Are there any parts that need more testing? - No - How can other people (reviewers) test your changes? Is there anything specific they need to know? - Are all resources released after stopping the app like this? The WASM is still loaded, the LogPlugin complains on the logger re-initialization, but it's a warning anyway. - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? - Tested the WASM version on web platform and the native version on MacOS. --------- Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									4ba09f3dd9
								
							
						
					
					
						commit
						fbc55b84e2
					
				| @ -24,6 +24,8 @@ use bevy_tasks::tick_global_task_pools_on_main_thread; | |||||||
| use bevy_utils::HashMap; | use bevy_utils::HashMap; | ||||||
| use bevy_utils::Instant; | use bevy_utils::Instant; | ||||||
| use core::marker::PhantomData; | use core::marker::PhantomData; | ||||||
|  | #[cfg(target_arch = "wasm32")] | ||||||
|  | use winit::platform::web::EventLoopExtWebSys; | ||||||
| use winit::{ | use winit::{ | ||||||
|     application::ApplicationHandler, |     application::ApplicationHandler, | ||||||
|     dpi::PhysicalSize, |     dpi::PhysicalSize, | ||||||
| @ -868,19 +870,27 @@ pub fn winit_runner<T: Event>(mut app: App) -> AppExit { | |||||||
|     app.world_mut() |     app.world_mut() | ||||||
|         .insert_resource(EventLoopProxyWrapper(event_loop.create_proxy())); |         .insert_resource(EventLoopProxyWrapper(event_loop.create_proxy())); | ||||||
| 
 | 
 | ||||||
|     let mut runner_state = WinitAppRunnerState::new(app); |     let runner_state = WinitAppRunnerState::new(app); | ||||||
| 
 | 
 | ||||||
|     trace!("starting winit event loop"); |     trace!("starting winit event loop"); | ||||||
|     // TODO(clean): the winit docs mention using `spawn` instead of `run` on Wasm.
 |     // The winit docs mention using `spawn` instead of `run` on Wasm.
 | ||||||
|     if let Err(err) = event_loop.run_app(&mut runner_state) { |     // https://docs.rs/winit/latest/winit/platform/web/trait.EventLoopExtWebSys.html#tymethod.spawn_app
 | ||||||
|         error!("winit event loop returned an error: {err}"); |     cfg_if::cfg_if! { | ||||||
|  |         if #[cfg(target_arch = "wasm32")] { | ||||||
|  |             event_loop.spawn_app(runner_state); | ||||||
|  |             AppExit::Success | ||||||
|  |         } else { | ||||||
|  |             let mut runner_state = runner_state; | ||||||
|  |             if let Err(err) = event_loop.run_app(&mut runner_state) { | ||||||
|  |                 error!("winit event loop returned an error: {err}"); | ||||||
|  |             } | ||||||
|  |             // If everything is working correctly then the event loop only exits after it's sent an exit code.
 | ||||||
|  |             runner_state.app_exit.unwrap_or_else(|| { | ||||||
|  |                 error!("Failed to receive an app exit code! This is a bug"); | ||||||
|  |                 AppExit::error() | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     // If everything is working correctly then the event loop only exits after it's sent an exit code.
 |  | ||||||
|     runner_state.app_exit.unwrap_or_else(|| { |  | ||||||
|         error!("Failed to receive a app exit code! This is a bug"); |  | ||||||
|         AppExit::error() |  | ||||||
|     }) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub(crate) fn react_to_resize( | pub(crate) fn react_to_resize( | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Wei Xu
						Wei Xu