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,
|
env,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process,
|
process,
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use iced::{
|
use iced::{
|
||||||
|
|
@ -11,16 +12,23 @@ use iced::{
|
||||||
keyboard, theme, widget, window,
|
keyboard, theme, widget, window,
|
||||||
};
|
};
|
||||||
use ignore::{WalkBuilder, types::TypesBuilder};
|
use ignore::{WalkBuilder, types::TypesBuilder};
|
||||||
|
use image::ImageError;
|
||||||
use rayon::iter::{ParallelBridge, ParallelIterator};
|
use rayon::iter::{ParallelBridge, ParallelIterator};
|
||||||
use rfd::AsyncFileDialog;
|
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;
|
mod maybe_image;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum Message {
|
enum Message {
|
||||||
LoadImage(PathBuf),
|
LoadImage(PathBuf),
|
||||||
|
ImageLoaded(Result<(PathBuf, widget::image::Handle), Arc<ImageError>>),
|
||||||
|
|
||||||
UnloadImage(PathBuf),
|
UnloadImage(PathBuf),
|
||||||
|
|
||||||
OpenImage(PathBuf),
|
OpenImage(PathBuf),
|
||||||
|
|
@ -58,10 +66,34 @@ impl State {
|
||||||
fn update(&mut self, message: Message) -> Task<Message> {
|
fn update(&mut self, message: Message) -> Task<Message> {
|
||||||
match message {
|
match message {
|
||||||
Message::LoadImage(path) => {
|
Message::LoadImage(path) => {
|
||||||
self.images.entry(path.clone()).and_modify(|e| {
|
let path_clone = path.clone();
|
||||||
*e = MaybeImage::Loaded(widget::image::Handle::from_path(path))
|
|
||||||
|
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) => {
|
Message::UnloadImage(path) => {
|
||||||
self.images.entry(path).and_modify(MaybeImage::unload);
|
self.images.entry(path).and_modify(MaybeImage::unload);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
mod app;
|
mod app;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
const SUPPORTED_TYPES: &[&str; 20] = &[
|
const SUPPORTED_TYPES: &[&str; 20] = &[
|
||||||
"*.png", "*.PNG", "*.jpg", "*.JPG", "*.jpeg", "*.JPEG", "*.avif", "*.jxl", "*.bmp", "*.exr",
|
"*.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