summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-01-14 19:43:06 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-01-14 19:43:06 +0700
commit810b445f8d2f429e9ad07625f9b67dba09783d7a (patch)
treebab7664ef79113a94ccaf48c8eed9ab9e433b40b /native
parentb7bc169120d3447ead238e974007027a5152d341 (diff)
downloadiced-810b445f8d2f429e9ad07625f9b67dba09783d7a.tar.gz
iced-810b445f8d2f429e9ad07625f9b67dba09783d7a.tar.bz2
iced-810b445f8d2f429e9ad07625f9b67dba09783d7a.zip
Rewrite `events` and `events_with` with a new `Runner` abstraction
Diffstat (limited to 'native')
-rw-r--r--native/src/subscription.rs72
-rw-r--r--native/src/subscription/events.rs35
2 files changed, 62 insertions, 45 deletions
diff --git a/native/src/subscription.rs b/native/src/subscription.rs
index 2950879c..7a1c5852 100644
--- a/native/src/subscription.rs
+++ b/native/src/subscription.rs
@@ -1,8 +1,12 @@
//! Listen to external events in your application.
use crate::event::{self, Event};
use crate::Hasher;
+
+use iced_futures::futures::{self, Stream};
use iced_futures::BoxStream;
+use std::hash::Hash;
+
/// A request to listen to external events.
///
/// Besides performing async actions on demand with [`Command`], most
@@ -29,20 +33,14 @@ pub type Tracker =
pub use iced_futures::subscription::Recipe;
-mod events;
-
-use events::Events;
-
/// Returns a [`Subscription`] to all the runtime events.
///
/// This subscription will notify your application of any [`Event`] that was
/// not captured by any widget.
pub fn events() -> Subscription<Event> {
- Subscription::from_recipe(Events {
- f: |event, status| match status {
- event::Status::Ignored => Some(event),
- event::Status::Captured => None,
- },
+ events_with(|event, status| match status {
+ event::Status::Ignored => Some(event),
+ event::Status::Captured => None,
})
}
@@ -60,5 +58,59 @@ pub fn events_with<Message>(
where
Message: 'static + Send,
{
- Subscription::from_recipe(Events { f })
+ #[derive(Debug, Clone, Copy, Hash)]
+ struct Events(u64);
+
+ let hash = {
+ use std::hash::Hasher as _;
+
+ let mut hasher = Hasher::default();
+
+ f.hash(&mut hasher);
+
+ hasher.finish()
+ };
+
+ Subscription::from_recipe(Runner {
+ initial: Events(hash),
+ spawn: move |_, events| {
+ use futures::future;
+ use futures::stream::StreamExt;
+
+ events.filter_map(move |(event, status)| {
+ future::ready(f(event, status))
+ })
+ },
+ })
+}
+
+struct Runner<T, F, S, Message>
+where
+ F: FnOnce(T, EventStream) -> S,
+ S: Stream<Item = Message>,
+{
+ initial: T,
+ spawn: F,
+}
+
+impl<T, S, F, Message> Recipe<Hasher, (Event, event::Status)>
+ for Runner<T, F, S, Message>
+where
+ T: Clone + Hash + 'static,
+ F: FnOnce(T, EventStream) -> S,
+ S: Stream<Item = Message> + Send + 'static,
+{
+ type Output = Message;
+
+ fn hash(&self, state: &mut Hasher) {
+ std::any::TypeId::of::<T>().hash(state);
+
+ self.initial.hash(state);
+ }
+
+ fn stream(self: Box<Self>, input: EventStream) -> BoxStream<Self::Output> {
+ use futures::stream::StreamExt;
+
+ (self.spawn)(self.initial, input).boxed()
+ }
}
diff --git a/native/src/subscription/events.rs b/native/src/subscription/events.rs
deleted file mode 100644
index ca143bb3..00000000
--- a/native/src/subscription/events.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use crate::event::{self, Event};
-use crate::subscription::{EventStream, Recipe};
-use crate::Hasher;
-use iced_futures::futures::future;
-use iced_futures::futures::StreamExt;
-use iced_futures::BoxStream;
-
-pub struct Events<Message> {
- pub(super) f: fn(Event, event::Status) -> Option<Message>,
-}
-
-impl<Message> Recipe<Hasher, (Event, event::Status)> for Events<Message>
-where
- Message: 'static + Send,
-{
- type Output = Message;
-
- fn hash(&self, state: &mut Hasher) {
- use std::hash::Hash;
-
- struct Marker;
- std::any::TypeId::of::<Marker>().hash(state);
- self.f.hash(state);
- }
-
- fn stream(
- self: Box<Self>,
- event_stream: EventStream,
- ) -> BoxStream<Self::Output> {
- let stream = event_stream.filter_map(move |(event, status)| {
- future::ready((self.f)(event, status))
- });
- iced_futures::boxed_stream(stream)
- }
-}