diff options
Diffstat (limited to 'winit/src')
| -rw-r--r-- | winit/src/application.rs | 57 | ||||
| -rw-r--r-- | winit/src/lib.rs | 3 | ||||
| -rw-r--r-- | winit/src/proxy.rs | 57 | ||||
| -rw-r--r-- | winit/src/subscription.rs | 97 | 
4 files changed, 77 insertions, 137 deletions
| diff --git a/winit/src/application.rs b/winit/src/application.rs index a14924ac..076ac092 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -1,9 +1,10 @@  use crate::{      conversion,      input::{keyboard, mouse}, -    subscription, window, Cache, Clipboard, Command, Debug, Element, Event, -    Mode, MouseCursor, Settings, Size, Subscription, UserInterface, +    window, Cache, Clipboard, Command, Debug, Element, Event, Mode, +    MouseCursor, Proxy, Settings, Size, Subscription, UserInterface,  }; +use iced_native::Runtime;  /// An interactive, native cross-platform application.  /// @@ -109,17 +110,19 @@ pub trait Application: Sized {          debug.startup_started();          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 subscription_pool = subscription::Pool::new(); +        let mut runtime = { +            let thread_pool = futures::executor::ThreadPool::new() +                .expect("Create thread pool"); + +            Runtime::new(thread_pool, Proxy::new(event_loop.create_proxy())) +        };          let mut external_messages = Vec::new();          let (mut application, init_command) = Self::new(); -        spawn(init_command, &mut thread_pool, &proxy); +        runtime.spawn(init_command);          let subscription = application.subscription(); -        subscription_pool.update(subscription, &mut thread_pool, &proxy); +        runtime.track(subscription);          let mut title = application.title();          let mut mode = application.mode(); @@ -212,7 +215,7 @@ pub trait Application: Sized {                  events                      .iter()                      .cloned() -                    .for_each(|event| subscription_pool.broadcast_event(event)); +                    .for_each(|event| runtime.broadcast(event));                  let mut messages = user_interface.update(                      &renderer, @@ -241,17 +244,15 @@ pub trait Application: Sized {                          debug.log_message(&message);                          debug.update_started(); -                        let command = application.update(message); -                        spawn(command, &mut thread_pool, &proxy); +                        let command = +                            runtime.enter(|| application.update(message)); +                        runtime.spawn(command);                          debug.update_finished();                      } -                    let subscription = application.subscription(); -                    subscription_pool.update( -                        subscription, -                        &mut thread_pool, -                        &proxy, -                    ); +                    let subscription = +                        runtime.enter(|| application.subscription()); +                    runtime.track(subscription);                      // Update window title                      let new_title = application.title(); @@ -463,28 +464,6 @@ fn to_physical(size: winit::dpi::LogicalSize, dpi: f64) -> (u16, u16) {      )  } -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); -    } -} -  // As defined in: http://www.unicode.org/faq/private_use.html  // TODO: Remove once https://github.com/rust-windowing/winit/pull/1254 lands  fn is_private_use_character(c: char) -> bool { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 9000f977..056ae8f0 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -31,7 +31,7 @@ pub mod settings;  mod application;  mod clipboard;  mod mode; -mod subscription; +mod proxy;  // We disable debug capabilities on release builds unless the `debug` feature  // is explicitly enabled. @@ -48,3 +48,4 @@ pub use settings::Settings;  use clipboard::Clipboard;  use debug::Debug; +use proxy::Proxy; diff --git a/winit/src/proxy.rs b/winit/src/proxy.rs new file mode 100644 index 00000000..7e8dee98 --- /dev/null +++ b/winit/src/proxy.rs @@ -0,0 +1,57 @@ +use futures::{ +    task::{Context, Poll}, +    Sink, +}; +use std::pin::Pin; + +pub struct Proxy<Message: 'static> { +    raw: winit::event_loop::EventLoopProxy<Message>, +} + +impl<Message: 'static> Clone for Proxy<Message> { +    fn clone(&self) -> Self { +        Self { +            raw: self.raw.clone(), +        } +    } +} + +impl<Message: 'static> Proxy<Message> { +    pub fn new(raw: winit::event_loop::EventLoopProxy<Message>) -> Self { +        Self { raw } +    } +} + +impl<Message: 'static> Sink<Message> for Proxy<Message> { +    type Error = core::convert::Infallible; + +    fn poll_ready( +        self: Pin<&mut Self>, +        _cx: &mut Context<'_>, +    ) -> Poll<Result<(), Self::Error>> { +        Poll::Ready(Ok(())) +    } + +    fn start_send( +        self: Pin<&mut Self>, +        message: Message, +    ) -> Result<(), Self::Error> { +        let _ = self.raw.send_event(message); + +        Ok(()) +    } + +    fn poll_flush( +        self: Pin<&mut Self>, +        _cx: &mut Context<'_>, +    ) -> Poll<Result<(), Self::Error>> { +        Poll::Ready(Ok(())) +    } + +    fn poll_close( +        self: Pin<&mut Self>, +        _cx: &mut Context<'_>, +    ) -> Poll<Result<(), Self::Error>> { +        Poll::Ready(Ok(())) +    } +} diff --git a/winit/src/subscription.rs b/winit/src/subscription.rs deleted file mode 100644 index bad68d55..00000000 --- a/winit/src/subscription.rs +++ /dev/null @@ -1,97 +0,0 @@ -use iced_native::{Event, Hasher, Subscription}; -use std::collections::HashMap; - -pub struct Pool { -    alive: HashMap<u64, Handle>, -} - -pub struct Handle { -    _cancel: futures::channel::oneshot::Sender<()>, -    listener: Option<futures::channel::mpsc::Sender<Event>>, -} - -impl Pool { -    pub fn new() -> Self { -        Self { -            alive: HashMap::new(), -        } -    } - -    pub fn update<Message: Send>( -        &mut self, -        subscription: Subscription<Message>, -        thread_pool: &mut futures::executor::ThreadPool, -        proxy: &winit::event_loop::EventLoopProxy<Message>, -    ) { -        use futures::{future::FutureExt, stream::StreamExt}; - -        let recipes = subscription.recipes(); -        let mut alive = std::collections::HashSet::new(); - -        for recipe in recipes { -            let id = { -                use std::hash::Hasher as _; - -                let mut hasher = Hasher::default(); -                recipe.hash(&mut hasher); - -                hasher.finish() -            }; - -            let _ = alive.insert(id); - -            if !self.alive.contains_key(&id) { -                let (cancel, cancelled) = futures::channel::oneshot::channel(); - -                // TODO: Use bus if/when it supports async -                let (event_sender, event_receiver) = -                    futures::channel::mpsc::channel(100); - -                let stream = recipe.stream(event_receiver.boxed()); -                let proxy = proxy.clone(); - -                let future = futures::future::select( -                    cancelled, -                    stream.for_each(move |message| { -                        proxy -                            .send_event(message) -                            .expect("Send subscription result to event loop"); - -                        futures::future::ready(()) -                    }), -                ) -                .map(|_| ()); - -                thread_pool.spawn_ok(future); - -                let _ = self.alive.insert( -                    id, -                    Handle { -                        _cancel: cancel, -                        listener: if event_sender.is_closed() { -                            None -                        } else { -                            Some(event_sender) -                        }, -                    }, -                ); -            } -        } - -        self.alive.retain(|id, _| alive.contains(&id)); -    } - -    pub fn broadcast_event(&mut self, event: Event) { -        self.alive -            .values_mut() -            .filter_map(|connection| connection.listener.as_mut()) -            .for_each(|listener| { -                if let Err(error) = listener.try_send(event.clone()) { -                    log::error!( -                        "Error sending event to subscription: {:?}", -                        error -                    ); -                } -            }); -    } -} | 
