Skip to content

Commit

Permalink
Avoid deleting folders and fix X freeze (ArturKovacs#191)
Browse files Browse the repository at this point in the history
* Avoid deleting folders and fix X freeze

* Fix clippy warning

* Fix for not updating the image after deleting one
  • Loading branch information
ArturKovacs authored Apr 16, 2021
1 parent 69b0f6e commit 149961f
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 109 deletions.
67 changes: 67 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ arboard = "1.1.0"
resvg = "0.13.1"
usvg = "0.13.1"
tiny-skia = "0.4.2"
log = "0.4"
env_logger = "0.8"

[dependencies.libavif-image]
version = "0.5.0"
Expand Down
31 changes: 20 additions & 11 deletions src/image_cache/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::fmt;
use std::fs;
use std::path::{Path, PathBuf};

use log::debug;

use super::image_loader::is_file_supported;
use crate::parallel_action::ParallelAction;

Expand Down Expand Up @@ -135,11 +137,8 @@ impl Directory {
Err(Error::Other(format!("Could not find file {:?} in directory {:?}", filename, path)))
}

pub fn curr_filename(&self) -> OsString {
match self.files.get(self.curr_file_idx) {
Some(n) => n.path.file_name().unwrap().to_owned(),
None => OsString::new(),
}
pub fn curr_filename(&self) -> Option<OsString> {
self.files.get(self.curr_file_idx).and_then(|x| x.path.file_name().map(|x| x.to_owned()))
}

pub fn curr_descriptor(&self) -> Option<&DirItem> {
Expand Down Expand Up @@ -216,19 +215,29 @@ impl Directory {

pub fn update_directory(&mut self) -> Result<()> {
let curr_filename = self.curr_filename();
let curr_filename = curr_filename.as_deref();
let curr_index = self.curr_file_idx;
debug!(
"Directory: `update_directory`. Current filename: {:?}, curr_index: {:?}",
curr_filename, curr_index
);
self.collect_directory()?;
for (index, desc) in self.files.iter().enumerate() {
if desc.path.file_name().unwrap() == curr_filename {
self.curr_file_idx = index;
self.set_image_index_from_file_index();
self.check_filter_ready();
return Ok(());
if curr_filename.is_some() {
for (index, desc) in self.files.iter().enumerate() {
if desc.path.file_name() == curr_filename {
debug!("Found file the previously 'current' file in the directory.");
self.curr_file_idx = index;
self.set_image_index_from_file_index();
self.check_filter_ready();
return Ok(());
}
}
}
debug!("Previously 'current' file not found, skipping to next supported.");
// if is_file_supported, preserve index of previous file or its following files
for (index, desc) in self.files.iter().enumerate().skip(curr_index) {
if is_file_supported(&desc.path) {
debug!("Next supported file found. Index {:?}, name {:?}.", index, desc.path);
self.curr_file_idx = index;
self.set_image_index_from_file_index();
self.check_filter_ready();
Expand Down
64 changes: 31 additions & 33 deletions src/image_cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ use std::rc::Rc;
use std::sync::atomic::Ordering;
use std::time::SystemTime;

use log::trace;

use gelatin::glium;

use glium::texture::SrgbTexture2d;

pub mod image_loader;
use self::image_loader::*;
use self::{directory::DirItem, image_loader::*};

mod pending_requests;
use pending_requests::PendingRequests;
Expand Down Expand Up @@ -180,12 +182,16 @@ impl ImageCache {
}
}

pub fn current_filename(&self) -> OsString {
pub fn current_filename(&self) -> Option<OsString> {
self.dir.curr_filename()
}

pub fn current_file_path(&self) -> PathBuf {
self.dir.path().join(self.current_filename())
pub fn current_file_path(&self) -> Option<PathBuf> {
if let Some(filename) = self.current_filename() {
Some(self.dir.path().join(filename))
} else {
None
}
}

/// Returns `None` when the directory hasn't finished filtering image files.
Expand All @@ -198,6 +204,14 @@ impl ImageCache {
self.dir.image_count()
}

fn curr_dir_item(&self) -> Result<DirItem> {
if let Some(desc) = self.dir.curr_descriptor() {
Ok(desc.clone())
} else {
bail!("Could not get the current file descriptor");
}
}

/// Returns tru if and only if the current image has been fully loaded and it has a single frame.
pub fn loaded_still_image(&self) -> bool {
if let Some(desc) = self.dir.curr_descriptor() {
Expand Down Expand Up @@ -258,7 +272,9 @@ impl ImageCache {
path: &Path,
frame_id: Option<isize>,
) -> Result<AnimationFrameTexture> {
trace!("Begin `load_specific`");
self.receive_prefetched();
trace!("Receive prefetched done");
let target_file_name;
let parent;
if path.is_dir() {
Expand All @@ -278,15 +294,8 @@ impl ImageCache {
self.current_frame_idx = 0;
}
if self.dir.path() != parent {
let file_path;
let req_id;
if let Some(desc) = self.dir.curr_descriptor() {
file_path = desc.path.clone();
req_id = desc.request_id;
} else {
bail!("Could not got current file descriptor");
}
self.send_request_for_file(file_path, req_id, RequestKind::Priority { display });
let DirItem { path, request_id } = self.curr_dir_item()?;
self.send_request_for_file(path, request_id, RequestKind::Priority { display });
return Err(errors::Error::from_kind(errors::ErrorKind::WaitingOnLoader));
}
if let Some(img_index) = self.dir.curr_img_index() {
Expand All @@ -311,6 +320,7 @@ impl ImageCache {
}

fn refresh_cache(&mut self) {
trace!("Begin `refresh_cache`");
if let Some(curr_index) = self.dir.curr_img_index() {
let cache = mem::take(&mut self.texture_cache);

Expand Down Expand Up @@ -359,12 +369,15 @@ impl ImageCache {
frame_jump_count: isize,
) -> Result<(AnimationFrameTexture, PathBuf)> {
if file_jump_count == 0 {
let _path = self.current_file_path();
// Here, it is possible that the current image was already
// requested but not yet loaded.
let target_frame = self.current_frame_idx as isize + frame_jump_count;
let requested = self.try_getting_requested_image(display, target_frame);
return requested.map(|t| (t, self.current_file_path()));
if let Some(path) = self.current_file_path() {
return requested.map(|t| (t, path));
} else {
bail!("No file is open");
}
} else {
self.current_frame_idx = 0;
}
Expand Down Expand Up @@ -449,14 +462,8 @@ impl ImageCache {
display: &glium::Display,
frame_id: isize,
) -> Result<AnimationFrameTexture> {
let path;
let req_id;
if let Some(desc) = self.dir.curr_descriptor() {
path = desc.path.clone();
req_id = desc.request_id;
} else {
bail!("Could not got current file descriptor");
}
trace!("Begin `try_getting_requested_image` in `image_cache`");
let DirItem { path, request_id: req_id } = self.curr_dir_item()?;

// Check if it's among the prefetched, and upload it, if it is
if let Some(results) = self.pending_requests.take_results(req_id) {
Expand Down Expand Up @@ -503,16 +510,7 @@ impl ImageCache {
PRIORITY_REQUEST_ID.store(req_id, Ordering::SeqCst);
return Err(Error::from_kind(ErrorKind::WaitingOnLoader));
}

let file_path;
let req_id;
if let Some(desc) = self.dir.curr_descriptor() {
file_path = desc.path.clone();
req_id = desc.request_id;
} else {
bail!("Could not got current file descriptor");
}
self.send_request_for_file(file_path, req_id, RequestKind::Priority { display });
self.send_request_for_file(path, req_id, RequestKind::Priority { display });
// If the texture is not in the cache just throw our hands in the air
// and tell the caller that we gotta wait for the loader to load this texture.
Err(Error::from_kind(ErrorKind::WaitingOnLoader))
Expand Down
4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use std::time::{Duration, Instant};
use directories_next::ProjectDirs;
use lazy_static::lazy_static;

use log::trace;

use gelatin::glium::glutin::{
dpi::{PhysicalPosition, PhysicalSize},
event::WindowEvent,
Expand Down Expand Up @@ -68,6 +70,8 @@ static LEFT_TO_PAN: &[u8] = include_bytes!("../resource/use-left-to-pan.png");
// ========================================================
fn main() {
std::panic::set_hook(Box::new(handle_panic::handle_panic));
env_logger::init();
trace!("Starting up. Panic hook set, logger initialized.");

// Load configuration and cache files
let (config_path, cache_path) = get_config_and_cache_paths();
Expand Down
Loading

0 comments on commit 149961f

Please sign in to comment.