summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-01-20 04:47:36 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-01-20 04:47:36 +0100
commit90690702e1e4abab804ec91e8ff4183824bec436 (patch)
treed3f989047f4ac5166bc5baed9febcc10af2d63a6
parent35760ac68f06e783e64e9048aff0fff6df1c09cf (diff)
downloadiced-90690702e1e4abab804ec91e8ff4183824bec436.tar.gz
iced-90690702e1e4abab804ec91e8ff4183824bec436.tar.bz2
iced-90690702e1e4abab804ec91e8ff4183824bec436.zip
Add `Application::Executor` associated type
-rw-r--r--Cargo.toml1
-rw-r--r--examples/events.rs5
-rw-r--r--examples/pokedex.rs1
-rw-r--r--examples/stopwatch.rs1
-rw-r--r--examples/todos.rs1
-rw-r--r--futures/Cargo.toml4
-rw-r--r--futures/src/executor.rs36
-rw-r--r--futures/src/executor/async_std.rs15
-rw-r--r--futures/src/executor/null.rs13
-rw-r--r--futures/src/executor/thread_pool.rs15
-rw-r--r--futures/src/executor/tokio.rs19
-rw-r--r--futures/src/lib.rs6
-rw-r--r--futures/src/runtime.rs8
-rw-r--r--futures/src/runtime/executor.rs27
-rw-r--r--native/Cargo.toml2
-rw-r--r--native/src/lib.rs7
-rw-r--r--native/src/runtime.rs2
-rw-r--r--native/src/subscription.rs2
-rw-r--r--native/src/subscription/events.rs3
-rw-r--r--src/application.rs14
-rw-r--r--src/lib.rs22
-rw-r--r--src/native.rs2
-rw-r--r--src/native/executor.rs23
-rw-r--r--src/sandbox.rs3
-rw-r--r--web/Cargo.toml1
-rw-r--r--web/src/lib.rs2
-rw-r--r--winit/Cargo.toml6
-rw-r--r--winit/src/application.rs18
-rw-r--r--winit/src/proxy.rs2
29 files changed, 192 insertions, 69 deletions
diff --git a/Cargo.toml b/Cargo.toml
index fbe3b9f2..87f3000e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -41,6 +41,7 @@ iced_web = { version = "0.1.0", path = "web" }
[dev-dependencies]
iced_native = { version = "0.1", path = "./native" }
iced_wgpu = { version = "0.1", path = "./wgpu" }
+iced_futures = { version = "0.1.0-alpha", path = "./futures", features = ["async-std"] }
env_logger = "0.7"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
diff --git a/examples/events.rs b/examples/events.rs
index 74542171..0c9dca05 100644
--- a/examples/events.rs
+++ b/examples/events.rs
@@ -1,6 +1,6 @@
use iced::{
- Align, Application, Checkbox, Column, Command, Container, Element, Length,
- Settings, Subscription, Text,
+ executor, Align, Application, Checkbox, Column, Command, Container,
+ Element, Length, Settings, Subscription, Text,
};
pub fn main() {
@@ -20,6 +20,7 @@ enum Message {
}
impl Application for Events {
+ type Executor = executor::Default;
type Message = Message;
fn new() -> (Events, Command<Message>) {
diff --git a/examples/pokedex.rs b/examples/pokedex.rs
index 7326f94f..505dbf19 100644
--- a/examples/pokedex.rs
+++ b/examples/pokedex.rs
@@ -27,6 +27,7 @@ enum Message {
}
impl Application for Pokedex {
+ type Executor = iced_futures::executor::AsyncStd;
type Message = Message;
fn new() -> (Pokedex, Command<Message>) {
diff --git a/examples/stopwatch.rs b/examples/stopwatch.rs
index 2bc85c4d..6e357039 100644
--- a/examples/stopwatch.rs
+++ b/examples/stopwatch.rs
@@ -28,6 +28,7 @@ enum Message {
}
impl Application for Stopwatch {
+ type Executor = iced_futures::executor::AsyncStd;
type Message = Message;
fn new() -> (Stopwatch, Command<Message>) {
diff --git a/examples/todos.rs b/examples/todos.rs
index 4166f75a..06595a1e 100644
--- a/examples/todos.rs
+++ b/examples/todos.rs
@@ -38,6 +38,7 @@ enum Message {
}
impl Application for Todos {
+ type Executor = iced_futures::executor::AsyncStd;
type Message = Message;
fn new() -> (Todos, Command<Message>) {
diff --git a/futures/Cargo.toml b/futures/Cargo.toml
index 5b303e01..13c2d6b7 100644
--- a/futures/Cargo.toml
+++ b/futures/Cargo.toml
@@ -23,3 +23,7 @@ version = "0.3"
version = "0.2"
optional = true
features = ["rt-core"]
+
+[dependencies.async-std]
+version = "1.0"
+optional = true
diff --git a/futures/src/executor.rs b/futures/src/executor.rs
new file mode 100644
index 00000000..144a41f8
--- /dev/null
+++ b/futures/src/executor.rs
@@ -0,0 +1,36 @@
+//! Choose your preferred executor to power a runtime.
+mod null;
+
+#[cfg(feature = "thread-pool")]
+mod thread_pool;
+
+#[cfg(feature = "thread-pool")]
+pub use thread_pool::ThreadPool;
+
+#[cfg(feature = "tokio")]
+mod tokio;
+
+#[cfg(feature = "async-std")]
+mod async_std;
+
+pub use null::Null;
+
+#[cfg(feature = "tokio")]
+pub use self::tokio::Tokio;
+
+#[cfg(feature = "async-std")]
+pub use self::async_std::AsyncStd;
+
+use futures::Future;
+
+pub trait Executor: Sized {
+ fn new() -> Result<Self, futures::io::Error>
+ where
+ Self: Sized;
+
+ fn spawn(&self, future: impl Future<Output = ()> + Send + 'static);
+
+ fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
+ f()
+ }
+}
diff --git a/futures/src/executor/async_std.rs b/futures/src/executor/async_std.rs
new file mode 100644
index 00000000..b056b23d
--- /dev/null
+++ b/futures/src/executor/async_std.rs
@@ -0,0 +1,15 @@
+use crate::Executor;
+
+use futures::Future;
+
+pub struct AsyncStd;
+
+impl Executor for AsyncStd {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Self)
+ }
+
+ fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
+ let _ = async_std::task::spawn(future);
+ }
+}
diff --git a/futures/src/executor/null.rs b/futures/src/executor/null.rs
new file mode 100644
index 00000000..722073bb
--- /dev/null
+++ b/futures/src/executor/null.rs
@@ -0,0 +1,13 @@
+use crate::Executor;
+
+use futures::Future;
+
+pub struct Null;
+
+impl Executor for Null {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Self)
+ }
+
+ fn spawn(&self, _future: impl Future<Output = ()> + Send + 'static) {}
+}
diff --git a/futures/src/executor/thread_pool.rs b/futures/src/executor/thread_pool.rs
new file mode 100644
index 00000000..6393d0d5
--- /dev/null
+++ b/futures/src/executor/thread_pool.rs
@@ -0,0 +1,15 @@
+use crate::Executor;
+
+use futures::Future;
+
+pub type ThreadPool = futures::executor::ThreadPool;
+
+impl Executor for futures::executor::ThreadPool {
+ fn new() -> Result<Self, futures::io::Error> {
+ futures::executor::ThreadPool::new()
+ }
+
+ fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
+ self.spawn_ok(future);
+ }
+}
diff --git a/futures/src/executor/tokio.rs b/futures/src/executor/tokio.rs
new file mode 100644
index 00000000..aafa7e7b
--- /dev/null
+++ b/futures/src/executor/tokio.rs
@@ -0,0 +1,19 @@
+use crate::Executor;
+
+use futures::Future;
+
+pub type Tokio = tokio::runtime::Runtime;
+
+impl Executor for Tokio {
+ fn new() -> Result<Self, futures::io::Error> {
+ tokio::runtime::Runtime::new()
+ }
+
+ fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
+ let _ = tokio::runtime::Runtime::spawn(self, future);
+ }
+
+ fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
+ tokio::runtime::Runtime::enter(self, f)
+ }
+}
diff --git a/futures/src/lib.rs b/futures/src/lib.rs
index f6bcf85a..832a50f6 100644
--- a/futures/src/lib.rs
+++ b/futures/src/lib.rs
@@ -1,8 +1,12 @@
+pub use futures;
+
mod command;
+mod runtime;
-pub mod runtime;
+pub mod executor;
pub mod subscription;
pub use command::Command;
+pub use executor::Executor;
pub use runtime::Runtime;
pub use subscription::Subscription;
diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs
index 37905c61..a508c46e 100644
--- a/futures/src/runtime.rs
+++ b/futures/src/runtime.rs
@@ -1,9 +1,5 @@
-//! Run commands and subscriptions.
-mod executor;
-
-pub use executor::Executor;
-
-use crate::{subscription, Command, Subscription};
+//! Run commands and keep track of subscriptions.
+use crate::{subscription, Command, Executor, Subscription};
use futures::Sink;
use std::marker::PhantomData;
diff --git a/futures/src/runtime/executor.rs b/futures/src/runtime/executor.rs
deleted file mode 100644
index eec5e231..00000000
--- a/futures/src/runtime/executor.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use futures::Future;
-
-pub trait Executor {
- fn spawn(&self, future: impl Future<Output = ()> + Send + 'static);
-
- fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
- f()
- }
-}
-
-#[cfg(feature = "thread-pool")]
-impl Executor for futures::executor::ThreadPool {
- fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
- self.spawn_ok(future);
- }
-}
-
-#[cfg(feature = "tokio")]
-impl Executor for tokio::runtime::Runtime {
- fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
- let _ = tokio::runtime::Runtime::spawn(self, future);
- }
-
- fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
- tokio::runtime::Runtime::enter(self, f)
- }
-}
diff --git a/native/Cargo.toml b/native/Cargo.toml
index 57a869e2..6276535e 100644
--- a/native/Cargo.toml
+++ b/native/Cargo.toml
@@ -11,7 +11,6 @@ repository = "https://github.com/hecrj/iced"
twox-hash = "1.5"
raw-window-handle = "0.3"
unicode-segmentation = "1.6"
-futures = "0.3"
[dependencies.iced_core]
version = "0.1.0"
@@ -20,3 +19,4 @@ path = "../core"
[dependencies.iced_futures]
version = "0.1.0-alpha"
path = "../futures"
+features = ["thread-pool"]
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 7730c6a3..b5856c00 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -42,7 +42,6 @@
pub mod input;
pub mod layout;
pub mod renderer;
-pub mod runtime;
pub mod subscription;
pub mod widget;
pub mod window;
@@ -52,6 +51,7 @@ mod element;
mod event;
mod hasher;
mod mouse_cursor;
+mod runtime;
mod size;
mod user_interface;
@@ -59,7 +59,10 @@ pub use iced_core::{
Align, Background, Color, Font, HorizontalAlignment, Length, Point,
Rectangle, Vector, VerticalAlignment,
};
-pub use iced_futures::Command;
+pub use iced_futures::{executor, futures, Command};
+
+#[doc(no_inline)]
+pub use executor::Executor;
pub use clipboard::Clipboard;
pub use element::Element;
diff --git a/native/src/runtime.rs b/native/src/runtime.rs
index 2b3abbf1..9fa031f4 100644
--- a/native/src/runtime.rs
+++ b/native/src/runtime.rs
@@ -10,5 +10,3 @@ use crate::{Event, Hasher};
/// [`Subscription`]: ../struct.Subscription.html
pub type Runtime<Executor, Receiver, Message> =
iced_futures::Runtime<Hasher, Event, Executor, Receiver, Message>;
-
-pub use iced_futures::runtime::Executor;
diff --git a/native/src/subscription.rs b/native/src/subscription.rs
index 43f1758a..0d002c6c 100644
--- a/native/src/subscription.rs
+++ b/native/src/subscription.rs
@@ -1,6 +1,6 @@
//! Listen to external events in your application.
use crate::{Event, Hasher};
-use futures::stream::BoxStream;
+use iced_futures::futures::stream::BoxStream;
/// A request to listen to external events.
///
diff --git a/native/src/subscription/events.rs b/native/src/subscription/events.rs
index 6ff2c0fb..7d33166e 100644
--- a/native/src/subscription/events.rs
+++ b/native/src/subscription/events.rs
@@ -2,6 +2,7 @@ use crate::{
subscription::{EventStream, Recipe},
Event, Hasher,
};
+use iced_futures::futures::stream::BoxStream;
pub struct Events;
@@ -17,7 +18,7 @@ impl Recipe<Hasher, Event> for Events {
fn stream(
self: Box<Self>,
event_stream: EventStream,
- ) -> futures::stream::BoxStream<'static, Self::Output> {
+ ) -> BoxStream<'static, Self::Output> {
event_stream
}
}
diff --git a/src/application.rs b/src/application.rs
index b940cc17..3a526f1b 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -1,4 +1,4 @@
-use crate::{window, Command, Element, Settings, Subscription};
+use crate::{window, Command, Element, Executor, Settings, Subscription};
/// An interactive cross-platform application.
///
@@ -19,7 +19,7 @@ use crate::{window, Command, Element, Settings, Subscription};
/// before](index.html#overview). We just need to fill in the gaps:
///
/// ```no_run
-/// use iced::{button, Application, Button, Column, Command, Element, Settings, Text};
+/// use iced::{button, executor, Application, Button, Column, Command, Element, Settings, Text};
///
/// pub fn main() {
/// Counter::run(Settings::default())
@@ -39,6 +39,7 @@ use crate::{window, Command, Element, Settings, Subscription};
/// }
///
/// impl Application for Counter {
+/// type Executor = executor::Null;
/// type Message = Message;
///
/// fn new() -> (Self, Command<Message>) {
@@ -80,6 +81,14 @@ use crate::{window, Command, Element, Settings, Subscription};
/// }
/// ```
pub trait Application: Sized {
+ /// The [`Executor`] that will run commands and subscriptions.
+ ///
+ /// The [`executor::Default`] can be a good starting point!
+ ///
+ /// [`Executor`]: trait.Executor.html
+ /// [`executor::Default`]: executor/struct.Default.html
+ type Executor: Executor;
+
/// The type of __messages__ your [`Application`] will produce.
///
/// [`Application`]: trait.Application.html
@@ -185,6 +194,7 @@ where
A: Application,
{
type Renderer = iced_wgpu::Renderer;
+ type Executor = A::Executor;
type Message = A::Message;
fn new() -> (Self, Command<A::Message>) {
diff --git a/src/lib.rs b/src/lib.rs
index 759dea2f..18dfc098 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -180,18 +180,26 @@
#![deny(unsafe_code)]
#![deny(rust_2018_idioms)]
mod application;
-#[cfg(target_arch = "wasm32")]
-#[path = "web.rs"]
-mod platform;
-#[cfg(not(target_arch = "wasm32"))]
-#[path = "native.rs"]
-mod platform;
mod sandbox;
+#[cfg(not(target_arch = "wasm32"))]
+mod native;
+
+#[cfg(not(target_arch = "wasm32"))]
+pub use native::*;
+
+#[cfg(target_arch = "wasm32")]
+mod web;
+
+#[cfg(target_arch = "wasm32")]
+pub use web::*;
+
pub mod settings;
pub mod window;
+#[doc(no_inline)]
+pub use executor::Executor;
+
pub use application::Application;
-pub use platform::*;
pub use sandbox::Sandbox;
pub use settings::Settings;
diff --git a/src/native.rs b/src/native.rs
index 35441a3e..86ccffab 100644
--- a/src/native.rs
+++ b/src/native.rs
@@ -3,6 +3,8 @@ pub use iced_winit::{
Space, Subscription, Vector, VerticalAlignment,
};
+pub mod executor;
+
pub mod widget {
//! Display information and interactive controls in your application.
//!
diff --git a/src/native/executor.rs b/src/native/executor.rs
new file mode 100644
index 00000000..68a1d280
--- /dev/null
+++ b/src/native/executor.rs
@@ -0,0 +1,23 @@
+//! Choose your preferred executor to power your application.
+pub use iced_winit::{executor::Null, Executor};
+use iced_winit::{executor::ThreadPool, futures};
+
+/// The default cross-platform executor.
+///
+/// - On native platforms, it will use a `ThreadPool`.
+/// - On the Web, it will use `wasm-bindgen-futures::spawn_local`.
+#[derive(Debug)]
+pub struct Default(ThreadPool);
+
+impl Executor for Default {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Default(ThreadPool::new()?))
+ }
+
+ fn spawn(
+ &self,
+ future: impl futures::Future<Output = ()> + Send + 'static,
+ ) {
+ self.0.spawn(future);
+ }
+}
diff --git a/src/sandbox.rs b/src/sandbox.rs
index dda4c3f5..2c0332ff 100644
--- a/src/sandbox.rs
+++ b/src/sandbox.rs
@@ -1,4 +1,4 @@
-use crate::{Application, Command, Element, Settings, Subscription};
+use crate::{executor, Application, Command, Element, Settings, Subscription};
/// A sandboxed [`Application`].
///
@@ -133,6 +133,7 @@ impl<T> Application for T
where
T: Sandbox,
{
+ type Executor = executor::Null;
type Message = T::Message;
fn new() -> (Self, Command<T::Message>) {
diff --git a/web/Cargo.toml b/web/Cargo.toml
index ea092575..46953863 100644
--- a/web/Cargo.toml
+++ b/web/Cargo.toml
@@ -18,7 +18,6 @@ maintenance = { status = "actively-developed" }
dodrio = "0.1.0"
wasm-bindgen = "0.2.51"
wasm-bindgen-futures = "0.4"
-futures = "0.3"
[dependencies.iced_core]
version = "0.1.0"
diff --git a/web/src/lib.rs b/web/src/lib.rs
index b183c390..c44b99b5 100644
--- a/web/src/lib.rs
+++ b/web/src/lib.rs
@@ -75,7 +75,7 @@ pub use iced_core::{
Align, Background, Color, Font, HorizontalAlignment, Length,
VerticalAlignment,
};
-pub use iced_futures::Command;
+pub use iced_futures::{futures, Command};
pub use style::Style;
pub use subscription::Subscription;
pub use widget::*;
diff --git a/winit/Cargo.toml b/winit/Cargo.toml
index ba6d5229..cef41e9c 100644
--- a/winit/Cargo.toml
+++ b/winit/Cargo.toml
@@ -16,17 +16,11 @@ debug = []
[dependencies]
winit = { version = "0.20.0-alpha3", git = "https://github.com/hecrj/winit", rev = "709808eb4e69044705fcb214bcc30556db761405"}
log = "0.4"
-futures = "0.3"
[dependencies.iced_native]
version = "0.1.0-alpha"
path = "../native"
-[dependencies.iced_futures]
-version = "0.1.0-alpha"
-path = "../futures"
-features = ["thread-pool"]
-
[dependencies.window_clipboard]
git = "https://github.com/hecrj/window_clipboard"
rev = "22c6dd6c04cd05d528029b50a30c56417cd4bebf"
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 076ac092..4b21a930 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -1,10 +1,9 @@
use crate::{
conversion,
input::{keyboard, mouse},
- window, Cache, Clipboard, Command, Debug, Element, Event, Mode,
- MouseCursor, Proxy, Settings, Size, Subscription, UserInterface,
+ window, Cache, Clipboard, Command, Debug, Element, Event, Executor, Mode,
+ MouseCursor, Proxy, Runtime, Settings, Size, Subscription, UserInterface,
};
-use iced_native::Runtime;
/// An interactive, native cross-platform application.
///
@@ -20,6 +19,11 @@ pub trait Application: Sized {
/// [`Application`]: trait.Application.html
type Renderer: window::Renderer;
+ /// The [`Executor`] that will run commands and subscriptions.
+ ///
+ /// [`Executor`]: trait.Executor.html
+ type Executor: Executor;
+
/// The type of __messages__ your [`Application`] will produce.
///
/// [`Application`]: trait.Application.html
@@ -110,13 +114,13 @@ pub trait Application: Sized {
debug.startup_started();
let event_loop = EventLoop::with_user_event();
+ let mut external_messages = Vec::new();
+
let mut runtime = {
- let thread_pool = futures::executor::ThreadPool::new()
- .expect("Create thread pool");
+ let executor = Self::Executor::new().expect("Create executor");
- Runtime::new(thread_pool, Proxy::new(event_loop.create_proxy()))
+ Runtime::new(executor, Proxy::new(event_loop.create_proxy()))
};
- let mut external_messages = Vec::new();
let (mut application, init_command) = Self::new();
runtime.spawn(init_command);
diff --git a/winit/src/proxy.rs b/winit/src/proxy.rs
index 7e8dee98..cff9df33 100644
--- a/winit/src/proxy.rs
+++ b/winit/src/proxy.rs
@@ -1,4 +1,4 @@
-use futures::{
+use iced_native::futures::{
task::{Context, Poll},
Sink,
};