Draft multi-threaded image rendering in iced_wgpu
This commit is contained in:
parent
92888a3639
commit
cb8d2710da
22 changed files with 886 additions and 305 deletions
|
|
@ -18,7 +18,7 @@ use iced::{
|
|||
Subscription, Task, Theme, color,
|
||||
};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
fn main() -> iced::Result {
|
||||
iced::application::timed(
|
||||
|
|
@ -35,6 +35,8 @@ fn main() -> iced::Result {
|
|||
struct Gallery {
|
||||
images: Vec<Image>,
|
||||
previews: HashMap<Id, Preview>,
|
||||
visible: HashSet<Id>,
|
||||
downloaded: HashSet<Id>,
|
||||
viewer: Viewer,
|
||||
now: Instant,
|
||||
}
|
||||
|
|
@ -43,6 +45,7 @@ struct Gallery {
|
|||
enum Message {
|
||||
ImagesListed(Result<Vec<Image>, Error>),
|
||||
ImagePoppedIn(Id),
|
||||
ImagePoppedOut(Id),
|
||||
ImageDownloaded(Result<Rgba, Error>),
|
||||
ThumbnailDownloaded(Id, Result<Rgba, Error>),
|
||||
ThumbnailHovered(Id, bool),
|
||||
|
|
@ -58,6 +61,8 @@ impl Gallery {
|
|||
Self {
|
||||
images: Vec::new(),
|
||||
previews: HashMap::new(),
|
||||
visible: HashSet::new(),
|
||||
downloaded: HashSet::new(),
|
||||
viewer: Viewer::new(),
|
||||
now: Instant::now(),
|
||||
},
|
||||
|
|
@ -102,6 +107,14 @@ impl Gallery {
|
|||
return Task::none();
|
||||
};
|
||||
|
||||
let _ = self.visible.insert(id);
|
||||
|
||||
if self.downloaded.contains(&id) {
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
let _ = self.downloaded.insert(id);
|
||||
|
||||
Task::sip(
|
||||
image.download(Size::Thumbnail {
|
||||
width: Preview::WIDTH,
|
||||
|
|
@ -111,6 +124,11 @@ impl Gallery {
|
|||
Message::ThumbnailDownloaded.with(id),
|
||||
)
|
||||
}
|
||||
Message::ImagePoppedOut(id) => {
|
||||
let _ = self.visible.remove(&id);
|
||||
|
||||
Task::none()
|
||||
}
|
||||
Message::ImageDownloaded(Ok(rgba)) => {
|
||||
self.viewer.show(rgba, self.now);
|
||||
|
||||
|
|
@ -181,7 +199,17 @@ impl Gallery {
|
|||
let images = self
|
||||
.images
|
||||
.iter()
|
||||
.map(|image| card(image, self.previews.get(&image.id), self.now))
|
||||
.map(|image| {
|
||||
card(
|
||||
image,
|
||||
if self.visible.contains(&image.id) {
|
||||
self.previews.get(&image.id)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
self.now,
|
||||
)
|
||||
})
|
||||
.chain((self.images.len()..=Image::LIMIT).map(|_| placeholder()));
|
||||
|
||||
let gallery = grid(images)
|
||||
|
|
@ -248,7 +276,7 @@ fn card<'a>(
|
|||
.on_enter(Message::ThumbnailHovered(metadata.id, true))
|
||||
.on_exit(Message::ThumbnailHovered(metadata.id, false));
|
||||
|
||||
if let Some(preview) = preview {
|
||||
let card: Element<'_, _> = if let Some(preview) = preview {
|
||||
let is_thumbnail = matches!(preview, Preview::Ready { .. });
|
||||
|
||||
button(card)
|
||||
|
|
@ -257,10 +285,13 @@ fn card<'a>(
|
|||
.style(button::text)
|
||||
.into()
|
||||
} else {
|
||||
sensor(card)
|
||||
.on_show(|_| Message::ImagePoppedIn(metadata.id))
|
||||
.into()
|
||||
}
|
||||
card.into()
|
||||
};
|
||||
|
||||
sensor(card)
|
||||
.on_show(|_| Message::ImagePoppedIn(metadata.id))
|
||||
.on_hide(Message::ImagePoppedOut(metadata.id))
|
||||
.into()
|
||||
}
|
||||
|
||||
fn placeholder<'a>() -> Element<'a, Message> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue