Introduce explicit image::allocate API

This commit is contained in:
Héctor Ramón Jiménez 2025-10-25 00:07:13 +02:00
parent 6fa54f7f6b
commit 23039e758e
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
15 changed files with 355 additions and 51 deletions

24
runtime/src/image.rs Normal file
View file

@ -0,0 +1,24 @@
//! Allocate images explicitly to control presentation.
use crate::core::image::Handle;
use crate::futures::futures::channel::oneshot;
use crate::task::{self, Task};
pub use crate::core::image::Allocation;
/// An image action.
#[derive(Debug)]
pub enum Action {
/// Allocates the given [`Handle`].
Allocate(Handle, oneshot::Sender<Allocation>),
}
/// Allocates an image [`Handle`].
///
/// When you obtain an [`Allocation`] explicitly, you get the guarantee
/// that using a [`Handle`] will draw the corresponding image immediately
/// in the next frame.
pub fn allocate(handle: Handle) -> Task<Allocation> {
task::oneshot(|sender| {
crate::Action::Image(Action::Allocate(handle, sender))
})
}

View file

@ -11,6 +11,7 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
pub mod clipboard;
pub mod font;
pub mod image;
pub mod keyboard;
pub mod system;
pub mod task;
@ -55,6 +56,9 @@ pub enum Action<T> {
/// Run a system action.
System(system::Action),
/// An image action.
Image(image::Action),
/// Recreate all user interfaces and redraw all windows.
Reload,
@ -81,6 +85,7 @@ impl<T> Action<T> {
Action::Clipboard(action) => Err(Action::Clipboard(action)),
Action::Window(action) => Err(Action::Window(action)),
Action::System(action) => Err(Action::System(action)),
Action::Image(action) => Err(Action::Image(action)),
Action::Reload => Err(Action::Reload),
Action::Exit => Err(Action::Exit),
}
@ -105,6 +110,7 @@ where
}
Action::Window(_) => write!(f, "Action::Window"),
Action::System(action) => write!(f, "Action::System({action:?})"),
Action::Image(_) => write!(f, "Action::Image"),
Action::Reload => write!(f, "Action::Reload"),
Action::Exit => write!(f, "Action::Exit"),
}

View file

@ -379,14 +379,16 @@ impl<T, E> Task<Result<T, E>> {
/// The success value is provided to the closure to create the subsequent [`Task`].
pub fn and_then<A>(
self,
f: impl Fn(T) -> Task<A> + MaybeSend + 'static,
) -> Task<A>
f: impl Fn(T) -> Task<Result<A, E>> + MaybeSend + 'static,
) -> Task<Result<A, E>>
where
T: MaybeSend + 'static,
E: MaybeSend + 'static,
A: MaybeSend + 'static,
{
self.then(move |option| option.map_or_else(|_| Task::none(), &f))
self.then(move |result| {
result.map_or_else(|error| Task::done(Err(error)), &f)
})
}
}