diff options
author | 2024-03-07 23:25:24 +0100 | |
---|---|---|
committer | 2024-03-07 23:25:24 +0100 | |
commit | ecf42b97df85df25b1b825f37adfeb00f658f6ee (patch) | |
tree | 43ea058c8b7d0b4a13f9fe3ad7015efeea94ed48 | |
parent | 1bb5a1b9a23e1c4739430ac87ca33b06c2f4d9df (diff) | |
download | iced-ecf42b97df85df25b1b825f37adfeb00f658f6ee.tar.gz iced-ecf42b97df85df25b1b825f37adfeb00f658f6ee.tar.bz2 iced-ecf42b97df85df25b1b825f37adfeb00f658f6ee.zip |
Fix `block_on` in `iced_wgpu` hanging Wasm builds
-rw-r--r-- | futures/src/backend/wasm/wasm_bindgen.rs | 2 | ||||
-rw-r--r-- | graphics/src/compositor.rs | 3 | ||||
-rw-r--r-- | renderer/src/compositor.rs | 27 | ||||
-rw-r--r-- | src/application.rs | 19 | ||||
-rw-r--r-- | tiny_skia/src/window/compositor.rs | 5 | ||||
-rw-r--r-- | wgpu/src/window/compositor.rs | 16 | ||||
-rw-r--r-- | winit/src/application.rs | 4 | ||||
-rw-r--r-- | winit/src/multi_window.rs | 7 |
8 files changed, 53 insertions, 30 deletions
diff --git a/futures/src/backend/wasm/wasm_bindgen.rs b/futures/src/backend/wasm/wasm_bindgen.rs index 2666f1b4..ff7ea0f6 100644 --- a/futures/src/backend/wasm/wasm_bindgen.rs +++ b/futures/src/backend/wasm/wasm_bindgen.rs @@ -1,4 +1,4 @@ -//! A `wasm-bindgein-futures` backend. +//! A `wasm-bindgen-futures` backend. /// A `wasm-bindgen-futures` executor. #[derive(Debug)] diff --git a/graphics/src/compositor.rs b/graphics/src/compositor.rs index 0188f4d8..91951a8e 100644 --- a/graphics/src/compositor.rs +++ b/graphics/src/compositor.rs @@ -6,6 +6,7 @@ use crate::core::Color; use crate::futures::{MaybeSend, MaybeSync}; use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; +use std::future::Future; use thiserror::Error; /// A graphics compositor that can draw to windows. @@ -23,7 +24,7 @@ pub trait Compositor: Sized { fn new<W: Window + Clone>( settings: Self::Settings, compatible_window: W, - ) -> Result<Self, Error>; + ) -> impl Future<Output = Result<Self, Error>>; /// Creates a [`Self::Renderer`] for the [`Compositor`]. fn create_renderer(&self) -> Self::Renderer; diff --git a/renderer/src/compositor.rs b/renderer/src/compositor.rs index dc2c50ff..c23a814c 100644 --- a/renderer/src/compositor.rs +++ b/renderer/src/compositor.rs @@ -4,6 +4,7 @@ use crate::graphics::{Error, Viewport}; use crate::{Renderer, Settings}; use std::env; +use std::future::Future; pub enum Compositor { TinySkia(iced_tiny_skia::window::Compositor), @@ -25,22 +26,25 @@ impl crate::graphics::Compositor for Compositor { fn new<W: Window + Clone>( settings: Self::Settings, compatible_window: W, - ) -> Result<Self, Error> { + ) -> impl Future<Output = Result<Self, Error>> { let candidates = Candidate::list_from_env().unwrap_or(Candidate::default_list()); - let mut error = Error::GraphicsAdapterNotFound; + async move { + let mut error = Error::GraphicsAdapterNotFound; - for candidate in candidates { - match candidate.build(settings, compatible_window.clone()) { - Ok(compositor) => return Ok(compositor), - Err(new_error) => { - error = new_error; + for candidate in candidates { + match candidate.build(settings, compatible_window.clone()).await + { + Ok(compositor) => return Ok(compositor), + Err(new_error) => { + error = new_error; + } } } - } - Err(error) + Err(error) + } } fn create_renderer(&self) -> Self::Renderer { @@ -225,7 +229,7 @@ impl Candidate { ) } - fn build<W: Window>( + async fn build<W: Window>( self, settings: Settings, _compatible_window: W, @@ -252,7 +256,8 @@ impl Candidate { ..iced_wgpu::Settings::from_env() }, _compatible_window, - )?; + ) + .await?; Ok(Compositor::Wgpu(compositor)) } diff --git a/src/application.rs b/src/application.rs index 3d89c758..87c2607a 100644 --- a/src/application.rs +++ b/src/application.rs @@ -205,11 +205,26 @@ pub trait Application: Sized { ..crate::renderer::Settings::default() }; - Ok(crate::shell::application::run::< + let run = crate::shell::application::run::< Instance<Self>, Self::Executor, crate::renderer::Compositor, - >(settings.into(), renderer_settings)?) + >(settings.into(), renderer_settings); + + #[cfg(target_arch = "wasm32")] + { + use crate::futures::FutureExt; + use iced_futures::backend::wasm::wasm_bindgen::Executor; + + Executor::new() + .expect("Create Wasm executor") + .spawn(run.map(|_| ())); + + Ok(()) + } + + #[cfg(not(target_arch = "wasm32"))] + Ok(crate::futures::executor::block_on(run)?) } } diff --git a/tiny_skia/src/window/compositor.rs b/tiny_skia/src/window/compositor.rs index 21ccf620..a98825f1 100644 --- a/tiny_skia/src/window/compositor.rs +++ b/tiny_skia/src/window/compositor.rs @@ -5,6 +5,7 @@ use crate::graphics::{Error, Viewport}; use crate::{Backend, Primitive, Renderer, Settings}; use std::collections::VecDeque; +use std::future::{self, Future}; use std::num::NonZeroU32; pub struct Compositor { @@ -31,8 +32,8 @@ impl crate::graphics::Compositor for Compositor { fn new<W: compositor::Window>( settings: Self::Settings, compatible_window: W, - ) -> Result<Self, Error> { - Ok(new(settings, compatible_window)) + ) -> impl Future<Output = Result<Self, Error>> { + future::ready(Ok(new(settings, compatible_window))) } fn create_renderer(&self) -> Self::Renderer { diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 0a5d2c8f..328ad781 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -6,6 +6,8 @@ use crate::graphics::compositor; use crate::graphics::{Error, Viewport}; use crate::{Backend, Primitive, Renderer, Settings}; +use std::future::Future; + /// A window graphics backend for iced powered by `wgpu`. #[allow(missing_debug_implementations)] pub struct Compositor { @@ -158,17 +160,13 @@ impl Compositor { /// Creates a [`Compositor`] and its [`Backend`] for the given [`Settings`] and /// window. -pub fn new<W: compositor::Window>( +pub async fn new<W: compositor::Window>( settings: Settings, compatible_window: W, ) -> Result<Compositor, Error> { - let compositor = futures::executor::block_on(Compositor::request( - settings, - Some(compatible_window), - )) - .ok_or(Error::GraphicsAdapterNotFound)?; - - Ok(compositor) + Compositor::request(settings, Some(compatible_window)) + .await + .ok_or(Error::GraphicsAdapterNotFound) } /// Presents the given primitives with the given [`Compositor`] and [`Backend`]. @@ -234,7 +232,7 @@ impl graphics::Compositor for Compositor { fn new<W: compositor::Window>( settings: Self::Settings, compatible_window: W, - ) -> Result<Self, Error> { + ) -> impl Future<Output = Result<Self, Error>> { new(settings, compatible_window) } diff --git a/winit/src/application.rs b/winit/src/application.rs index 05a4f070..29ee1a71 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -97,7 +97,7 @@ where /// Runs an [`Application`] with an executor, compositor, and the provided /// settings. -pub fn run<A, E, C>( +pub async fn run<A, E, C>( settings: Settings<A::Flags>, compositor_settings: C::Settings, ) -> Result<(), Error> @@ -188,7 +188,7 @@ where }; } - let compositor = C::new(compositor_settings, window.clone())?; + let compositor = C::new(compositor_settings, window.clone()).await?; let mut renderer = compositor.create_renderer(); for font in settings.fonts { diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index 03066d6c..49d4b8e8 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -12,7 +12,9 @@ use crate::core::widget::operation; use crate::core::window; use crate::core::{Point, Size}; use crate::futures::futures::channel::mpsc; -use crate::futures::futures::{task, Future, StreamExt}; +use crate::futures::futures::executor; +use crate::futures::futures::task; +use crate::futures::futures::{Future, StreamExt}; use crate::futures::{Executor, Runtime, Subscription}; use crate::graphics::{compositor, Compositor}; use crate::multi_window::window_manager::WindowManager; @@ -183,7 +185,8 @@ where }; } - let mut compositor = C::new(compositor_settings, main_window.clone())?; + let mut compositor = + executor::block_on(C::new(compositor_settings, main_window.clone()))?; let mut window_manager = WindowManager::new(); let _ = window_manager.insert( |