summaryrefslogtreecommitdiffstats
path: root/winit/src/application.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-12-05 06:10:13 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-12-05 06:10:13 +0100
commitd575f4541126e2ab25908fe55c6805f16716b2a5 (patch)
tree9d5221fe201b64e2ec649228ebae26be819dbf58 /winit/src/application.rs
parente92ea48e8814b42fc566017db085ca9bdaf3c272 (diff)
downloadiced-d575f4541126e2ab25908fe55c6805f16716b2a5.tar.gz
iced-d575f4541126e2ab25908fe55c6805f16716b2a5.tar.bz2
iced-d575f4541126e2ab25908fe55c6805f16716b2a5.zip
Draft first version of event subscriptions :tada:
Diffstat (limited to 'winit/src/application.rs')
-rw-r--r--winit/src/application.rs79
1 files changed, 77 insertions, 2 deletions
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 3772a667..959e142d 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -2,9 +2,10 @@ use crate::{
conversion,
input::{keyboard, mouse},
renderer::{Target, Windowed},
- Cache, Command, Container, Debug, Element, Event, Length, MouseCursor,
- Settings, UserInterface,
+ subscription, Cache, Command, Container, Debug, Element, Event, Length,
+ MouseCursor, Settings, Subscription, UserInterface,
};
+use std::collections::HashMap;
/// An interactive, native cross-platform application.
///
@@ -57,6 +58,9 @@ pub trait Application: Sized {
/// [`Command`]: struct.Command.html
fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
+ /// TODO
+ fn subscriptions(&self) -> Subscription<Self::Message>;
+
/// Returns the widgets to display in the [`Application`].
///
/// These widgets can produce __messages__ based on user interaction.
@@ -89,11 +93,15 @@ pub trait Application: Sized {
let proxy = event_loop.create_proxy();
let mut thread_pool =
futures::executor::ThreadPool::new().expect("Create thread pool");
+ let mut alive_subscriptions = Subscriptions::new();
let mut external_messages = Vec::new();
let (mut application, init_command) = Self::new();
spawn(init_command, &mut thread_pool, &proxy);
+ let subscriptions = application.subscriptions();
+ alive_subscriptions.update(subscriptions, &mut thread_pool, &proxy);
+
let mut title = application.title();
let window = {
@@ -204,6 +212,13 @@ pub trait Application: Sized {
debug.update_finished();
}
+ let subscriptions = application.subscriptions();
+ alive_subscriptions.update(
+ subscriptions,
+ &mut thread_pool,
+ &proxy,
+ );
+
// Update window title
let new_title = application.title();
@@ -404,6 +419,66 @@ fn spawn<Message: Send>(
}
}
+pub struct Subscriptions {
+ alive: HashMap<u64, Box<dyn subscription::Handle>>,
+}
+
+impl Subscriptions {
+ fn new() -> Self {
+ Self {
+ alive: HashMap::new(),
+ }
+ }
+
+ fn update<Message: Send>(
+ &mut self,
+ subscriptions: Subscription<Message>,
+ thread_pool: &mut futures::executor::ThreadPool,
+ proxy: &winit::event_loop::EventLoopProxy<Message>,
+ ) {
+ use futures::stream::StreamExt;
+
+ let definitions = subscriptions.definitions();
+ let mut alive = std::collections::HashSet::new();
+
+ for definition in definitions {
+ let id = definition.id();
+ let _ = alive.insert(id);
+
+ if !self.alive.contains_key(&id) {
+ let (stream, handle) = definition.stream();
+
+ let proxy =
+ std::sync::Arc::new(std::sync::Mutex::new(proxy.clone()));
+
+ let future = stream.for_each(move |message| {
+ proxy
+ .lock()
+ .expect("Acquire event loop proxy lock")
+ .send_event(message)
+ .expect("Send subscription result to event loop");
+
+ futures::future::ready(())
+ });
+
+ thread_pool.spawn_ok(future);
+
+ let _ = self.alive.insert(id, handle);
+ }
+ }
+
+ self.alive.retain(|id, handle| {
+ let is_still_alive = alive.contains(&id);
+
+ if !is_still_alive {
+ handle.cancel();
+ }
+
+ is_still_alive
+ });
+ }
+}
+
// 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 {