From ad44f6f2fc586bbf0cf8c131467e93df58295b2d Mon Sep 17 00:00:00 2001 From: rabite Date: Sat, 16 Feb 2019 18:59:48 +0100 Subject: [PATCH] preview v3 rc1 --- src/preview.rs | 120 +++++++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 43 deletions(-) diff --git a/src/preview.rs b/src/preview.rs index e458cfc..2d3f82c 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -13,19 +13,24 @@ use crate::widget::Widget; use crate::fail::HError; - +type HResult = Result; +type HClosure = Box Result + Send>; +type WClosure = HClosure>; +type WidgetO = Box; +type WidgetFn = Box Box>; lazy_static! { - static ref PIDS: Arc>> = { Arc::new(Mutex::new(vec![])) }; + static ref SUBPROC: Arc>> = { Arc::new(Mutex::new(None)) }; static ref CURFILE: Arc>> = { Arc::new(Mutex::new(None)) }; } -fn kill_procs() { - let mut pids = PIDS.lock().unwrap(); - for pid in &*pids { - unsafe { libc::kill(*pid as i32, 9); } - } - pids.clear(); +fn kill_proc() -> HResult<()> { + let mut pid = SUBPROC.lock()?; + pid.map(|pid| + unsafe { libc::kill(pid as i32, 15); } + ); + *pid = None; + Ok(()) } fn is_current(file: &File) -> bool { @@ -35,6 +40,12 @@ fn is_current(file: &File) -> bool { } } +fn set_current(file: &File) -> HResult<()> { + let mut curfile = CURFILE.lock()?; + *curfile = Some(file.clone()); + Ok(()) +} + enum State { Is(T), Becoming, @@ -49,7 +60,7 @@ struct WillBe { } impl WillBe where { - pub fn new_become(closure: Box T + Send>) + pub fn new_become(closure: HClosure) -> WillBe { let (tx,rx) = std::sync::mpsc::channel(); let mut willbe = WillBe { state: State::Becoming, @@ -59,10 +70,13 @@ impl WillBe where { willbe } - fn run(&mut self, closure: Box T + Send>, tx: std::sync::mpsc::Sender) { + fn run(&mut self, closure: HClosure, tx: std::sync::mpsc::Sender) { std::thread::spawn(move|| { - let thing = closure(); - tx.send(thing).ok(); + let thing = closure(); + match thing { + Ok(thing) => { tx.send(thing).ok(); }, + Err(err) => { dbg!(err); } + } }); } @@ -105,7 +119,7 @@ struct WillBeWidget { } impl WillBeWidget { - fn new(closure: Box T + Send>) -> WillBeWidget { + fn new(closure: HClosure) -> WillBeWidget { WillBeWidget { willbe: WillBe::new_become(Box::new(move || closure())), coordinates: Coordinates::new() @@ -162,7 +176,7 @@ impl Widget for WillBeWidget { } } -type WidgetO = Box; + #[derive(PartialEq)] pub struct Previewer { @@ -173,75 +187,86 @@ pub struct Previewer { impl Previewer { pub fn new() -> Previewer { let willbe = WillBeWidget::new(Box::new(move || { - Box::new(crate::textview::TextView { + Ok(Box::new(crate::textview::TextView { lines: vec![], buffer: String::new(), coordinates: Coordinates::new() - }) as Box + }) as Box) })); Previewer { widget: willbe } } - fn become_preview(&mut self, widget: WillBeWidget>) { + fn become_preview(&mut self, + widget: HResult>) { let coordinates = self.get_coordinates().clone(); - self.widget = widget; + self.widget = widget.unwrap(); self.set_coordinates(&coordinates); } pub fn set_file(&mut self, file: &File) { let coordinates = self.get_coordinates().clone(); - //let pids = PIDS.clone(); - //kill_procs(); let file = file.clone(); + set_current(&file).unwrap(); - self.become_preview(WillBeWidget::new(Box::new(move || { - //kill_procs(); + self.become_preview(Ok(WillBeWidget::new(Box::new(move || { + kill_proc().unwrap(); let file = file.clone(); if file.kind == Kind::Directory { - let preview = Previewer::preview_dir(&file, &coordinates); - let mut preview = preview.unwrap(); - preview.set_coordinates(&coordinates); - return preview + let preview = Previewer::preview_dir(&file, &coordinates); + return preview; } if file.get_mime() == Some("text".to_string()) { return Previewer::preview_text(&file, &coordinates) - } else { - } - let mut textview = crate::textview::TextView::new_blank(); - textview.set_coordinates(&coordinates); - return Box::new(textview) as Box - }))); + let preview = Previewer::preview_external(&file, &coordinates); + if preview.is_ok() { return preview; } + else { + let mut blank = Box::new(TextView::new_blank()); + blank.set_coordinates(&coordinates); + blank.refresh(); + blank.animate_slide_up(); + return Ok(blank) + } + })))); + } + + fn preview_failed(file: &File) -> HResult { + Err(HError::PreviewFailed { file: file.name.clone() }) } fn preview_dir(file: &File, coordinates: &Coordinates) - -> Result { + -> Result { let files = Files::new_from_path(&file.path)?; - //if !is_current(&file) { return } let len = files.len(); - //if len == 0 { return }; + + if len == 0 || !is_current(&file) { return Previewer::preview_failed(&file) } + let mut file_list = ListView::new(files); file_list.set_coordinates(&coordinates); file_list.refresh(); - //if !is_current(&file) { return } + if !is_current(&file) { return Previewer::preview_failed(&file) } file_list.animate_slide_up(); Ok(Box::new(file_list) as Box) } - fn preview_text(file: &File, coordinates: &Coordinates) -> Box { + fn preview_text(file: &File, coordinates: &Coordinates) + -> HResult { let lines = coordinates.ysize() as usize; let mut textview = TextView::new_from_file_limit_lines(&file, lines); - //if !is_current(&file) { return } + if !is_current(&file) { return Previewer::preview_failed(&file) } + textview.set_coordinates(&coordinates); textview.refresh(); - //if !is_current(&file) { return } + + if !is_current(&file) { return Previewer::preview_failed(&file) } + textview.animate_slide_up(); - Box::new(textview) + Ok(Box::new(textview)) } fn preview_external(file: &File, coordinates: &Coordinates) @@ -259,13 +284,22 @@ impl Previewer { .spawn()?; let pid = process.id(); - let mut pids = PIDS.lock()?; - pids.push(pid); + { + let mut pid_ = SUBPROC.lock()?; + *pid_ = Some(pid); + } - //if !is_current(&file) { return } + if !is_current(&file) { return Previewer::preview_failed(&file) } let output = process.wait_with_output()?; + if !is_current(&file) { return Previewer::preview_failed(&file) } + + { + let mut pid_ = SUBPROC.lock()?; + *pid_ = None; + } + let status = output.status.code() .ok_or(HError::PreviewFailed{file: file.name.clone()})?;