feat: parallel loading
This commit is contained in:
parent
eaf0c674ab
commit
e179b824c8
3 changed files with 45 additions and 3 deletions
|
|
@ -4,6 +4,7 @@ use std::{
|
|||
env,
|
||||
path::{Path, PathBuf},
|
||||
process,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use iced::{
|
||||
|
|
@ -11,16 +12,23 @@ use iced::{
|
|||
keyboard, theme, widget, window,
|
||||
};
|
||||
use ignore::{WalkBuilder, types::TypesBuilder};
|
||||
use image::ImageError;
|
||||
use rayon::iter::{ParallelBridge, ParallelIterator};
|
||||
use rfd::AsyncFileDialog;
|
||||
|
||||
use crate::{SUPPORTED_TYPES, app::maybe_image::MaybeImage};
|
||||
use crate::{
|
||||
SUPPORTED_TYPES,
|
||||
app::maybe_image::{MaybeImage, handle_from_image},
|
||||
utils,
|
||||
};
|
||||
|
||||
mod maybe_image;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Message {
|
||||
LoadImage(PathBuf),
|
||||
ImageLoaded(Result<(PathBuf, widget::image::Handle), Arc<ImageError>>),
|
||||
|
||||
UnloadImage(PathBuf),
|
||||
|
||||
OpenImage(PathBuf),
|
||||
|
|
@ -58,10 +66,34 @@ impl State {
|
|||
fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::LoadImage(path) => {
|
||||
self.images.entry(path.clone()).and_modify(|e| {
|
||||
*e = MaybeImage::Loaded(widget::image::Handle::from_path(path))
|
||||
let path_clone = path.clone();
|
||||
|
||||
let (task, handle) = Task::perform(
|
||||
async {
|
||||
utils::load_image(&path)
|
||||
.map(|img| (path, handle_from_image(img)))
|
||||
.map_err(Arc::new)
|
||||
},
|
||||
Message::ImageLoaded,
|
||||
)
|
||||
.abortable();
|
||||
|
||||
self.images.entry(path_clone).and_modify(|e| {
|
||||
*e = MaybeImage::Loading(handle);
|
||||
});
|
||||
|
||||
return task;
|
||||
}
|
||||
Message::ImageLoaded(result) => {
|
||||
self.error = result.as_ref().err().map(|e| e.to_string());
|
||||
|
||||
if let Ok((path, handle)) = result {
|
||||
self.images
|
||||
.entry(path)
|
||||
.and_modify(|e| *e = MaybeImage::Loaded(handle));
|
||||
}
|
||||
}
|
||||
|
||||
Message::UnloadImage(path) => {
|
||||
self.images.entry(path).and_modify(MaybeImage::unload);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
mod app;
|
||||
mod utils;
|
||||
|
||||
const SUPPORTED_TYPES: &[&str; 20] = &[
|
||||
"*.png", "*.PNG", "*.jpg", "*.JPG", "*.jpeg", "*.JPEG", "*.avif", "*.jxl", "*.bmp", "*.exr",
|
||||
|
|
|
|||
9
src/utils.rs
Normal file
9
src/utils.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
use std::path::Path;
|
||||
|
||||
use image::{DynamicImage, ImageReader, ImageResult};
|
||||
|
||||
pub fn load_image(path: impl AsRef<Path>) -> ImageResult<DynamicImage> {
|
||||
Ok(DynamicImage::from_decoder(
|
||||
ImageReader::open(path)?.into_decoder()?,
|
||||
)?)
|
||||
}
|
||||
Loading…
Reference in a new issue