From a6c829e1439dd1a50eb3de090bb13990a1eaf932 Mon Sep 17 00:00:00 2001 From: rabite Date: Wed, 5 Feb 2020 21:45:51 +0100 Subject: buggy super-fast crazy stuff --- src/fail.rs | 9 +++ src/file_browser.rs | 92 +++++++++++++++-------------- src/files.rs | 54 ++++++++++++----- src/listview.rs | 165 +++++++++++++++++++++++++++------------------------- src/preview.rs | 8 +-- 5 files changed, 187 insertions(+), 141 deletions(-) diff --git a/src/fail.rs b/src/fail.rs index 38a66d0..1abdea7 100644 --- a/src/fail.rs +++ b/src/fail.rs @@ -30,6 +30,8 @@ pub enum HError { ChannelRecvError{#[cause] error: std::sync::mpsc::RecvError}, #[fail(display = "Channel failed")] ChannelSendError, + #[fail(display = "Timer ran out while waiting for message on channel!")] + ChannelRecvTimeout(#[cause] std::sync::mpsc::RecvTimeoutError), #[fail(display = "Previewer failed on file: {}", file)] PreviewFailed{file: String}, #[fail(display = "StalePreviewer for file: {}", file)] @@ -292,6 +294,13 @@ impl From for HError { } } +impl From for HError { + fn from(error: std::sync::mpsc::RecvTimeoutError) -> Self { + let err = HError::ChannelRecvTimeout(error); + err + } +} + impl From> for HError { fn from(_error: std::sync::mpsc::SendError) -> Self { let err = HError::ChannelSendError; diff --git a/src/file_browser.rs b/src/file_browser.rs index 9361dce..66d6dc6 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -199,7 +199,6 @@ impl Tabbable for TabView { w.as_mut() .map(|mut w| { w.content.show_hidden = show_hidden; - w.content.dirty_meta.set_dirty(); w.refresh().log(); }).ok(); Ok(()) @@ -211,7 +210,6 @@ impl Tabbable for TabView { w.as_mut() .map(|mut w| { w.content.show_hidden = show_hidden; - w.content.dirty_meta.set_dirty(); w.refresh().log(); }).ok(); Ok(()) @@ -262,7 +260,7 @@ impl FileBrowser { let source = FileSource::Path(dir); ListView::builder(core_m, source) .meta_all() - .prerender() + // .prerender() .with_cache(cache) .with_stale(stale.clone()) .build() @@ -274,8 +272,8 @@ impl FileBrowser { let dir = File::new_from_path(&left_path, None)?; let source = FileSource::Path(dir); ListView::builder(core_l, source) - .meta_all() - .prerender() + // .meta_all() + // .prerender() .with_cache(cache) .with_stale(stale.clone()) .build() @@ -359,7 +357,7 @@ impl FileBrowser { ListView::builder(core, source) .meta_all() - .prerender() + // .prerender() .with_cache(cache) .with_stale(stale.clone()) .build() @@ -476,19 +474,19 @@ impl FileBrowser { self.prev_cwd = Some(self.cwd.clone()); self.cwd = dir.clone(); - let file_source = FileSource::Path(self.cwd.clone()); + let file_source = FileSource::Path(self.cwd.clone()); - let main_async_widget = self.main_async_widget_mut()?; - main_async_widget.change_to(move |stale: &Stale, core| { - let view = ListView::builder(core, file_source) - .meta_all() - .prerender() - .with_cache(cache) - .with_stale(stale.clone()) - .build()?; + let main_async_widget = self.main_async_widget_mut()?; + main_async_widget.change_to(move |stale: &Stale, core| { + let view = ListView::builder(core, file_source) + .meta_all() + // .prerender() + .with_cache(cache) + .with_stale(stale.clone()) + .build()?; - Ok(view) - }).log(); + Ok(view) + }).log(); if let Ok(grand_parent) = self.cwd()?.parent_as_file() { @@ -499,32 +497,36 @@ impl FileBrowser { }).log(); } + self.preview_widget_mut() + .map(|p| p.set_stale()) + .ok(); + Ok(()) } pub fn left_widget_goto(&mut self, dir: &File) -> HResult<()> { - // Check if we're in the correct directory already and return - // if we are - let left_dir = &self.left_widget()?.content.directory; - if self.left_widget().is_ok() && left_dir == dir { - return Ok(()); - } - - let cache = self.fs_cache.clone(); - let file_source = FileSource::Path(dir.clone()); - let left_async_widget = self.left_async_widget_mut()?; - left_async_widget.change_to(move |stale, core| { - let view = ListView::builder(core, file_source) - .meta_all() - .prerender() - .with_cache(cache) - .with_stale(stale.clone()) - .build()?; - - Ok(view) - }).log(); - - Ok(()) + // Check if we're in the correct directory already and return + // if we are + let left_dir = &self.left_widget()?.content.directory; + if self.left_widget().is_ok() && left_dir == dir { + return Ok(()); + } + + let cache = self.fs_cache.clone(); + let file_source = FileSource::Path(dir.clone()); + let left_async_widget = self.left_async_widget_mut()?; + left_async_widget.change_to(move |stale, core| { + let view = ListView::builder(core, file_source) + // .meta_all() + // .prerender() + .with_cache(cache) + .with_stale(stale.clone()) + .build()?; + + Ok(view) + }).log(); + + Ok(()) } pub fn go_back(&mut self) -> HResult<()> { @@ -548,7 +550,7 @@ impl FileBrowser { ListView::builder(core, file_source) .select(main_selection) .meta_all() - .prerender() + // .prerender() .with_cache(cache) .with_stale(stale.clone()) .build() @@ -559,7 +561,7 @@ impl FileBrowser { let cache = self.fs_cache.clone(); self.left_async_widget_mut()?.change_to(move |stale, core| { ListView::builder(core, file_source) - .prerender() + // .prerender() .with_cache(cache) .with_stale(stale.clone()) .build() @@ -698,16 +700,16 @@ impl FileBrowser { pub fn take_main_files(&mut self) -> HResult { let mut w = self.main_widget_mut()?; - w.lines = 0; - w.buffer.clear(); + w.content.len = 0; + //w.buffer.clear(); let files = std::mem::take(&mut w.content); Ok(files) } pub fn take_left_files(&mut self) -> HResult { let mut w = self.left_widget_mut()?; - w.lines = 0; - w.buffer.clear(); + w.content.len = 0; + //w.buffer.clear(); let files = std::mem::take(&mut w.content); Ok(files) } diff --git a/src/files.rs b/src/files.rs index c7d250a..78741c1 100644 --- a/src/files.rs +++ b/src/files.rs @@ -8,6 +8,7 @@ use std::sync::{Arc, Mutex, RwLock}; use std::sync::mpsc::Sender; use std::hash::{Hash, Hasher}; use std::str::FromStr; +use std::sync::atomic::{AtomicU32, Ordering}; use lscolors::LsColors; use tree_magic; @@ -157,8 +158,6 @@ impl RefreshPackage { for event in events.into_iter() { match event { Create(mut file) => { - let dirty_meta = files.dirty_meta.clone(); - file.dirty_meta = Some(dirty_meta); file.meta_sync().log(); new_files.push(file); } @@ -251,7 +250,6 @@ pub struct Files { pub filter: Option, pub filter_selected: bool, pub dirty: DirtyBit, - pub dirty_meta: AsyncDirtyBit, } impl Index for Files { @@ -294,7 +292,6 @@ impl Default for Files { filter: None, filter_selected: false, dirty: DirtyBit::new(), - dirty_meta: AsyncDirtyBit::new(), } } } @@ -325,8 +322,6 @@ impl Files { let mut files = Files::default(); files.directory = File::new_from_path(&path, None)?; files.len = len; - files.dirty_meta = dirty_meta; - Ok(files) } @@ -371,7 +366,6 @@ impl Files { filter: None, filter_selected: false, dirty: dirty, - dirty_meta: dirty_meta, }; Ok(files) @@ -418,6 +412,7 @@ impl Files { (!filter_selected || f.selected)) .filter(move |(_,f)| !(!show_hidden && f.hidden)) } + pub fn iter_files(&self) -> impl Iterator { let filter = self.filter.clone(); let filter_selected = self.filter_selected; @@ -761,13 +756,14 @@ impl std::default::Default for File { } + #[derive(Clone)] pub struct File { pub name: String, pub path: PathBuf, pub hidden: bool, pub kind: Kind, - pub dirsize: Option, + pub dirsize: Option>, pub target: Option, pub color: Option, pub meta: Option, @@ -882,14 +878,27 @@ impl File { self.meta = Some(meta); self.process_meta().log(); - if self.is_dir() { - let dirsize = std::fs::read_dir(&self.path)?.count(); - self.dirsize = Some(dirsize); - } + // if self.is_dir() { + // let dirsize = std::fs::read_dir(&self.path)?.count(); + // self.dirsize = Some(dirsize); + // } Ok(()) } + pub fn run_dirsize(&mut self) { + let dirsize = Arc::new(AtomicU32::new(0)); + self.dirsize = Some(dirsize.clone()); + let path = self.path.clone(); + rayon::spawn(move || { + std::fs::read_dir(&path) + .map(|dirs| { + let size = dirs.count(); + dirsize.store(size as u32, Ordering::Release); + }); + }); + } + pub fn meta(&self) -> Option<&Metadata> { self.meta.as_ref() } @@ -921,8 +930,13 @@ impl File { } pub fn calculate_size(&self) -> HResult<(u32, &str)> { - if let Some(ref dirsize) = self.dirsize { - return Ok((*dirsize as u32, "")) + if self.is_dir() { + let size = match self.dirsize { + Some(ref size) => (size.load(Ordering::Acquire), ""), + None => (0, ""), + }; + + return Ok(size); } @@ -966,6 +980,18 @@ impl File { tree_magic::match_filepath("text/plain", &self.path) } + pub fn is_filtered(&self, filter: &str, filter_selected: bool) -> bool { + self.kind == Kind::Placeholder || + !(// filter.is_some() && + !self.name.contains(filter// .as_ref().unwrap() + )) && + (!filter_selected || self.selected) + } + + pub fn is_hidden(&self) -> bool { + self.hidden + } + pub fn parent(&self) -> Option { Some(self.path.parent()?.to_path_buf()) diff --git a/src/listview.rs b/src/listview.rs index 6084f98..db08908 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -147,10 +147,10 @@ where { pub content: T, pub current_item: Option< as Listable>::Item>, - pub lines: usize, + // pub lines: usize, selection: usize, pub offset: usize, - pub buffer: Vec, + //pub buffer: Vec, pub core: WidgetCore, seeking: bool, searching: Option, @@ -165,10 +165,10 @@ where let mut view = ListView:: { content: content, current_item: None, - lines: 0, + // lines: 0, selection: 0, offset: 0, - buffer: Vec::new(), + // buffer: Vec::new(), core: core.clone(), seeking: false, searching: None @@ -190,10 +190,10 @@ where self.seeking = false; } pub fn move_down(&mut self) { - let lines = self.lines; + let lines = self.len(); let y_size = self.get_coordinates().unwrap().ysize() as usize; - if self.lines == 0 || self.selection == lines - 1 { + if lines == 0 || self.selection == lines - 1 { return; } @@ -210,7 +210,7 @@ where } pub fn move_bottom(&mut self) { - let lines = self.lines; + let lines = self.len(); self.set_selection(lines - 1); } @@ -354,22 +354,27 @@ impl FileListBuilder { .skip(from) .take(upto) .par_bridge() - .for_each(|f| f.meta_sync().log()); - view.content.meta_upto = Some(view.content.len); + .for_each(|f| { + f.meta_sync().log(); + if f.is_dir() { + f.run_dirsize(); + } + }); + view.content.meta_upto = Some(upto); - if self.prerender { - match self.stale { - Some(s) => view.render_buffer_stale(s)?, - None => view.render_buffer()? - } + // if self.prerender { + // match self.stale { + // Some(s) => view.render_buffer_stale(s)?, + // None => view.render_buffer()? + // } - if view.buffer.len() > 0 { - view.lines = view.buffer.len() - 1; - } - }; + // if view.buffer.len() > 0 { + // view.lines = view.buffer.len() - 1; + // } + // }; view.content.set_clean(); - view.content.dirty_meta.set_clean(); + // view.content.dirty_meta.set_clean(); view.core.set_clean(); Ok(view) @@ -565,9 +570,9 @@ impl ListView file.toggle_selection(); if !self.content.filter_selected { - let selection = self.get_selection(); - let line = self.render_line(&file); - self.buffer[selection] = line; + //let selection = self.get_selection(); + //let line = self.render_line(&file); + //self.buffer[selection] = line; self.move_down(); } else { @@ -607,12 +612,12 @@ impl ListView self.selected_file_mut().toggle_tag()?; // Create a mutable clone to render changes into buffer - let mut file = self.clone_selected_file(); - file.toggle_tag()?; + // let mut file = self.clone_selected_file(); + // file.toggle_tag()?; - let line = self.render_line(&file); - let selection = self.get_selection(); - self.buffer[selection] = line; + // let line = self.render_line(&file); + // let selection = self.get_selection(); + // self.buffer[selection] = line; self.move_down(); Ok(()) @@ -868,60 +873,66 @@ impl ListView fn render(&self) -> Vec { let render_fn = self.render_line_fn(); + let ysize = self.get_coordinates().unwrap().ysize_u(); self.content .iter_files() + .skip(self.offset) + .take(ysize+1) + // .collect::>() + // .into_par_iter() .map(|file| render_fn(file)) .collect() } fn render_buffer(&mut self) -> HResult<()> { - let render_fn = self.render_line_fn(); - self.buffer = self.content - .iter_files() - .enumerate() - .map(|(_, file)| { - render_fn(file) - }) - .collect(); + // let render_fn = self.render_line_fn(); + // self.buffer = self.content + // .iter_files() + // .enumerate() + // .map(|(_, file)| { + // render_fn(file) + // }) + // .collect(); Ok(()) } fn render_buffer_stale(&mut self, stale: Stale) -> HResult<()> { - let render_fn = self.render_line_fn(); - let buffer = self.content - .iter_files() - .stop_stale(stale.clone()) - .enumerate() - .map(|(_, file)| { - render_fn(file) - }) - .collect(); - - if stale.is_stale() - .unwrap_or(true) { - return HError::stale(); - } else { - self.buffer = buffer; - return Ok(()) - } + // let render_fn = self.render_line_fn(); + // let buffer = self.content + // .iter_files() + // .stop_stale(stale.clone()) + // .enumerate() + // .map(|(_, file)| { + // render_fn(file) + // }) + // .collect(); + + // if stale.is_stale() + // .unwrap_or(true) { + // return HError::stale(); + // } else { + // self.buffer = buffer; + // return Ok(()) + // } + Ok(()) } fn refresh_files(&mut self) -> HResult<()> { - if let Ok(Some(mut refresh)) = self.content.get_refresh() { - let file = self.clone_selected_file(); + // if let Ok(Some(mut refresh)) = self.content.get_refresh() { + // let file = self.clone_selected_file(); - self.buffer = refresh.new_buffer.take()?; - self.lines = self.buffer.len() - 1; + // self.buffer = refresh.new_buffer.take()?; + // self.lines = self.buffer.len() - 1; - self.select_file(&file); - } + // self.select_file(&file); + // } - if self.content.ready_to_refresh()? { - let render_fn = self.render_line_fn(); - self.content.process_fs_events(self.buffer.clone(), - self.core.get_sender(), - render_fn)?; - } + // if self.content.ready_to_refresh()? { + // let render_fn = self.render_line_fn(); + // self.content.process_fs_events(self.buffer.clone(), + // self.core.get_sender(), + // render_fn)?; + // } Ok(()) } @@ -941,18 +952,18 @@ where fn refresh(&mut self) -> HResult<()> { self.on_refresh().log(); - let buffer_len = self.buffer.len(); + // let buffer_len = self.buffer.len(); - self.lines = buffer_len; + // self.lines = buffer_len; - if self.selection >= self.buffer.len() && self.buffer.len() != 0 { - self.selection = self.buffer.len() - 1; + if self.selection >= self.len() && self.len() != 0 { + self.selection = self.len() - 1; } - if self.core.is_dirty() { - self.buffer = self.render(); - self.core.set_clean(); - } + // if self.core.is_dirty() { + // self.buffer = self.render(); + // self.core.set_clean(); + // } Ok(()) } @@ -967,13 +978,11 @@ where fn get_drawlist(&self) -> HResult { let mut output = term::reset(); let (xpos, ypos) = self.get_coordinates().unwrap().position().position(); - let ysize = self.get_coordinates().unwrap().ysize() as usize; - output += &self - .buffer + let render = self.render(); + + output += &render .iter() - .skip(self.offset) - .take(ysize) .enumerate() .map(|(i, item)| { let mut output = term::normal_color(); @@ -991,7 +1000,7 @@ where }) .collect::(); - output += &self.get_redraw_empty_list(self.buffer.len())?; + output += &self.get_redraw_empty_list(self.len())?; Ok(output) } diff --git a/src/preview.rs b/src/preview.rs index cc50168..0b27176 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -65,7 +65,7 @@ pub struct AsyncWidget { impl AsyncWidget { pub fn new(core: &WidgetCore, - closure: impl FnOnce(&Stale) -> HResult + Send + Sync + 'static) + closure: impl FnOnce(&Stale) -> HResult + Send + 'static) -> AsyncWidget { let sender = Arc::new(Mutex::new(core.get_sender())); let mut widget = Async::new(move |stale| @@ -86,7 +86,7 @@ impl AsyncWidget { pub fn change_to(&mut self, closure: impl FnOnce(&Stale, WidgetCore) - -> HResult + Send + Sync + 'static) + -> HResult + Send + 'static) -> HResult<()> { self.set_stale().log(); @@ -327,7 +327,7 @@ impl Previewer { let source = crate::listview::FileSource::Files(files); let list = ListView::builder(core.clone(), source) - .prerender() + // .prerender() .with_cache(cache) .with_stale(stale.clone()) .select(selected_file) @@ -457,7 +457,7 @@ impl Previewer { let source = FileSource::Path(file.clone()); let mut file_list = ListView::builder(core.clone(), source) - .prerender() + // .prerender() .with_cache(cache) .with_stale(stale.clone()) .build()?; -- cgit v1.2.3