diff --git a/maplibre-winit/src/lib.rs b/maplibre-winit/src/lib.rs index 280a3bb2..1a3ff7b4 100644 --- a/maplibre-winit/src/lib.rs +++ b/maplibre-winit/src/lib.rs @@ -12,6 +12,7 @@ use maplibre::{ }; use winit::{ event::{ElementState, Event, KeyEvent, WindowEvent}, + event_loop::ActiveEventLoop, keyboard::{Key, NamedKey}, }; @@ -19,6 +20,7 @@ use crate::input::{InputController, UpdateState}; pub mod input; +use maplibre::event_loop::EventLoopError; #[cfg(target_os = "android")] pub use winit::platform::android::activity as android_activity; @@ -75,7 +77,7 @@ pub struct WinitEventLoop { impl EventLoop for WinitEventLoop { type EventLoopProxy = WinitEventLoopProxy; - fn run(self, mut map: Map, max_frames: Option) + fn run(self, mut map: Map, max_frames: Option) -> Result<(), EventLoopError> where E: Environment, ::MapWindow: HeadedMapWindow, @@ -86,21 +88,20 @@ impl EventLoop for WinitEventLoop { let mut input_controller = InputController::new(0.2, 100.0, 0.1); let mut scale_factor = map.window().scale_factor(); - self.event_loop - .run(move |event, window_target| { - #[cfg(target_os = "android")] - if !map.is_initialized() && event == Event::Resumed { - use tokio::{runtime::Handle, task}; + let loop_ = move |event, window_target: &ActiveEventLoop| { + #[cfg(target_os = "android")] + if !map.is_initialized() && event == Event::Resumed { + use tokio::{runtime::Handle, task}; - task::block_in_place(|| { - Handle::current().block_on(async { - map.initialize_renderer().await.unwrap(); - }) - }); - return; - } + task::block_in_place(|| { + Handle::current().block_on(async { + map.initialize_renderer().await.unwrap(); + }) + }); + return; + } - match event { + match event { Event::DeviceEvent { ref event, .. // We're not using device_id currently @@ -182,7 +183,16 @@ impl EventLoop for WinitEventLoop { } _ => {} } - }); + }; + + #[cfg(target_arch = "wasm32")] + { + winit::platform::web::EventLoopExtWebSys::spawn(self.event_loop, loop_); + return Ok(()); + } + + #[cfg(not(target_arch = "wasm32"))] + return self.event_loop.run(loop_).map_err(|_| EventLoopError); } fn create_proxy(&self) -> Self::EventLoopProxy { diff --git a/maplibre-winit/src/noweb.rs b/maplibre-winit/src/noweb.rs index a1675fd1..339b593c 100644 --- a/maplibre-winit/src/noweb.rs +++ b/maplibre-winit/src/noweb.rs @@ -152,7 +152,8 @@ pub fn run_headed_map

( map.window_mut() .take_event_loop() - .expect("Event loop is not available") + .expect("event loop is not available") .run(map, None) + .expect("event loop creation failed") }) } diff --git a/maplibre/src/event_loop.rs b/maplibre/src/event_loop.rs index 12f710c5..19ccc680 100644 --- a/maplibre/src/event_loop.rs +++ b/maplibre/src/event_loop.rs @@ -21,6 +21,11 @@ pub enum SendEventError { Closed, } +/// When sending events to an event loop errors can occur. +#[derive(Error, Debug)] +#[error("event loop creation failed")] +pub struct EventLoopError; + pub trait EventLoopProxy { fn send_event(&self, event: T) -> Result<(), SendEventError>; } @@ -28,7 +33,7 @@ pub trait EventLoopProxy { pub trait EventLoop { type EventLoopProxy: EventLoopProxy; - fn run(self, map: Map, max_frames: Option) + fn run(self, map: Map, max_frames: Option) -> Result<(), EventLoopError> where E: Environment, ::MapWindow: HeadedMapWindow;