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::Instant;
|
||||
use core::marker::PhantomData;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use winit::platform::web::EventLoopExtWebSys;
|
||||
use winit::{
|
||||
application::ApplicationHandler,
|
||||
dpi::PhysicalSize,
|
||||
@ -868,19 +870,27 @@ pub fn winit_runner<T: Event>(mut app: App) -> AppExit {
|
||||
app.world_mut()
|
||||
.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");
|
||||
// TODO(clean): the winit docs mention using `spawn` instead of `run` on Wasm.
|
||||
if let Err(err) = event_loop.run_app(&mut runner_state) {
|
||||
error!("winit event loop returned an error: {err}");
|
||||
// The winit docs mention using `spawn` instead of `run` on Wasm.
|
||||
// https://docs.rs/winit/latest/winit/platform/web/trait.EventLoopExtWebSys.html#tymethod.spawn_app
|
||||
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(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user