Loadable no longer stores a loader.

This commit is contained in:
Filipe Rodrigues 2025-09-17 09:05:20 +01:00
parent cf9a1b9e82
commit 4e99f2b55b
Signed by: zenithsiz
SSH Key Fingerprint: SHA256:Mb5ppb3Sh7IarBO/sBTXLHbYEOz37hJAlslLQPPAPaU
2 changed files with 31 additions and 65 deletions

View File

@ -1,33 +1,25 @@
//! Loadable
// Imports
use {
crate::AppError,
core::{fmt, task::Poll},
futures::FutureExt,
std::task,
};
use {crate::AppError, core::task::Poll, futures::FutureExt, std::task};
/// Loadable value
pub struct Loadable<T, F> {
#[derive(Debug)]
pub struct Loadable<T> {
/// Current value, if any
value: Option<T>,
/// Loading task
task: Option<tokio::task::JoinHandle<T>>,
/// Loader
loader: F,
}
impl<T, F> Loadable<T, F> {
impl<T> Loadable<T> {
/// Creates a new, empty, loadable
#[must_use]
pub fn new(loader: F) -> Self {
pub fn new() -> Self {
Self {
value: None,
task: None,
loader,
task: None,
}
}
@ -52,11 +44,14 @@ impl<T, F> Loadable<T, F> {
self.value.take()
}
/// Tries to load the inner value
pub fn try_load<Args>(&mut self, args: Args) -> Option<&mut T>
/// Tries to load the inner value.
///
/// If the value isn't loading, `spawn_task` is called to spawn a
/// task that loads the value
pub fn try_load<F>(&mut self, spawn_task: F) -> Option<&mut T>
where
T: Send + 'static,
F: Loader<Args, T>,
F: FnOnce() -> Result<tokio::task::JoinHandle<T>, AppError>,
{
// If the value is loaded, we're done
// Note: We can't use if-let due to a borrow-checker limitation
@ -88,7 +83,7 @@ impl<T, F> Loadable<T, F> {
}
},
None => {
match self.loader.spawn(args) {
match spawn_task() {
Ok(task) => self.task = Some(task),
Err(err) => tracing::warn!("Unable to spawn task: {}", err.pretty()),
}
@ -99,18 +94,8 @@ impl<T, F> Loadable<T, F> {
}
}
/// Loader trait
pub trait Loader<Args, T> {
/// Spawns the loader future
fn spawn(&mut self, args: Args) -> Result<tokio::task::JoinHandle<T>, AppError>;
}
impl<T: fmt::Debug, F> fmt::Debug for Loadable<T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Loadable")
.field("value", &self.value)
.field("task", &self.task)
.field("loader", &"..")
.finish()
impl<T> Default for Loadable<T> {
fn default() -> Self {
Self::new()
}
}

View File

@ -7,7 +7,7 @@ use {
image::{DynamicImage, imageops},
std::{self, mem, path::Path, sync::Arc},
tokio::sync::OnceCell,
zsw_util::{AppError, Loadable, loadable::Loader},
zsw_util::{AppError, Loadable},
zsw_wgpu::Wgpu,
zutil_cloned::cloned,
};
@ -47,7 +47,7 @@ pub struct PanelFadeImages {
pub image_bind_group: OnceCell<wgpu::BindGroup>,
/// Next image
pub next_image: Loadable<ImageLoadRes, NextImageLoader>,
pub next_image: Loadable<ImageLoadRes>,
}
/// Panel's fade image
@ -63,14 +63,6 @@ pub struct PanelFadeImage {
pub path: Arc<Path>,
}
/// Arguments to the next image loader
pub struct NextImageArgs {
playlist_pos: usize,
path: Arc<Path>,
max_image_size: u32,
}
impl PanelFadeImages {
/// Creates a new panel
#[must_use]
@ -81,7 +73,7 @@ impl PanelFadeImages {
next: None,
image_sampler: OnceCell::new(),
image_bind_group: OnceCell::new(),
next_image: Loadable::new(NextImageLoader),
next_image: Loadable::new(),
}
}
@ -240,10 +232,18 @@ impl PanelFadeImages {
let max_image_size = wgpu.device.limits().max_texture_dimension_2d;
self.next_image.try_load(NextImageArgs {
playlist_pos,
path,
max_image_size,
self.next_image.try_load(|| {
tokio::task::Builder::new()
.name(&format!("Load image {path:?}"))
.spawn_blocking(move || {
let image_res = self::load(&path, max_image_size);
ImageLoadRes {
path,
playlist_pos,
image_res,
}
})
.context("Unable to spawn task")
})
}
@ -253,25 +253,6 @@ impl PanelFadeImages {
}
}
/// Next image loader
pub struct NextImageLoader;
impl Loader<NextImageArgs, ImageLoadRes> for NextImageLoader {
fn spawn(&mut self, args: NextImageArgs) -> Result<tokio::task::JoinHandle<ImageLoadRes>, AppError> {
tokio::task::Builder::new()
.name(&format!("Load image {:?}", args.path))
.spawn_blocking(move || {
let image_res = self::load(&args.path, args.max_image_size);
ImageLoadRes {
path: args.path,
playlist_pos: args.playlist_pos,
image_res,
}
})
.context("Unable to spawn task")
}
}
/// Image slot
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
enum Slot {