From c9f33126404d2c23c8667bff9c20183151629ab0 Mon Sep 17 00:00:00 2001 From: rabite Date: Wed, 22 Jan 2020 21:45:48 +0100 Subject: save number of visible files instead of recalculating it every time --- src/files.rs | 85 ++++++++++++++++++++++++++++++++++++--------------------- src/fscache.rs | 15 +++++++--- src/listview.rs | 2 +- 3 files changed, 66 insertions(+), 36 deletions(-) diff --git a/src/files.rs b/src/files.rs index ccdaabf..25d21ad 100644 --- a/src/files.rs +++ b/src/files.rs @@ -103,6 +103,7 @@ pub fn tags_loaded() -> HResult<()> { pub struct RefreshPackage { pub new_files: Option>, pub new_buffer: Option>, + pub new_len: usize, } @@ -187,6 +188,9 @@ impl RefreshPackage { // Finally add all new files files.files.extend(new_files); + // Files added, removed, renamed to hidden, etc... + files.recalculate_len(); + let new_len = files.len(); // Need to unpack this to prevent issue with recursive Files type // Also, if no files remain add placeholder let files = if files.len() > 0 { @@ -222,6 +226,7 @@ impl RefreshPackage { RefreshPackage { new_files: Some(files), new_buffer: Some(new_buffer), + new_len: new_len } } } @@ -232,6 +237,7 @@ impl RefreshPackage { pub struct Files { pub directory: File, pub files: Vec, + pub len: usize, #[derivative(Debug="ignore")] #[derivative(PartialEq="ignore")] #[derivative(Hash="ignore")] @@ -273,11 +279,33 @@ impl Dirtyable for Files { } } +use std::default::Default; + +impl Default for Files { + fn default() -> Files { + Files { + directory: File::new_placeholder(Path::new("")).unwrap(), + files: vec![], + len: 0, + pending_events: Arc::new(RwLock::new(vec![])), + refresh: None, + meta_upto: None, + sort: SortBy::Name, + dirs_first: true, + reverse: false, + show_hidden: true, + filter: None, + filter_selected: false, + dirty: DirtyBit::new(), + dirty_meta: AsyncDirtyBit::new(), + } + } +} + impl Files { pub fn new_from_path(path: &Path) -> Result { let direntries: Result, _> = std::fs::read_dir(&path)?.collect(); - let dirty = DirtyBit::new(); let dirty_meta = AsyncDirtyBit::new(); let files: Vec<_> = direntries? @@ -292,29 +320,13 @@ impl Files { }) .collect(); - let mut files = Files { - directory: File::new_from_path(&path, None)?, - files: files, - pending_events: Arc::new(RwLock::new(vec![])), - refresh: None, - meta_upto: None, - sort: SortBy::Name, - dirs_first: true, - reverse: false, - show_hidden: true, - filter: None, - filter_selected: false, - dirty: dirty, - dirty_meta: dirty_meta, - }; - - files.sort(); - + let len = files.len(); + let mut files = Files::default(); + files.directory = File::new_from_path(&path, None)?; + files.len = len; + files.dirty_meta = dirty_meta; - if files.files.len() == 0 { - files.files = vec![File::new_placeholder(&path)?]; - } Ok(files) } @@ -351,9 +363,12 @@ impl Files { })?; } - let mut files = Files { + let len = files.len(); + + let files = Files { directory: File::new_from_path(&path, None)?, files: files, + len: len, pending_events: Arc::new(RwLock::new(vec![])), refresh: None, meta_upto: None, @@ -367,15 +382,13 @@ impl Files { dirty_meta: dirty_meta, }; - files.sort(); - - if files.files.len() == 0 { - files.files = vec![File::new_placeholder(&path)?]; - } - Ok(files) } + pub fn recalculate_len(&mut self) { + self.len = self.iter_files().count(); + } + pub fn get_file_mut(&mut self, index: usize) -> Option<&mut File> { self.iter_files_mut() .nth(index) @@ -511,13 +524,19 @@ impl Files { if self.show_hidden == true && self.len() > 1 { self.remove_placeholder(); + } else { + // avoid doing this twice, since remove_placeholder() does it too + self.recalculate_len(); } } fn remove_placeholder(&mut self) { let dirpath = self.directory.path.clone(); self.find_file_with_path(&dirpath).cloned() - .map(|placeholder| self.files.remove_item(&placeholder)); + .map(|placeholder| { + self.files.remove_item(&placeholder); + self.recalculate_len(); + }); } pub fn ready_to_refresh(&self) -> HResult { @@ -532,6 +551,9 @@ impl Files { refresh.pull_async()?; let mut refresh = refresh.value?; self.files = refresh.new_files.take()?; + if refresh.new_len != self.len() { + self.len = refresh.new_len; + } return Ok(Some(refresh)); } else { self.refresh.replace(refresh); @@ -658,6 +680,7 @@ impl Files { if self.len() == 0 { let placeholder = File::new_placeholder(&self.directory.path).unwrap(); self.files.push(placeholder); + self.len = 1; } self.set_dirty(); @@ -672,7 +695,7 @@ impl Files { } pub fn len(&self) -> usize { - self.iter_files().count() + self.len } pub fn get_selected(&self) -> impl Iterator { diff --git a/src/fscache.rs b/src/fscache.rs index 7f4ce24..9fbc1e8 100644 --- a/src/fscache.rs +++ b/src/fscache.rs @@ -176,6 +176,7 @@ impl FsCache { cache.fs_event_dispatcher.add_target(&dir, &files.pending_events).log(); FsCache::apply_settingss(&cache, &mut files).ok(); + files.sort(); Ok(files) }); Ok((selection, files)) @@ -184,8 +185,7 @@ impl FsCache { pub fn get_files_sync(&self, dir: &File) -> HResult { let files = self.get_files(&dir, Stale::new())?.1; - let mut files = files.run_sync()?; - FsCache::apply_settingss(&self, &mut files).ok(); + let files = files.run_sync()?; let files = FsCache::ensure_not_empty(files)?; Ok(files) } @@ -268,7 +268,6 @@ impl FsCache { } } - files.sort(); let files = FsCache::ensure_not_empty(files)?; Ok(files) }); @@ -285,6 +284,12 @@ impl FsCache { if tab_settings.is_none() { return Ok(()) } let tab_settings = tab_settings?; + if files.show_hidden != tab_settings.dir_settings.show_hidden || + files.filter != tab_settings.dir_settings.filter || + files.filter_selected != tab_settings.dir_settings.filter_selected { + files.recalculate_len(); + } + files.sort = tab_settings.dir_settings.sort; files.dirs_first = tab_settings.dir_settings.dirs_first; files.reverse = tab_settings.dir_settings.reverse; @@ -292,6 +297,8 @@ impl FsCache { files.filter = tab_settings.dir_settings.filter.clone(); files.filter_selected = tab_settings.dir_settings.filter_selected; + + if tab_settings.multi_selections.len() > 0 { for file in &mut files.files { for selected_files in &tab_settings.multi_selections { @@ -302,7 +309,6 @@ impl FsCache { } } - files.sort(); Ok(()) } @@ -311,6 +317,7 @@ impl FsCache { let path = &files.directory.path; let placeholder = File::new_placeholder(&path)?; files.files.push(placeholder); + files.len = 1; } Ok(files) } diff --git a/src/listview.rs b/src/listview.rs index c744f4f..be27dd8 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -707,7 +707,7 @@ impl Widget for ListView where ListView: Listable { self.selection = self.buffer.len() - 1; } - if self.core.is_dirty() || buffer_len != self.len() { + if self.core.is_dirty() { self.buffer = self.render(); self.core.set_clean(); } -- cgit v1.2.3