Fix Compositor concurrent initialization
It seems that initializing the compositor in a different thread can cause issues in some environments.
This commit is contained in:
parent
d203392c9d
commit
1b22d7d5fc
8 changed files with 37 additions and 14 deletions
|
|
@ -12,6 +12,10 @@ impl crate::Executor for Executor {
|
||||||
fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
|
fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
|
||||||
smol::spawn(future).detach();
|
smol::spawn(future).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
||||||
|
smol::block_on(future)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod time {
|
pub mod time {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@ impl crate::Executor for Executor {
|
||||||
fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
|
fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
|
||||||
self.spawn_ok(future);
|
self.spawn_ok(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
||||||
|
futures::executor::block_on(future)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod time {
|
pub mod time {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ impl crate::Executor for Executor {
|
||||||
let _guard = tokio::runtime::Runtime::enter(self);
|
let _guard = tokio::runtime::Runtime::enter(self);
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
||||||
|
self.block_on(future)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod time {
|
pub mod time {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ impl crate::Executor for Executor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn(&self, _future: impl Future<Output = ()> + MaybeSend + 'static) {}
|
fn spawn(&self, _future: impl Future<Output = ()> + MaybeSend + 'static) {}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
fn block_on<T>(&self, _future: impl Future<Output = T>) -> T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod time {
|
pub mod time {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,10 @@ pub trait Executor: Sized {
|
||||||
/// Spawns a future in the [`Executor`].
|
/// Spawns a future in the [`Executor`].
|
||||||
fn spawn(&self, future: impl Future<Output = ()> + MaybeSend + 'static);
|
fn spawn(&self, future: impl Future<Output = ()> + MaybeSend + 'static);
|
||||||
|
|
||||||
|
/// Runs a future to completion in the current thread within the [`Executor`].
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
fn block_on<T>(&self, future: impl Future<Output = T>) -> T;
|
||||||
|
|
||||||
/// Runs the given closure inside the [`Executor`].
|
/// Runs the given closure inside the [`Executor`].
|
||||||
///
|
///
|
||||||
/// Some executors, like `tokio`, require some global state to be in place
|
/// Some executors, like `tokio`, require some global state to be in place
|
||||||
|
|
|
||||||
|
|
@ -50,12 +50,10 @@ where
|
||||||
self.executor.enter(f)
|
self.executor.enter(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawns a [`Future`] in the [`Runtime`].
|
/// Runs a future to completion in the current thread within the [`Runtime`].
|
||||||
pub fn spawn(
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
&mut self,
|
pub fn block_on<T>(&mut self, future: impl Future<Output = T>) -> T {
|
||||||
future: impl Future<Output = ()> + MaybeSend + 'static,
|
self.executor.block_on(future)
|
||||||
) {
|
|
||||||
self.executor.spawn(future);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs a [`Stream`] in the [`Runtime`] until completion.
|
/// Runs a [`Stream`] in the [`Runtime`] until completion.
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use thiserror::Error;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// A graphics compositor that can draw to windows.
|
/// A graphics compositor that can draw to windows.
|
||||||
pub trait Compositor: Sized + MaybeSend {
|
pub trait Compositor: Sized {
|
||||||
/// The iced renderer of the backend.
|
/// The iced renderer of the backend.
|
||||||
type Renderer;
|
type Renderer;
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ pub trait Compositor: Sized + MaybeSend {
|
||||||
fn new<W: Window + Clone>(
|
fn new<W: Window + Clone>(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: W,
|
compatible_window: W,
|
||||||
) -> impl Future<Output = Result<Self, Error>> + MaybeSend {
|
) -> impl Future<Output = Result<Self, Error>> {
|
||||||
Self::with_backend(settings, compatible_window, None)
|
Self::with_backend(settings, compatible_window, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ pub trait Compositor: Sized + MaybeSend {
|
||||||
_settings: Settings,
|
_settings: Settings,
|
||||||
_compatible_window: W,
|
_compatible_window: W,
|
||||||
_backend: Option<&str>,
|
_backend: Option<&str>,
|
||||||
) -> impl Future<Output = Result<Self, Error>> + MaybeSend;
|
) -> impl Future<Output = Result<Self, Error>>;
|
||||||
|
|
||||||
/// Creates a [`Self::Renderer`] for the [`Compositor`].
|
/// Creates a [`Self::Renderer`] for the [`Compositor`].
|
||||||
fn create_renderer(&self) -> Self::Renderer;
|
fn create_renderer(&self) -> Self::Renderer;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::futures::futures::channel::oneshot;
|
||||||
use crate::futures::futures::task;
|
use crate::futures::futures::task;
|
||||||
use crate::futures::futures::{Future, StreamExt};
|
use crate::futures::futures::{Future, StreamExt};
|
||||||
use crate::futures::subscription::{self, Subscription};
|
use crate::futures::subscription::{self, Subscription};
|
||||||
use crate::futures::{Executor, MaybeSend, Runtime};
|
use crate::futures::{Executor, Runtime};
|
||||||
use crate::graphics;
|
use crate::graphics;
|
||||||
use crate::graphics::{Compositor, compositor};
|
use crate::graphics::{Compositor, compositor};
|
||||||
use crate::runtime::Debug;
|
use crate::runtime::Debug;
|
||||||
|
|
@ -149,7 +149,7 @@ pub fn run<P, C>(
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
P: Program + 'static,
|
P: Program + 'static,
|
||||||
C: Compositor<Renderer = P::Renderer> + MaybeSend + 'static,
|
C: Compositor<Renderer = P::Renderer> + 'static,
|
||||||
P::Theme: theme::Base,
|
P::Theme: theme::Base,
|
||||||
{
|
{
|
||||||
use winit::event_loop::EventLoop;
|
use winit::event_loop::EventLoop;
|
||||||
|
|
@ -560,7 +560,7 @@ async fn run_instance<P, C>(
|
||||||
default_fonts: Vec<Cow<'static, [u8]>>,
|
default_fonts: Vec<Cow<'static, [u8]>>,
|
||||||
) where
|
) where
|
||||||
P: Program + 'static,
|
P: Program + 'static,
|
||||||
C: Compositor<Renderer = P::Renderer> + MaybeSend + 'static,
|
C: Compositor<Renderer = P::Renderer> + 'static,
|
||||||
P::Theme: theme::Base,
|
P::Theme: theme::Base,
|
||||||
{
|
{
|
||||||
use winit::event;
|
use winit::event;
|
||||||
|
|
@ -636,7 +636,11 @@ async fn run_instance<P, C>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
runtime.spawn(create_compositor);
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
wasm_bindgen_futures::spawn_local(create_compositor);
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
runtime.block_on(create_compositor);
|
||||||
|
|
||||||
match compositor_receiver
|
match compositor_receiver
|
||||||
.await
|
.await
|
||||||
|
|
@ -648,7 +652,7 @@ async fn run_instance<P, C>(
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let _ = control_sender
|
let _ = control_sender
|
||||||
.start_send(Control::Crash(error.into()));
|
.start_send(Control::Crash(error.into()));
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue