Introduce subscription::Event
... and remove `PlatformSpecific` from `Event`
This commit is contained in:
parent
83296a73eb
commit
5d7dcf417c
13 changed files with 156 additions and 129 deletions
|
|
@ -23,27 +23,6 @@ pub enum Event {
|
|||
|
||||
/// A touch event
|
||||
Touch(touch::Event),
|
||||
|
||||
/// A platform specific event
|
||||
PlatformSpecific(PlatformSpecific),
|
||||
}
|
||||
|
||||
/// A platform specific event
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum PlatformSpecific {
|
||||
/// A MacOS specific event
|
||||
MacOS(MacOS),
|
||||
}
|
||||
|
||||
/// Describes an event specific to MacOS
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum MacOS {
|
||||
/// Triggered when the app receives an URL from the system
|
||||
///
|
||||
/// _**Note:** For this event to be triggered, the executable needs to be properly [bundled]!_
|
||||
///
|
||||
/// [bundled]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW19
|
||||
ReceivedUrl(String),
|
||||
}
|
||||
|
||||
/// The status of an [`Event`] after being processed.
|
||||
|
|
|
|||
1
core/src/program.rs
Normal file
1
core/src/program.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
use crate::window;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use iced::event::{self, Event};
|
||||
use iced::event;
|
||||
use iced::widget::{center, text};
|
||||
use iced::{Element, Subscription};
|
||||
|
||||
|
|
@ -15,27 +15,20 @@ struct App {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Message {
|
||||
EventOccurred(Event),
|
||||
UrlReceived(String),
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn update(&mut self, message: Message) {
|
||||
match message {
|
||||
Message::EventOccurred(event) => {
|
||||
if let Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
|
||||
url,
|
||||
)),
|
||||
) = event
|
||||
{
|
||||
self.url = Some(url);
|
||||
}
|
||||
Message::UrlReceived(url) => {
|
||||
self.url = Some(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
event::listen().map(Message::EventOccurred)
|
||||
event::listen_url().map(Message::UrlReceived)
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<Message> {
|
||||
|
|
|
|||
|
|
@ -32,11 +32,17 @@ where
|
|||
#[derive(Hash)]
|
||||
struct EventsWith;
|
||||
|
||||
subscription::filter_map((EventsWith, f), move |event, status, window| {
|
||||
match event {
|
||||
Event::Window(window::Event::RedrawRequested(_)) => None,
|
||||
_ => f(event, status, window),
|
||||
subscription::filter_map((EventsWith, f), move |event| match event {
|
||||
subscription::Event::Interaction {
|
||||
event: Event::Window(window::Event::RedrawRequested(_)),
|
||||
..
|
||||
}
|
||||
| subscription::Event::PlatformSpecific(_) => None,
|
||||
subscription::Event::Interaction {
|
||||
window,
|
||||
event,
|
||||
status,
|
||||
} => f(event, status, window),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -54,5 +60,32 @@ where
|
|||
#[derive(Hash)]
|
||||
struct RawEvents;
|
||||
|
||||
subscription::filter_map((RawEvents, f), f)
|
||||
subscription::filter_map((RawEvents, f), move |event| match event {
|
||||
subscription::Event::Interaction {
|
||||
window,
|
||||
event,
|
||||
status,
|
||||
} => f(event, status, window),
|
||||
subscription::Event::PlatformSpecific(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a [`Subscription`] that notifies of custom application URL
|
||||
/// received from the system.
|
||||
///
|
||||
/// _**Note:** Currently, it only triggers on macOS and the executable needs to be properly [bundled]!_
|
||||
///
|
||||
/// [bundled]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW19
|
||||
pub fn listen_url() -> Subscription<String> {
|
||||
#[derive(Hash)]
|
||||
struct ListenUrl;
|
||||
|
||||
subscription::filter_map(ListenUrl, move |event| match event {
|
||||
subscription::Event::PlatformSpecific(
|
||||
subscription::PlatformSpecific::MacOS(
|
||||
subscription::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
) => Some(url),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! Listen to keyboard events.
|
||||
use crate::core;
|
||||
use crate::core::event;
|
||||
use crate::core::keyboard::{Event, Key, Modifiers};
|
||||
use crate::subscription::{self, Subscription};
|
||||
use crate::MaybeSend;
|
||||
|
|
@ -18,16 +19,14 @@ where
|
|||
#[derive(Hash)]
|
||||
struct OnKeyPress;
|
||||
|
||||
subscription::filter_map((OnKeyPress, f), move |event, status, _window| {
|
||||
match (event, status) {
|
||||
(
|
||||
core::Event::Keyboard(Event::KeyPressed {
|
||||
key, modifiers, ..
|
||||
}),
|
||||
core::event::Status::Ignored,
|
||||
) => f(key, modifiers),
|
||||
_ => None,
|
||||
}
|
||||
subscription::filter_map((OnKeyPress, f), move |event| match event {
|
||||
subscription::Event::Interaction {
|
||||
event:
|
||||
core::Event::Keyboard(Event::KeyPressed { key, modifiers, .. }),
|
||||
status: event::Status::Ignored,
|
||||
..
|
||||
} => f(key, modifiers),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -45,18 +44,13 @@ where
|
|||
#[derive(Hash)]
|
||||
struct OnKeyRelease;
|
||||
|
||||
subscription::filter_map(
|
||||
(OnKeyRelease, f),
|
||||
move |event, status, _window| match (event, status) {
|
||||
(
|
||||
core::Event::Keyboard(Event::KeyReleased {
|
||||
key,
|
||||
modifiers,
|
||||
..
|
||||
}),
|
||||
core::event::Status::Ignored,
|
||||
) => f(key, modifiers),
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
subscription::filter_map((OnKeyRelease, f), move |event| match event {
|
||||
subscription::Event::Interaction {
|
||||
event:
|
||||
core::Event::Keyboard(Event::KeyReleased { key, modifiers, .. }),
|
||||
status: event::Status::Ignored,
|
||||
..
|
||||
} => f(key, modifiers),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
//! Run commands and keep track of subscriptions.
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::window;
|
||||
use crate::subscription;
|
||||
use crate::{BoxFuture, BoxStream, Executor, MaybeSend};
|
||||
|
||||
|
|
@ -128,12 +126,7 @@ where
|
|||
/// See [`Tracker::broadcast`] to learn more.
|
||||
///
|
||||
/// [`Tracker::broadcast`]: subscription::Tracker::broadcast
|
||||
pub fn broadcast(
|
||||
&mut self,
|
||||
event: Event,
|
||||
status: event::Status,
|
||||
window: window::Id,
|
||||
) {
|
||||
self.subscriptions.broadcast(event, status, window);
|
||||
pub fn broadcast(&mut self, event: subscription::Event) {
|
||||
self.subscriptions.broadcast(event);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ mod tracker;
|
|||
|
||||
pub use tracker::Tracker;
|
||||
|
||||
use crate::core::event::{self, Event};
|
||||
use crate::core::event;
|
||||
use crate::core::window;
|
||||
use crate::futures::{Future, Stream};
|
||||
use crate::{BoxStream, MaybeSend};
|
||||
|
|
@ -13,10 +13,48 @@ use futures::never::Never;
|
|||
use std::any::TypeId;
|
||||
use std::hash::Hash;
|
||||
|
||||
/// A subscription event.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Event {
|
||||
/// A user interacted with a user interface in a window.
|
||||
Interaction {
|
||||
/// The window holding the interface of the interaction.
|
||||
window: window::Id,
|
||||
/// The [`Event`] describing the interaction.
|
||||
///
|
||||
/// [`Event`]: event::Event
|
||||
event: event::Event,
|
||||
|
||||
/// The [`event::Status`] of the interaction.
|
||||
status: event::Status,
|
||||
},
|
||||
|
||||
/// A platform specific event.
|
||||
PlatformSpecific(PlatformSpecific),
|
||||
}
|
||||
|
||||
/// A platform specific event
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum PlatformSpecific {
|
||||
/// A MacOS specific event
|
||||
MacOS(MacOS),
|
||||
}
|
||||
|
||||
/// Describes an event specific to MacOS
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum MacOS {
|
||||
/// Triggered when the app receives an URL from the system
|
||||
///
|
||||
/// _**Note:** For this event to be triggered, the executable needs to be properly [bundled]!_
|
||||
///
|
||||
/// [bundled]: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW19
|
||||
ReceivedUrl(String),
|
||||
}
|
||||
|
||||
/// A stream of runtime events.
|
||||
///
|
||||
/// It is the input of a [`Subscription`].
|
||||
pub type EventStream = BoxStream<(Event, event::Status, window::Id)>;
|
||||
pub type EventStream = BoxStream<Event>;
|
||||
|
||||
/// The hasher used for identifying subscriptions.
|
||||
pub type Hasher = rustc_hash::FxHasher;
|
||||
|
|
@ -290,9 +328,7 @@ where
|
|||
pub(crate) fn filter_map<I, F, Message>(id: I, f: F) -> Subscription<Message>
|
||||
where
|
||||
I: Hash + 'static,
|
||||
F: Fn(Event, event::Status, window::Id) -> Option<Message>
|
||||
+ MaybeSend
|
||||
+ 'static,
|
||||
F: Fn(Event) -> Option<Message> + MaybeSend + 'static,
|
||||
Message: 'static + MaybeSend,
|
||||
{
|
||||
Subscription::from_recipe(Runner {
|
||||
|
|
@ -301,9 +337,7 @@ where
|
|||
use futures::future;
|
||||
use futures::stream::StreamExt;
|
||||
|
||||
events.filter_map(move |(event, status, window)| {
|
||||
future::ready(f(event, status, window))
|
||||
})
|
||||
events.filter_map(move |event| future::ready(f(event)))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
use crate::core::event::{self, Event};
|
||||
use crate::core::window;
|
||||
use crate::subscription::{Hasher, Recipe};
|
||||
use crate::subscription::{Event, Hasher, Recipe};
|
||||
use crate::{BoxFuture, MaybeSend};
|
||||
|
||||
use futures::channel::mpsc;
|
||||
|
|
@ -24,9 +22,7 @@ pub struct Tracker {
|
|||
#[derive(Debug)]
|
||||
pub struct Execution {
|
||||
_cancel: futures::channel::oneshot::Sender<()>,
|
||||
listener: Option<
|
||||
futures::channel::mpsc::Sender<(Event, event::Status, window::Id)>,
|
||||
>,
|
||||
listener: Option<futures::channel::mpsc::Sender<Event>>,
|
||||
}
|
||||
|
||||
impl Tracker {
|
||||
|
|
@ -142,19 +138,12 @@ impl Tracker {
|
|||
/// currently open.
|
||||
///
|
||||
/// [`Recipe::stream`]: crate::subscription::Recipe::stream
|
||||
pub fn broadcast(
|
||||
&mut self,
|
||||
event: Event,
|
||||
status: event::Status,
|
||||
window: window::Id,
|
||||
) {
|
||||
pub fn broadcast(&mut self, event: Event) {
|
||||
self.subscriptions
|
||||
.values_mut()
|
||||
.filter_map(|connection| connection.listener.as_mut())
|
||||
.for_each(|listener| {
|
||||
if let Err(error) =
|
||||
listener.try_send((event.clone(), status, window))
|
||||
{
|
||||
if let Err(error) = listener.try_send(event.clone()) {
|
||||
log::warn!(
|
||||
"Error sending event to subscription: {error:?}"
|
||||
);
|
||||
|
|
|
|||
|
|
@ -236,8 +236,10 @@ pub mod font {
|
|||
|
||||
pub mod event {
|
||||
//! Handle events of a user interface.
|
||||
pub use crate::core::event::{Event, MacOS, PlatformSpecific, Status};
|
||||
pub use iced_futures::event::{listen, listen_raw, listen_with};
|
||||
pub use crate::core::event::{Event, Status};
|
||||
pub use iced_futures::event::{
|
||||
listen, listen_raw, listen_url, listen_with,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod keyboard {
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ where
|
|||
core::Event::Keyboard(keyboard_event) => {
|
||||
Some(Event::Keyboard(keyboard_event))
|
||||
}
|
||||
_ => None,
|
||||
core::Event::Window(_) => None,
|
||||
};
|
||||
|
||||
if let Some(canvas_event) = canvas_event {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ where
|
|||
core::Event::Window(window::Event::RedrawRequested(instant)) => {
|
||||
Some(Event::RedrawRequested(instant))
|
||||
}
|
||||
_ => None,
|
||||
core::Event::Window(_) => None,
|
||||
};
|
||||
|
||||
if let Some(custom_shader_event) = custom_shader_event {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ use crate::core::widget::operation;
|
|||
use crate::core::window;
|
||||
use crate::core::{Color, Event, Point, Size, Theme};
|
||||
use crate::futures::futures;
|
||||
use crate::futures::{Executor, Runtime, Subscription};
|
||||
use crate::futures::subscription::{self, Subscription};
|
||||
use crate::futures::{Executor, Runtime};
|
||||
use crate::graphics;
|
||||
use crate::graphics::compositor::{self, Compositor};
|
||||
use crate::runtime::clipboard;
|
||||
|
|
@ -574,12 +575,10 @@ async fn run_instance<A, E, C>(
|
|||
event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
)) => {
|
||||
use crate::core::event;
|
||||
|
||||
events.push(Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
|
||||
url,
|
||||
)),
|
||||
runtime.broadcast(subscription::Event::PlatformSpecific(
|
||||
subscription::PlatformSpecific::MacOS(
|
||||
subscription::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
));
|
||||
}
|
||||
event::Event::UserEvent(message) => {
|
||||
|
|
@ -650,11 +649,11 @@ async fn run_instance<A, E, C>(
|
|||
_ => ControlFlow::Wait,
|
||||
});
|
||||
|
||||
runtime.broadcast(
|
||||
redraw_event,
|
||||
core::event::Status::Ignored,
|
||||
window::Id::MAIN,
|
||||
);
|
||||
runtime.broadcast(subscription::Event::Interaction {
|
||||
window: window::Id::MAIN,
|
||||
event: redraw_event,
|
||||
status: core::event::Status::Ignored,
|
||||
});
|
||||
|
||||
debug.draw_started();
|
||||
let new_mouse_interaction = user_interface.draw(
|
||||
|
|
@ -744,7 +743,11 @@ async fn run_instance<A, E, C>(
|
|||
for (event, status) in
|
||||
events.drain(..).zip(statuses.into_iter())
|
||||
{
|
||||
runtime.broadcast(event, status, window::Id::MAIN);
|
||||
runtime.broadcast(subscription::Event::Interaction {
|
||||
window: window::Id::MAIN,
|
||||
event,
|
||||
status,
|
||||
});
|
||||
}
|
||||
|
||||
if !messages.is_empty()
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ use crate::futures::futures::channel::oneshot;
|
|||
use crate::futures::futures::executor;
|
||||
use crate::futures::futures::task;
|
||||
use crate::futures::futures::{Future, StreamExt};
|
||||
use crate::futures::{Executor, Runtime, Subscription};
|
||||
use crate::futures::subscription::{self, Subscription};
|
||||
use crate::futures::{Executor, Runtime};
|
||||
use crate::graphics;
|
||||
use crate::graphics::{compositor, Compositor};
|
||||
use crate::multi_window::window_manager::WindowManager;
|
||||
|
|
@ -585,16 +586,13 @@ async fn run_instance<A, E, C>(
|
|||
event::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
) => {
|
||||
use crate::core::event;
|
||||
|
||||
events.push((
|
||||
window::Id::MAIN,
|
||||
event::Event::PlatformSpecific(
|
||||
event::PlatformSpecific::MacOS(
|
||||
event::MacOS::ReceivedUrl(url),
|
||||
runtime.broadcast(
|
||||
subscription::Event::PlatformSpecific(
|
||||
subscription::PlatformSpecific::MacOS(
|
||||
subscription::MacOS::ReceivedUrl(url),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
}
|
||||
event::Event::UserEvent(message) => {
|
||||
messages.push(message);
|
||||
|
|
@ -655,11 +653,11 @@ async fn run_instance<A, E, C>(
|
|||
window.mouse_interaction = new_mouse_interaction;
|
||||
}
|
||||
|
||||
runtime.broadcast(
|
||||
redraw_event.clone(),
|
||||
core::event::Status::Ignored,
|
||||
id,
|
||||
);
|
||||
runtime.broadcast(subscription::Event::Interaction {
|
||||
window: id,
|
||||
event: redraw_event,
|
||||
status: core::event::Status::Ignored,
|
||||
});
|
||||
|
||||
let _ = control_sender.start_send(Control::ChangeFlow(
|
||||
match ui_state {
|
||||
|
|
@ -866,15 +864,23 @@ async fn run_instance<A, E, C>(
|
|||
.into_iter()
|
||||
.zip(statuses.into_iter())
|
||||
{
|
||||
runtime.broadcast(event, status, id);
|
||||
runtime.broadcast(
|
||||
subscription::Event::Interaction {
|
||||
window: id,
|
||||
event,
|
||||
status,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (id, event) in events.drain(..) {
|
||||
runtime.broadcast(
|
||||
event,
|
||||
core::event::Status::Ignored,
|
||||
id,
|
||||
subscription::Event::Interaction {
|
||||
window: id,
|
||||
event,
|
||||
status: core::event::Status::Ignored,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue