diff options
Diffstat (limited to '')
| -rw-r--r-- | runtime/src/clipboard.rs | 10 | ||||
| -rw-r--r-- | runtime/src/font.rs | 5 | ||||
| -rw-r--r-- | runtime/src/lib.rs | 5 | ||||
| -rw-r--r-- | runtime/src/task.rs | 163 | ||||
| -rw-r--r-- | runtime/src/window.rs | 52 | 
5 files changed, 118 insertions, 117 deletions
| diff --git a/runtime/src/clipboard.rs b/runtime/src/clipboard.rs index 19950d01..a02cc011 100644 --- a/runtime/src/clipboard.rs +++ b/runtime/src/clipboard.rs @@ -1,7 +1,7 @@  //! Access the clipboard.  use crate::core::clipboard::Kind;  use crate::futures::futures::channel::oneshot; -use crate::Task; +use crate::task::{self, Task};  /// A clipboard action to be performed by some [`Task`].  /// @@ -27,7 +27,7 @@ pub enum Action {  /// Read the current contents of the clipboard.  pub fn read() -> Task<Option<String>> { -    Task::oneshot(|channel| { +    task::oneshot(|channel| {          crate::Action::Clipboard(Action::Read {              target: Kind::Standard,              channel, @@ -37,7 +37,7 @@ pub fn read() -> Task<Option<String>> {  /// Read the current contents of the primary clipboard.  pub fn read_primary() -> Task<Option<String>> { -    Task::oneshot(|channel| { +    task::oneshot(|channel| {          crate::Action::Clipboard(Action::Read {              target: Kind::Primary,              channel, @@ -47,7 +47,7 @@ pub fn read_primary() -> Task<Option<String>> {  /// Write the given contents to the clipboard.  pub fn write<T>(contents: String) -> Task<T> { -    Task::effect(crate::Action::Clipboard(Action::Write { +    task::effect(crate::Action::Clipboard(Action::Write {          target: Kind::Standard,          contents,      })) @@ -55,7 +55,7 @@ pub fn write<T>(contents: String) -> Task<T> {  /// Write the given contents to the primary clipboard.  pub fn write_primary<Message>(contents: String) -> Task<Message> { -    Task::effect(crate::Action::Clipboard(Action::Write { +    task::effect(crate::Action::Clipboard(Action::Write {          target: Kind::Primary,          contents,      })) diff --git a/runtime/src/font.rs b/runtime/src/font.rs index d54eb6a8..75fdfc11 100644 --- a/runtime/src/font.rs +++ b/runtime/src/font.rs @@ -1,5 +1,6 @@  //! Load and use fonts. -use crate::{Action, Task}; +use crate::task::{self, Task}; +use crate::Action;  use std::borrow::Cow;  /// An error while loading a font. @@ -8,7 +9,7 @@ pub enum Error {}  /// Load a font from its bytes.  pub fn load(bytes: impl Into<Cow<'static, [u8]>>) -> Task<Result<(), Error>> { -    Task::oneshot(|channel| Action::LoadFont { +    task::oneshot(|channel| Action::LoadFont {          bytes: bytes.into(),          channel,      }) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 7e46593a..f27657d1 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -15,14 +15,13 @@ pub mod keyboard;  pub mod overlay;  pub mod program;  pub mod system; +pub mod task;  pub mod user_interface;  pub mod window;  #[cfg(feature = "multi-window")]  pub mod multi_window; -mod task; -  // We disable debug capabilities on release builds unless the `debug` feature  // is explicitly enabled.  #[cfg(feature = "debug")] @@ -127,5 +126,5 @@ where  /// This will normally close any application windows and  /// terminate the runtime loop.  pub fn exit<T>() -> Task<T> { -    Task::effect(Action::Exit) +    task::effect(Action::Exit)  } diff --git a/runtime/src/task.rs b/runtime/src/task.rs index b8a83d6d..e037c403 100644 --- a/runtime/src/task.rs +++ b/runtime/src/task.rs @@ -1,3 +1,4 @@ +//! Create runtime tasks.  use crate::core::widget;  use crate::futures::futures::channel::mpsc;  use crate::futures::futures::channel::oneshot; @@ -29,24 +30,6 @@ impl<T> Task<T> {          Self::future(future::ready(value))      } -    /// Creates a new [`Task`] that runs the given [`Future`] and produces -    /// its output. -    pub fn future(future: impl Future<Output = T> + MaybeSend + 'static) -> Self -    where -        T: 'static, -    { -        Self::stream(stream::once(future)) -    } - -    /// Creates a new [`Task`] that runs the given [`Stream`] and produces -    /// each of its items. -    pub fn stream(stream: impl Stream<Item = T> + MaybeSend + 'static) -> Self -    where -        T: 'static, -    { -        Self(Some(boxed_stream(stream.map(Action::Output)))) -    } -      /// Creates a [`Task`] that runs the given [`Future`] to completion and maps its      /// output with the given closure.      pub fn perform<A>( @@ -72,75 +55,33 @@ impl<T> Task<T> {          Self::stream(stream.map(f))      } -    /// Combines the given tasks and produces a single [`Task`] that will run all of them -    /// in parallel. -    pub fn batch(tasks: impl IntoIterator<Item = Self>) -> Self -    where -        T: 'static, -    { -        Self(Some(boxed_stream(stream::select_all( -            tasks.into_iter().filter_map(|task| task.0), -        )))) -    } - -    /// Creates a new [`Task`] that runs the given [`widget::Operation`] and produces +    /// Creates a new [`Task`] that runs the given [`Future`] and produces      /// its output. -    pub fn widget(operation: impl widget::Operation<T> + 'static) -> Task<T> +    pub fn future(future: impl Future<Output = T> + MaybeSend + 'static) -> Self      where -        T: Send + 'static, +        T: 'static,      { -        Self::channel(move |sender| { -            let operation = -                widget::operation::map(Box::new(operation), move |value| { -                    let _ = sender.clone().try_send(value); -                }); - -            Action::Widget(Box::new(operation)) -        }) +        Self::stream(stream::once(future))      } -    /// Creates a new [`Task`] that executes the [`Action`] returned by the closure and -    /// produces the value fed to the [`oneshot::Sender`]. -    pub fn oneshot(f: impl FnOnce(oneshot::Sender<T>) -> Action<T>) -> Task<T> +    /// Creates a new [`Task`] that runs the given [`Stream`] and produces +    /// each of its items. +    pub fn stream(stream: impl Stream<Item = T> + MaybeSend + 'static) -> Self      where -        T: MaybeSend + 'static, +        T: 'static,      { -        let (sender, receiver) = oneshot::channel(); - -        let action = f(sender); - -        Self(Some(boxed_stream( -            stream::once(async move { action }).chain( -                receiver.into_stream().filter_map(|result| async move { -                    Some(Action::Output(result.ok()?)) -                }), -            ), -        ))) +        Self(Some(boxed_stream(stream.map(Action::Output))))      } -    /// Creates a new [`Task`] that executes the [`Action`] returned by the closure and -    /// produces the values fed to the [`mpsc::Sender`]. -    pub fn channel(f: impl FnOnce(mpsc::Sender<T>) -> Action<T>) -> Task<T> +    /// Combines the given tasks and produces a single [`Task`] that will run all of them +    /// in parallel. +    pub fn batch(tasks: impl IntoIterator<Item = Self>) -> Self      where -        T: MaybeSend + 'static, +        T: 'static,      { -        let (sender, receiver) = mpsc::channel(1); - -        let action = f(sender); - -        Self(Some(boxed_stream( -            stream::once(async move { action }) -                .chain(receiver.map(|result| Action::Output(result))), -        ))) -    } - -    /// Creates a new [`Task`] that executes the given [`Action`] and produces no output. -    pub fn effect(action: impl Into<Action<Never>>) -> Self { -        let action = action.into(); - -        Self(Some(boxed_stream(stream::once(async move { -            action.output().expect_err("no output") -        })))) +        Self(Some(boxed_stream(stream::select_all( +            tasks.into_iter().filter_map(|task| task.0), +        ))))      }      /// Maps the output of a [`Task`] with the given closure. @@ -235,11 +176,6 @@ impl<T> Task<T> {              ))),          }      } - -    /// Returns the underlying [`Stream`] of the [`Task`]. -    pub fn into_stream(self) -> Option<BoxStream<Action<T>>> { -        self.0 -    }  }  impl<T> Task<Option<T>> { @@ -283,3 +219,68 @@ where          Self::none()      }  } + +/// Creates a new [`Task`] that runs the given [`widget::Operation`] and produces +/// its output. +pub fn widget<T>(operation: impl widget::Operation<T> + 'static) -> Task<T> +where +    T: Send + 'static, +{ +    channel(move |sender| { +        let operation = +            widget::operation::map(Box::new(operation), move |value| { +                let _ = sender.clone().try_send(value); +            }); + +        Action::Widget(Box::new(operation)) +    }) +} + +/// Creates a new [`Task`] that executes the [`Action`] returned by the closure and +/// produces the value fed to the [`oneshot::Sender`]. +pub fn oneshot<T>(f: impl FnOnce(oneshot::Sender<T>) -> Action<T>) -> Task<T> +where +    T: MaybeSend + 'static, +{ +    let (sender, receiver) = oneshot::channel(); + +    let action = f(sender); + +    Task(Some(boxed_stream( +        stream::once(async move { action }).chain( +            receiver.into_stream().filter_map(|result| async move { +                Some(Action::Output(result.ok()?)) +            }), +        ), +    ))) +} + +/// Creates a new [`Task`] that executes the [`Action`] returned by the closure and +/// produces the values fed to the [`mpsc::Sender`]. +pub fn channel<T>(f: impl FnOnce(mpsc::Sender<T>) -> Action<T>) -> Task<T> +where +    T: MaybeSend + 'static, +{ +    let (sender, receiver) = mpsc::channel(1); + +    let action = f(sender); + +    Task(Some(boxed_stream( +        stream::once(async move { action }) +            .chain(receiver.map(|result| Action::Output(result))), +    ))) +} + +/// Creates a new [`Task`] that executes the given [`Action`] and produces no output. +pub fn effect<T>(action: impl Into<Action<Never>>) -> Task<T> { +    let action = action.into(); + +    Task(Some(boxed_stream(stream::once(async move { +        action.output().expect_err("no output") +    })))) +} + +/// Returns the underlying [`Stream`] of the [`Task`]. +pub fn into_stream<T>(task: Task<T>) -> Option<BoxStream<Action<T>>> { +    task.0 +} diff --git a/runtime/src/window.rs b/runtime/src/window.rs index 3e53dd55..815827d1 100644 --- a/runtime/src/window.rs +++ b/runtime/src/window.rs @@ -11,7 +11,7 @@ use crate::core::{Point, Size};  use crate::futures::event;  use crate::futures::futures::channel::oneshot;  use crate::futures::Subscription; -use crate::Task; +use crate::task::{self, Task};  pub use raw_window_handle; @@ -210,99 +210,99 @@ pub fn close_requests() -> Subscription<Id> {  pub fn open(settings: Settings) -> Task<Id> {      let id = Id::unique(); -    Task::oneshot(|channel| { +    task::oneshot(|channel| {          crate::Action::Window(Action::Open(id, settings, channel))      })  }  /// Closes the window with `id`.  pub fn close<T>(id: Id) -> Task<T> { -    Task::effect(crate::Action::Window(Action::Close(id))) +    task::effect(crate::Action::Window(Action::Close(id)))  }  /// Gets the window [`Id`] of the oldest window.  pub fn get_oldest() -> Task<Option<Id>> { -    Task::oneshot(|channel| crate::Action::Window(Action::GetOldest(channel))) +    task::oneshot(|channel| crate::Action::Window(Action::GetOldest(channel)))  }  /// Gets the window [`Id`] of the latest window.  pub fn get_latest() -> Task<Option<Id>> { -    Task::oneshot(|channel| crate::Action::Window(Action::GetLatest(channel))) +    task::oneshot(|channel| crate::Action::Window(Action::GetLatest(channel)))  }  /// Begins dragging the window while the left mouse button is held.  pub fn drag<T>(id: Id) -> Task<T> { -    Task::effect(crate::Action::Window(Action::Drag(id))) +    task::effect(crate::Action::Window(Action::Drag(id)))  }  /// Resizes the window to the given logical dimensions.  pub fn resize<T>(id: Id, new_size: Size) -> Task<T> { -    Task::effect(crate::Action::Window(Action::Resize(id, new_size))) +    task::effect(crate::Action::Window(Action::Resize(id, new_size)))  }  /// Get the window's size in logical dimensions.  pub fn get_size(id: Id) -> Task<Size> { -    Task::oneshot(move |channel| { +    task::oneshot(move |channel| {          crate::Action::Window(Action::GetSize(id, channel))      })  }  /// Gets the maximized state of the window with the given [`Id`].  pub fn get_maximized(id: Id) -> Task<bool> { -    Task::oneshot(move |channel| { +    task::oneshot(move |channel| {          crate::Action::Window(Action::GetMaximized(id, channel))      })  }  /// Maximizes the window.  pub fn maximize<T>(id: Id, maximized: bool) -> Task<T> { -    Task::effect(crate::Action::Window(Action::Maximize(id, maximized))) +    task::effect(crate::Action::Window(Action::Maximize(id, maximized)))  }  /// Gets the minimized state of the window with the given [`Id`].  pub fn get_minimized(id: Id) -> Task<Option<bool>> { -    Task::oneshot(move |channel| { +    task::oneshot(move |channel| {          crate::Action::Window(Action::GetMinimized(id, channel))      })  }  /// Minimizes the window.  pub fn minimize<T>(id: Id, minimized: bool) -> Task<T> { -    Task::effect(crate::Action::Window(Action::Minimize(id, minimized))) +    task::effect(crate::Action::Window(Action::Minimize(id, minimized)))  }  /// Gets the position in logical coordinates of the window with the given [`Id`].  pub fn get_position(id: Id) -> Task<Option<Point>> { -    Task::oneshot(move |channel| { +    task::oneshot(move |channel| {          crate::Action::Window(Action::GetPosition(id, channel))      })  }  /// Moves the window to the given logical coordinates.  pub fn move_to<T>(id: Id, position: Point) -> Task<T> { -    Task::effect(crate::Action::Window(Action::Move(id, position))) +    task::effect(crate::Action::Window(Action::Move(id, position)))  }  /// Changes the [`Mode`] of the window.  pub fn change_mode<T>(id: Id, mode: Mode) -> Task<T> { -    Task::effect(crate::Action::Window(Action::ChangeMode(id, mode))) +    task::effect(crate::Action::Window(Action::ChangeMode(id, mode)))  }  /// Gets the current [`Mode`] of the window.  pub fn get_mode(id: Id) -> Task<Mode> { -    Task::oneshot(move |channel| { +    task::oneshot(move |channel| {          crate::Action::Window(Action::GetMode(id, channel))      })  }  /// Toggles the window to maximized or back.  pub fn toggle_maximize<T>(id: Id) -> Task<T> { -    Task::effect(crate::Action::Window(Action::ToggleMaximize(id))) +    task::effect(crate::Action::Window(Action::ToggleMaximize(id)))  }  /// Toggles the window decorations.  pub fn toggle_decorations<T>(id: Id) -> Task<T> { -    Task::effect(crate::Action::Window(Action::ToggleDecorations(id))) +    task::effect(crate::Action::Window(Action::ToggleDecorations(id)))  }  /// Request user attention to the window. This has no effect if the application @@ -315,7 +315,7 @@ pub fn request_user_attention<T>(      id: Id,      user_attention: Option<UserAttention>,  ) -> Task<T> { -    Task::effect(crate::Action::Window(Action::RequestUserAttention( +    task::effect(crate::Action::Window(Action::RequestUserAttention(          id,          user_attention,      ))) @@ -328,32 +328,32 @@ pub fn request_user_attention<T>(  /// you are certain that's what the user wants. Focus stealing can cause an extremely disruptive  /// user experience.  pub fn gain_focus<T>(id: Id) -> Task<T> { -    Task::effect(crate::Action::Window(Action::GainFocus(id))) +    task::effect(crate::Action::Window(Action::GainFocus(id)))  }  /// Changes the window [`Level`].  pub fn change_level<T>(id: Id, level: Level) -> Task<T> { -    Task::effect(crate::Action::Window(Action::ChangeLevel(id, level))) +    task::effect(crate::Action::Window(Action::ChangeLevel(id, level)))  }  /// Show the [system menu] at cursor position.  ///  /// [system menu]: https://en.wikipedia.org/wiki/Common_menus_in_Microsoft_Windows#System_menu  pub fn show_system_menu<T>(id: Id) -> Task<T> { -    Task::effect(crate::Action::Window(Action::ShowSystemMenu(id))) +    task::effect(crate::Action::Window(Action::ShowSystemMenu(id)))  }  /// Gets an identifier unique to the window, provided by the underlying windowing system. This is  /// not to be confused with [`Id`].  pub fn get_raw_id<Message>(id: Id) -> Task<u64> { -    Task::oneshot(|channel| { +    task::oneshot(|channel| {          crate::Action::Window(Action::GetRawId(id, channel))      })  }  /// Changes the [`Icon`] of the window.  pub fn change_icon<T>(id: Id, icon: Icon) -> Task<T> { -    Task::effect(crate::Action::Window(Action::ChangeIcon(id, icon))) +    task::effect(crate::Action::Window(Action::ChangeIcon(id, icon)))  }  /// Runs the given callback with the native window handle for the window with the given id. @@ -366,7 +366,7 @@ pub fn run_with_handle<T>(  where      T: Send + 'static,  { -    Task::oneshot(move |channel| { +    task::oneshot(move |channel| {          crate::Action::Window(Action::RunWithHandle(              id,              Box::new(move |handle| { @@ -378,7 +378,7 @@ where  /// Captures a [`Screenshot`] from the window.  pub fn screenshot(id: Id) -> Task<Screenshot> { -    Task::oneshot(move |channel| { +    task::oneshot(move |channel| {          crate::Action::Window(Action::Screenshot(id, channel))      })  } | 
