Support async actions in iced_winit
This commit is contained in:
parent
e640b87590
commit
02c20e6202
@ -1,12 +1,12 @@
|
||||
use iced::{
|
||||
button, scrollable, Align, Application, Button, Container, Element, Image,
|
||||
Length, Scrollable, Text,
|
||||
button, scrollable, Align, Application, Button, Command, Container,
|
||||
Element, Image, Length, Scrollable, Text,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
Example::default().run()
|
||||
Example::run()
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@ -25,16 +25,22 @@ pub enum Message {
|
||||
impl Application for Example {
|
||||
type Message = Message;
|
||||
|
||||
fn new() -> (Example, Command<Message>) {
|
||||
(Example::default(), Command::none())
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
String::from("Scroll - Iced")
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) {
|
||||
fn update(&mut self, message: Message) -> Command<Message> {
|
||||
match message {
|
||||
Message::AddItem => {
|
||||
self.item_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
}
|
||||
|
||||
fn view(&mut self) -> Element<Message> {
|
||||
|
@ -1,11 +1,11 @@
|
||||
use iced::{
|
||||
button, scrollable, text::HorizontalAlignment, text_input, Align,
|
||||
Application, Background, Button, Checkbox, Color, Column, Container,
|
||||
Element, Font, Length, Row, Scrollable, Text, TextInput,
|
||||
Application, Background, Button, Checkbox, Color, Column, Command,
|
||||
Container, Element, Font, Length, Row, Scrollable, Text, TextInput,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
Todos::default().run()
|
||||
Todos::run()
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@ -29,11 +29,15 @@ pub enum Message {
|
||||
impl Application for Todos {
|
||||
type Message = Message;
|
||||
|
||||
fn new() -> (Todos, Command<Message>) {
|
||||
(Todos::default(), Command::none())
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
String::from("Todos - Iced")
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) {
|
||||
fn update(&mut self, message: Message) -> Command<Message> {
|
||||
match message {
|
||||
Message::InputChanged(value) => {
|
||||
self.input_value = value;
|
||||
@ -58,6 +62,8 @@ impl Application for Todos {
|
||||
}
|
||||
|
||||
dbg!(self);
|
||||
|
||||
Command::none()
|
||||
}
|
||||
|
||||
fn view(&mut self) -> Element<Message> {
|
||||
|
@ -1,13 +1,14 @@
|
||||
use iced::{
|
||||
button, scrollable, slider, text::HorizontalAlignment, text_input,
|
||||
Application, Background, Button, Checkbox, Color, Column, Container,
|
||||
Element, Image, Length, Radio, Row, Scrollable, Slider, Text, TextInput,
|
||||
Application, Background, Button, Checkbox, Color, Column, Command,
|
||||
Container, Element, Image, Length, Radio, Row, Scrollable, Slider, Text,
|
||||
TextInput,
|
||||
};
|
||||
|
||||
pub fn main() {
|
||||
env_logger::init();
|
||||
|
||||
Tour::new().run()
|
||||
Tour::run()
|
||||
}
|
||||
|
||||
pub struct Tour {
|
||||
@ -18,26 +19,27 @@ pub struct Tour {
|
||||
debug: bool,
|
||||
}
|
||||
|
||||
impl Tour {
|
||||
pub fn new() -> Tour {
|
||||
Tour {
|
||||
steps: Steps::new(),
|
||||
scroll: scrollable::State::new(),
|
||||
back_button: button::State::new(),
|
||||
next_button: button::State::new(),
|
||||
debug: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Application for Tour {
|
||||
type Message = Message;
|
||||
|
||||
fn new() -> (Tour, Command<Message>) {
|
||||
(
|
||||
Tour {
|
||||
steps: Steps::new(),
|
||||
scroll: scrollable::State::new(),
|
||||
back_button: button::State::new(),
|
||||
next_button: button::State::new(),
|
||||
debug: true,
|
||||
},
|
||||
Command::none(),
|
||||
)
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
format!("{} - Iced", self.steps.title())
|
||||
}
|
||||
|
||||
fn update(&mut self, event: Message) {
|
||||
fn update(&mut self, event: Message) -> Command<Message> {
|
||||
match event {
|
||||
Message::BackPressed => {
|
||||
self.steps.go_back();
|
||||
@ -49,6 +51,8 @@ impl Application for Tour {
|
||||
self.steps.update(step_msg, &mut self.debug);
|
||||
}
|
||||
}
|
||||
|
||||
Command::none()
|
||||
}
|
||||
|
||||
fn view(&mut self) -> Element<Message> {
|
||||
|
22
src/lib.rs
22
src/lib.rs
@ -4,21 +4,23 @@ mod platform;
|
||||
|
||||
pub use platform::*;
|
||||
|
||||
pub trait Application {
|
||||
type Message: std::fmt::Debug;
|
||||
pub trait Application: Sized {
|
||||
type Message: std::fmt::Debug + Send;
|
||||
|
||||
fn new() -> (Self, Command<Self::Message>);
|
||||
|
||||
fn title(&self) -> String;
|
||||
|
||||
fn update(&mut self, message: Self::Message);
|
||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
|
||||
|
||||
fn view(&mut self) -> Element<Self::Message>;
|
||||
|
||||
fn run(self)
|
||||
fn run()
|
||||
where
|
||||
Self: 'static + Sized,
|
||||
{
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
iced_winit::Application::run(Instance(self));
|
||||
<Instance<Self> as iced_winit::Application>::run();
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
iced_web::Application::run(Instance(self));
|
||||
@ -35,12 +37,18 @@ where
|
||||
type Renderer = Renderer;
|
||||
type Message = A::Message;
|
||||
|
||||
fn new() -> (Self, Command<A::Message>) {
|
||||
let (app, command) = A::new();
|
||||
|
||||
(Instance(app), command)
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
self.0.title()
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Message) {
|
||||
self.0.update(message);
|
||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
|
||||
self.0.update(message)
|
||||
}
|
||||
|
||||
fn view(&mut self) -> Element<Self::Message> {
|
||||
|
@ -2,8 +2,8 @@ pub use iced_wgpu::{Primitive, Renderer};
|
||||
|
||||
pub use iced_winit::{
|
||||
button, scrollable, slider, text, text_input, winit, Align, Background,
|
||||
Checkbox, Color, Font, Image, Length, Radio, Scrollable, Slider, Text,
|
||||
TextInput,
|
||||
Checkbox, Color, Command, Font, Image, Length, Radio, Scrollable, Slider,
|
||||
Text, TextInput,
|
||||
};
|
||||
|
||||
pub type Element<'a, Message> = iced_winit::Element<'a, Message, Renderer>;
|
||||
|
@ -13,4 +13,5 @@ debug = []
|
||||
[dependencies]
|
||||
iced_native = { version = "0.1.0-alpha", path = "../native" }
|
||||
winit = { version = "0.20.0-alpha3", git = "https://github.com/rust-windowing/winit", rev = "709808eb4e69044705fcb214bcc30556db761405"}
|
||||
futures = { version = "0.3", features = ["thread-pool"] }
|
||||
log = "0.4"
|
||||
|
@ -2,24 +2,26 @@ use crate::{
|
||||
conversion,
|
||||
input::{keyboard, mouse},
|
||||
renderer::{Target, Windowed},
|
||||
Cache, Container, Debug, Element, Event, Length, MouseCursor,
|
||||
Cache, Command, Container, Debug, Element, Event, Length, MouseCursor,
|
||||
UserInterface,
|
||||
};
|
||||
|
||||
pub trait Application {
|
||||
pub trait Application: Sized {
|
||||
type Renderer: Windowed;
|
||||
|
||||
type Message: std::fmt::Debug;
|
||||
type Message: std::fmt::Debug + Send;
|
||||
|
||||
fn new() -> (Self, Command<Self::Message>);
|
||||
|
||||
fn title(&self) -> String;
|
||||
|
||||
fn update(&mut self, message: Self::Message);
|
||||
fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
|
||||
|
||||
fn view(&mut self) -> Element<Self::Message, Self::Renderer>;
|
||||
|
||||
fn run(mut self)
|
||||
fn run()
|
||||
where
|
||||
Self: 'static + Sized,
|
||||
Self: 'static,
|
||||
{
|
||||
use winit::{
|
||||
event::{self, WindowEvent},
|
||||
@ -28,10 +30,18 @@ pub trait Application {
|
||||
};
|
||||
|
||||
let mut debug = Debug::new();
|
||||
let mut title = self.title();
|
||||
|
||||
debug.startup_started();
|
||||
let event_loop = EventLoop::new();
|
||||
let event_loop = EventLoop::with_user_event();
|
||||
let proxy = event_loop.create_proxy();
|
||||
let mut thread_pool =
|
||||
futures::executor::ThreadPool::new().expect("Create thread pool");
|
||||
let mut external_messages = Vec::new();
|
||||
|
||||
let (mut application, init_command) = Self::new();
|
||||
spawn(init_command, &mut thread_pool, &proxy);
|
||||
|
||||
let mut title = application.title();
|
||||
|
||||
// TODO: Ask for window settings and configure this properly
|
||||
let window = WindowBuilder::new()
|
||||
@ -59,7 +69,7 @@ pub trait Application {
|
||||
|
||||
debug.layout_started();
|
||||
let user_interface = UserInterface::build(
|
||||
document(&mut self, size, &mut debug),
|
||||
document(&mut application, size, &mut debug),
|
||||
Cache::default(),
|
||||
&mut renderer,
|
||||
);
|
||||
@ -85,15 +95,16 @@ pub trait Application {
|
||||
// handled.
|
||||
debug.layout_started();
|
||||
let mut user_interface = UserInterface::build(
|
||||
document(&mut self, size, &mut debug),
|
||||
document(&mut application, size, &mut debug),
|
||||
cache.take().unwrap(),
|
||||
&mut renderer,
|
||||
);
|
||||
debug.layout_finished();
|
||||
|
||||
debug.event_processing_started();
|
||||
let messages =
|
||||
let mut messages =
|
||||
user_interface.update(&renderer, events.drain(..));
|
||||
messages.extend(external_messages.drain(..));
|
||||
debug.event_processing_finished();
|
||||
|
||||
if messages.is_empty() {
|
||||
@ -113,12 +124,14 @@ pub trait Application {
|
||||
debug.log_message(&message);
|
||||
|
||||
debug.update_started();
|
||||
self.update(message);
|
||||
let command = application.update(message);
|
||||
|
||||
spawn(command, &mut thread_pool, &proxy);
|
||||
debug.update_finished();
|
||||
}
|
||||
|
||||
// Update window title
|
||||
let new_title = self.title();
|
||||
let new_title = application.title();
|
||||
|
||||
if title != new_title {
|
||||
window.set_title(&new_title);
|
||||
@ -128,7 +141,7 @@ pub trait Application {
|
||||
|
||||
debug.layout_started();
|
||||
let user_interface = UserInterface::build(
|
||||
document(&mut self, size, &mut debug),
|
||||
document(&mut application, size, &mut debug),
|
||||
temp_cache,
|
||||
&mut renderer,
|
||||
);
|
||||
@ -143,6 +156,9 @@ pub trait Application {
|
||||
|
||||
window.request_redraw();
|
||||
}
|
||||
event::Event::UserEvent(message) => {
|
||||
external_messages.push(message);
|
||||
}
|
||||
event::Event::RedrawRequested(_) => {
|
||||
debug.render_started();
|
||||
|
||||
@ -288,3 +304,25 @@ where
|
||||
.height(Length::Units(size.height.round() as u16))
|
||||
.into()
|
||||
}
|
||||
|
||||
fn spawn<Message: Send>(
|
||||
command: Command<Message>,
|
||||
thread_pool: &mut futures::executor::ThreadPool,
|
||||
proxy: &winit::event_loop::EventLoopProxy<Message>,
|
||||
) {
|
||||
use futures::FutureExt;
|
||||
|
||||
let futures = command.futures();
|
||||
|
||||
for future in futures {
|
||||
let proxy = proxy.clone();
|
||||
|
||||
let future = future.map(move |message| {
|
||||
proxy
|
||||
.send_event(message)
|
||||
.expect("Send command result to event loop");
|
||||
});
|
||||
|
||||
thread_pool.spawn_ok(future);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user