diff options
author | rabite <rabite@posteo.de> | 2019-03-22 22:49:34 +0100 |
---|---|---|
committer | rabite <rabite@posteo.de> | 2019-03-22 22:53:54 +0100 |
commit | fd366a26dcddfc50d54ec0481a8f6e4848356b32 (patch) | |
tree | e1f72f7c8859c71989da6036b3ffe04972e7f818 /src | |
parent | bb917a0dad8922c3a629450aba1e7da905e36c1a (diff) |
async stuff much improved
Diffstat (limited to 'src')
-rw-r--r-- | src/fail.rs | 20 | ||||
-rw-r--r-- | src/file_browser.rs | 125 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/preview.rs | 236 | ||||
-rw-r--r-- | src/proclist.rs | 42 |
5 files changed, 232 insertions, 192 deletions
diff --git a/src/fail.rs b/src/fail.rs index 6cf4afe..039002a 100644 --- a/src/fail.rs +++ b/src/fail.rs @@ -37,6 +37,12 @@ pub enum HError { NoneError(Backtrace), #[fail(display = "Not ready yet!")] WillBeNotReady(Backtrace), + #[fail(display = "Not ready yet!")] + AsyncNotReadyError(Backtrace), + #[fail(display = "Value has already been taken!")] + AsyncAlreadyTakenError(Backtrace), + #[fail(display = "Async Error: {}", _0)] + AsyncError(String), #[fail(display = "No widget found")] NoWidgetError(Backtrace), #[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)] @@ -72,7 +78,7 @@ pub enum HError { #[fail(display = "Terminal has been resized!")] TerminalResizedError, #[fail(display = "{}", _0)] - Log(String) + Log(String), } impl HError { @@ -126,6 +132,18 @@ impl HError { pub fn stale<T>() -> HResult<T> { Err(HError::StaleError(Backtrace::new())) } + + pub fn async_not_ready<T>() -> HResult<T> { + Err(HError::AsyncNotReadyError(Backtrace::new())) + } + + pub fn async_taken<T>() -> HResult<T> { + Err(HError::AsyncAlreadyTakenError(Backtrace::new())) + } + + pub fn async_error<T>(error: &HError) -> HResult<T> { + Err(HError::AsyncError(format!("{}", error))) + } } diff --git a/src/file_browser.rs b/src/file_browser.rs index 558e5a6..37d44bb 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -7,15 +7,14 @@ use std::sync::mpsc::{channel, Receiver, Sender}; use std::time::Duration; use std::path::PathBuf; use std::collections::HashMap; -use std::ffi::{OsString, OsStr}; +use std::ffi::OsString; -use crate::files::{File, Files, PathBufExt, OsStrTools}; +use crate::files::{File, Files, PathBufExt}; use crate::listview::ListView; use crate::hbox::HBox; use crate::widget::Widget; -use crate::dirty::Dirtyable; use crate::tabview::{TabView, Tabbable}; -use crate::preview::{Previewer, WillBeWidget}; +use crate::preview::{Previewer, AsyncWidget}; use crate::fail::{HResult, HError, ErrorLog}; use crate::widget::{Events, WidgetCore}; use crate::proclist::ProcView; @@ -27,7 +26,7 @@ use crate::coordinates::Coordinates; #[derive(PartialEq)] pub enum FileBrowserWidgets { - FileList(WillBeWidget<ListView<Files>>), + FileList(AsyncWidget<ListView<Files>>), Previewer(Previewer), } @@ -191,7 +190,7 @@ impl FileBrowser { }).last()?; let left_path = main_path.parent().map(|p| p.to_path_buf()); - let main_widget = WillBeWidget::new(&core, Box::new(move |_| { + let main_widget = AsyncWidget::new(&core, Box::new(move |_| { let mut list = ListView::new(&core_m, Files::new_from_path(&main_path)?); list.animate_slide_up().log(); @@ -199,7 +198,7 @@ impl FileBrowser { })); if let Some(left_path) = left_path { - let left_widget = WillBeWidget::new(&core, Box::new(move |_| { + let left_widget = AsyncWidget::new(&core, Box::new(move |_| { let mut list = ListView::new(&core_l, Files::new_from_path(&left_path)?); list.animate_slide_up().log(); @@ -314,8 +313,8 @@ impl FileBrowser { self.prev_cwd = Some(self.cwd.clone()); self.cwd = dir.clone(); - let main_widget = self.main_widget_mut()?; - main_widget.change_to(Box::new(move |stale, core| { + let main_async_widget = self.main_async_widget_mut()?; + main_async_widget.change_to(Box::new(move |stale, core| { let path = dir.path(); let cached_files = cached_files.clone(); @@ -334,7 +333,7 @@ impl FileBrowser { if let Ok(grand_parent) = self.cwd()?.parent_as_file() { self.left_widget_goto(&grand_parent).log(); } else { - self.left_widget_mut()?.set_stale().log(); + self.left_async_widget_mut()?.set_stale().log(); } Ok(()) @@ -345,8 +344,8 @@ impl FileBrowser { let cached_files = self.get_cached_files(&dir).ok(); let dir = dir.clone(); - let left_widget = self.left_widget_mut()?; - left_widget.change_to(Box::new(move |stale, core| { + let left_async_widget = self.left_async_widget_mut()?; + left_async_widget.change_to(Box::new(move |stale, core| { let path = dir.path(); let cached_files = cached_files.clone(); @@ -415,34 +414,29 @@ impl FileBrowser { } pub fn update_preview(&mut self) -> HResult<()> { - if !self.main_widget()?.ready() { return Ok(()) } + if !self.main_async_widget_mut()?.ready() { return Ok(()) } if self.main_widget()? - .widget()? - .lock()? - .as_ref() - .unwrap() .content .len() == 0 { - self.preview_widget_mut()?.set_stale(); + self.preview_widget_mut()?.set_stale().log(); return Ok(()); } let file = self.selected_file()?.clone(); let selection = self.get_selection(&file).ok().cloned(); let cached_files = self.get_cached_files(&file).ok(); let preview = self.preview_widget_mut()?; - preview.set_file(&file, selection, cached_files); + preview.set_file(&file, selection, cached_files).log(); Ok(()) } pub fn set_left_selection(&mut self) -> HResult<()> { - if !self.left_widget()?.ready() { return Ok(()) } + if !self.left_async_widget_mut()?.ready() { return Ok(()) } if self.cwd.parent().is_none() { return Ok(()) } let parent = self.cwd()?.parent_as_file(); - if let Ok(left_selection) = self.get_selection(&parent?) { - self.left_widget()?.widget()?.lock()?.as_mut()?.select_file(&left_selection); - } + let left_selection = self.get_selection(&parent?)?.clone(); + self.left_widget_mut()?.select_file(&left_selection); Ok(()) } @@ -452,11 +446,11 @@ impl FileBrowser { } pub fn get_files(&mut self) -> HResult<Files> { - Ok(self.main_widget()?.widget()?.lock()?.as_ref()?.content.clone()) + Ok(self.main_widget()?.content.clone()) } pub fn get_left_files(&mut self) -> HResult<Files> { - Ok(self.left_widget()?.widget()?.lock()?.as_ref()?.content.clone()) + Ok(self.left_widget()?.content.clone()) } pub fn cache_files(&mut self, files: Files) -> HResult<()> { @@ -491,13 +485,14 @@ impl FileBrowser { } pub fn left_dir(&self) -> HResult<File> { - let widget = self.left_widget()?.widget()?; - let dir = widget.lock()?.as_ref()?.content.directory.clone(); + let widget = self.left_widget()?; + let dir = widget.content.directory.clone(); Ok(dir) } fn update_watches(&mut self) -> HResult<()> { - if !self.left_widget()?.ready() || !self.main_widget()?.ready() { + if !self.left_async_widget_mut()?.ready() || + !self.main_async_widget_mut()?.ready() { return Ok(()) } let watched_dirs = self.watches.clone(); @@ -539,13 +534,11 @@ impl FileBrowser { fn handle_dir_events(&mut self) -> HResult<()> { let dir_events = self.dir_events.clone(); for event in dir_events.lock()?.iter() { - let main_widget = self.main_widget()?.widget()?; - let mut main_widget = main_widget.lock()?; - let main_result = main_widget.as_mut()?.content.handle_event(event); + let main_widget = self.main_widget_mut()?; + let main_result = main_widget.content.handle_event(event); - let left_widget = self.left_widget()?.widget()?; - let mut left_files = left_widget.lock()?; - let left_result = left_files.as_mut()?.content.handle_event(event); + let left_widget = self.left_widget_mut()?; + let left_result = left_widget.content.handle_event(event); match main_result { Err(HError::WrongDirectoryError { .. }) => { @@ -563,61 +556,79 @@ impl FileBrowser { } pub fn selected_file(&self) -> HResult<File> { - let widget = self.main_widget()?.widget()?; - let file = widget.lock()?.as_ref()?.selected_file().clone(); + let widget = self.main_widget()?; + let file = widget.selected_file().clone(); Ok(file) } pub fn selected_files(&self) -> HResult<Vec<File>> { - let widget = self.main_widget()?.widget()?; - let files = widget.lock()?.as_ref()?.content.get_selected().into_iter().map(|f| { + let widget = self.main_widget()?; + let files = widget.content.get_selected().into_iter().map(|f| { f.clone() }).collect(); Ok(files) } - pub fn main_widget(&self) -> HResult<&WillBeWidget<ListView<Files>>> { + pub fn main_async_widget_mut(&mut self) -> HResult<&mut AsyncWidget<ListView<Files>>> { + let widget = self.columns.active_widget_mut()?; + + let widget = match widget { + FileBrowserWidgets::FileList(filelist) => filelist, + _ => { HError::wrong_widget("previewer", "filelist")? } + }; + Ok(widget) + } + + pub fn main_widget(&self) -> HResult<&ListView<Files>> { let widget = self.columns.active_widget()?; let widget = match widget { - FileBrowserWidgets::FileList(filelist) => Ok(filelist), + FileBrowserWidgets::FileList(filelist) => filelist.widget(), _ => { HError::wrong_widget("previewer", "filelist")? } }; widget } - pub fn main_widget_mut(&mut self) -> HResult<&mut WillBeWidget<ListView<Files>>> { + pub fn main_widget_mut(&mut self) -> HResult<&mut ListView<Files>> { let widget = self.columns.active_widget_mut()?; let widget = match widget { - FileBrowserWidgets::FileList(filelist) => Ok(filelist), + FileBrowserWidgets::FileList(filelist) => filelist.widget_mut(), _ => { HError::wrong_widget("previewer", "filelist")? } }; widget } - pub fn left_widget(&self) -> HResult<&WillBeWidget<ListView<Files>>> { + pub fn left_async_widget_mut(&mut self) -> HResult<&mut AsyncWidget<ListView<Files>>> { + let widget = match self.columns.widgets.get_mut(0)? { + FileBrowserWidgets::FileList(filelist) => filelist, + _ => { return HError::wrong_widget("previewer", "filelist"); } + }; + Ok(widget) + } + + pub fn left_widget(&self) -> HResult<&ListView<Files>> { let widget = match self.columns.widgets.get(0)? { - FileBrowserWidgets::FileList(filelist) => Ok(filelist), + FileBrowserWidgets::FileList(filelist) => filelist.widget(), _ => { return HError::wrong_widget("previewer", "filelist"); } }; widget } - pub fn left_widget_mut(&mut self) -> HResult<&mut WillBeWidget<ListView<Files>>> { + pub fn left_widget_mut(&mut self) -> HResult<&mut ListView<Files>> { let widget = match self.columns.widgets.get_mut(0)? { - FileBrowserWidgets::FileList(filelist) => Ok(filelist), + FileBrowserWidgets::FileList(filelist) => filelist.widget_mut(), _ => { return HError::wrong_widget("previewer", "filelist"); } }; widget } - pub fn preview_widget(&self) -> HResult<&Previewer> { - match self.columns.widgets.get(2)? { - FileBrowserWidgets::Previewer(previewer) => Ok(previewer), - _ => { return HError::wrong_widget("filelist", "previewer"); } - } - } + // pub fn preview_widget(&self) -> HResult<&Previewer> { + // match self.columns.widgets.get(2)? { + // FileBrowserWidgets::Previewer(previewer) => Ok(previewer), + // _ => { return HError::wrong_widget("filelist", "previewer"); } + // } + // } pub fn preview_widget_mut(&mut self) -> HResult<&mut Previewer> { match self.columns.widgets.get_mut(2)? { @@ -660,14 +671,14 @@ impl FileBrowser { let mcore = self.main_widget()?.get_core()?.clone(); let lcore = self.left_widget()?.get_core()?.clone();; - let middle = WillBeWidget::new(&self.core, Box::new(move |_| { + let middle = AsyncWidget::new(&self.core, Box::new(move |_| { let files = Files::new_from_path(&dir.clone())?; let listview = ListView::new(&mcore, files); Ok(listview) })); let middle = FileBrowserWidgets::FileList(middle); - let left = WillBeWidget::new(&self.core, Box::new(move |_| { + let left = AsyncWidget::new(&self.core, Box::new(move |_| { let files = Files::new_from_path(&left_dir.parent()?)?; let listview = ListView::new(&lcore, files); Ok(listview) @@ -751,9 +762,9 @@ impl FileBrowser { "--> ".to_string() + &target.short_string() } else { "".to_string() }; - let main_widget = self.main_widget()?.widget()?; - let selection = main_widget.lock()?.as_ref().unwrap().get_selection(); - let file_count = main_widget.lock()?.as_ref().unwrap().content.len(); + let main_widget = self.main_widget()?; + let selection = main_widget.get_selection(); + let file_count = main_widget.content.len(); let file_count = format!("{}", file_count); let digits = file_count.len(); let file_count = format!("{:digits$}/{:digits$}", diff --git a/src/main.rs b/src/main.rs index 0042ff0..8376fc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,6 +58,7 @@ use term::ScreenExt; use fail::{HResult, HError}; use file_browser::FileBrowser; use tabview::TabView; +use preview::Async; fn main() -> HResult<()> { diff --git a/src/preview.rs b/src/preview.rs index 4c51ceb..d02fc50 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -1,7 +1,5 @@ use std::sync::{Arc, Mutex}; -use failure::Backtrace; - use crate::files::{File, Files, Kind}; use crate::listview::ListView; use crate::textview::TextView; @@ -10,9 +8,14 @@ use crate::coordinates::Coordinates; use crate::fail::{HResult, HError, ErrorLog}; +pub type Stale = Arc<Mutex<bool>>; + +pub type AsyncValueFn<T> = Box<Fn(Stale) -> HResult<T> + Send>; +pub type AsyncValue<T> = Arc<Mutex<Option<HResult<T>>>>; +pub type AsyncReadyFn<T> = Box<Fn(&mut T) -> HResult<()> + Send>; +pub type AsyncWidgetFn<W> = Box<Fn(Stale, WidgetCore) -> HResult<W> + Send>; + -type HClosure<T> = Box<Fn(Arc<Mutex<bool>>) -> Result<T, HError> + Send>; -type HCClosure<T> = Box<Fn(Arc<Mutex<bool>>, WidgetCore) -> Result<T, HError> + Send>; type WidgetO = Box<dyn Widget + Send>; lazy_static! { @@ -33,49 +36,49 @@ pub fn is_stale(stale: &Arc<Mutex<bool>>) -> HResult<bool> { Ok(stale) } -enum State { - Is, - Becoming, - Fail(HError) -} -struct WillBe<T: Send> { - pub state: Arc<Mutex<State>>, - pub thing: Arc<Mutex<Option<T>>>, - on_ready: Arc<Mutex<Option<Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>>>>, - stale: Arc<Mutex<bool>> +pub struct Async<T: Send> { + pub value: HResult<T>, + async_value: AsyncValue<T>, + async_closure: Option<AsyncValueFn<T>>, + on_ready: Arc<Mutex<Option<AsyncReadyFn<T>>>>, + stale: Stale } -impl<T: Send + 'static> WillBe<T> where { - pub fn new_become(closure: HClosure<T>) - -> WillBe<T> { - let mut willbe = WillBe { state: Arc::new(Mutex::new(State::Becoming)), - thing: Arc::new(Mutex::new(None)), - on_ready: Arc::new(Mutex::new(None)), - stale: Arc::new(Mutex::new(false)) }; - willbe.run(closure); - willbe +impl<T: Send + 'static> Async<T> { + pub fn new(closure: AsyncValueFn<T>) + -> Async<T> { + let async_value = Async { + value: HError::async_not_ready(), + async_value: Arc::new(Mutex::new(None)), + async_closure: Some(closure), + on_ready: Arc::new(Mutex::new(None)), + stale: Arc::new(Mutex::new(false)) }; + + async_value } - fn run(&mut self, closure: HClosure<T>) { - let state = self.state.clone(); + fn run(&mut self) -> HResult<()> { + let closure = self.async_closure.take()?; + let async_value = self.async_value.clone(); let stale = self.stale.clone(); - let thing = self.thing.clone(); let on_ready_fn = self.on_ready.clone(); - std::thread::spawn(move|| { - let got_thing = closure(stale); - match got_thing { - Ok(got_thing) => { - *thing.lock().unwrap() = Some(got_thing); - *state.lock().unwrap() = State::Is; - match *on_ready_fn.lock().unwrap() { - Some(ref on_ready) => { on_ready(thing.clone()).ok(); }, + + std::thread::spawn(move|| -> HResult<()> { + let value = closure(stale); + match value { + Ok(mut value) => { + match *on_ready_fn.lock()? { + Some(ref on_ready) => { on_ready(&mut value).log(); }, None => {} } + async_value.lock()?.replace(Ok(value)); }, - Err(err) => *state.lock().unwrap() = State::Fail(err) + Err(err) => *async_value.lock()? = Some(Err(err)) } + Ok(()) }); + Ok(()) } pub fn set_stale(&mut self) -> HResult<()> { @@ -87,23 +90,46 @@ impl<T: Send + 'static> WillBe<T> where { is_stale(&self.stale) } - pub fn take(&mut self) -> HResult<T> { - self.check()?; - Ok(self.thing.lock()?.take()?) + pub fn take_async(&mut self) -> HResult<()> { + if self.value.is_ok() { return Ok(()) } + + let mut async_value = self.async_value.lock()?; + match async_value.as_ref() { + Some(Ok(_)) => { + let value = async_value.take()?; + self.value = value; + } + Some(Err(HError::AsyncAlreadyTakenError(..))) => HError::async_taken()?, + Some(Err(_)) => { + let value = async_value.take()?; + self.value = value; + } + None => HError::async_not_ready()?, + } + Ok(()) + } + + pub fn get(&self) -> HResult<&T> { + match self.value { + Ok(ref value) => Ok(value), + Err(ref err) => HError::async_error(err) + } } - pub fn check(&self) -> HResult<()> { - match *self.state.lock()? { - State::Is => Ok(()), - _ => Err(HError::WillBeNotReady(Backtrace::new())) + pub fn get_mut(&mut self) -> HResult<&mut T> { + self.take_async().ok(); + + match self.value { + Ok(ref mut value) => Ok(value), + Err(ref err) => HError::async_error(err) } } pub fn on_ready(&mut self, - fun: Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>) + fun: AsyncReadyFn<T>) -> HResult<()> { - if self.check().is_ok() { - fun(self.thing.clone())?; + if self.value.is_ok() { + fun(self.value.as_mut().unwrap())?; } else { *self.on_ready.lock()? = Some(fun); } @@ -111,8 +137,8 @@ impl<T: Send + 'static> WillBe<T> where { } } -impl<W: Widget + Send + 'static> PartialEq for WillBeWidget<W> { - fn eq(&self, other: &WillBeWidget<W>) -> bool { +impl<W: Widget + Send + 'static> PartialEq for AsyncWidget<W> { + fn eq(&self, other: &AsyncWidget<W>) -> bool { if self.get_coordinates().unwrap() == other.get_coordinates().unwrap() { true @@ -122,65 +148,66 @@ impl<W: Widget + Send + 'static> PartialEq for WillBeWidget<W> { } } -pub struct WillBeWidget<T: Widget + Send + 'static> { - willbe: WillBe<T>, + +pub struct AsyncWidget<W: Widget + Send + 'static> { + widget: Async<W>, core: WidgetCore } -impl<T: Widget + Send + 'static> WillBeWidget<T> { - pub fn new(core: &WidgetCore, closure: HClosure<T>) -> WillBeWidget<T> { +impl<W: Widget + Send + 'static> AsyncWidget<W> { + pub fn new(core: &WidgetCore, closure: AsyncValueFn<W>) -> AsyncWidget<W> { let sender = core.get_sender(); - let mut willbe = WillBe::new_become(Box::new(move |stale| closure(stale))); - willbe.on_ready(Box::new(move |_| { + let mut widget = Async::new(Box::new(move |stale| closure(stale))); + widget.on_ready(Box::new(move |_| { sender.send(crate::widget::Events::WidgetReady)?; - Ok(()) })).ok(); + Ok(()) + })).log(); + widget.run().log(); - WillBeWidget { - willbe: willbe, + AsyncWidget { + widget: widget, core: core.clone() } } - pub fn change_to(&mut self, closure: HCClosure<T>) -> HResult<()> { + pub fn change_to(&mut self, closure: AsyncWidgetFn<W>) -> HResult<()> { self.set_stale().log(); let sender = self.get_core()?.get_sender(); let core = self.get_core()?.clone(); - let mut willbe = WillBe::new_become(Box::new(move |stale| { - let core = core.clone(); - closure(stale, core) + let mut widget = Async::new(Box::new(move |stale| { + closure(stale, core.clone()) })); - willbe.on_ready(Box::new(move |_| { + + widget.on_ready(Box::new(move |_| { sender.send(crate::widget::Events::WidgetReady)?; Ok(()) }))?; - self.willbe = willbe; + widget.run().log(); + + self.widget = widget; Ok(()) } pub fn set_stale(&mut self) -> HResult<()> { - self.willbe.set_stale() + self.widget.set_stale() } pub fn is_stale(&self) -> HResult<bool> { - self.willbe.is_stale() + self.widget.is_stale() } - pub fn widget(&self) -> HResult<Arc<Mutex<Option<T>>>> { - self.willbe.check()?; - Ok(self.willbe.thing.clone()) + pub fn widget(&self) -> HResult<&W> { + self.widget.get() } - pub fn ready(&self) -> bool { - match self.willbe.check() { - Ok(_) => true, - _ => false - } + pub fn widget_mut(&mut self) -> HResult<&mut W> { + self.widget.get_mut() } - pub fn take(&mut self) -> HResult<T> { - self.willbe.take() + pub fn ready(&self) -> bool { + self.widget().is_ok() } } @@ -195,7 +222,7 @@ impl<T: Widget + Send + 'static> WillBeWidget<T> { // } //} -impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> { +impl<T: Widget + Send + 'static> Widget for AsyncWidget<T> { fn get_core(&self) -> HResult<&WidgetCore> { Ok(&self.core) } @@ -205,22 +232,19 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> { fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> { self.core.coordinates = coordinates.clone(); - if let Ok(widget) = self.widget() { - let mut widget = widget.lock()?; - let widget = widget.as_mut()?; + if let Ok(widget) = self.widget_mut() { widget.set_coordinates(&coordinates)?; } Ok(()) } fn refresh(&mut self) -> HResult<()> { - let coords = self.get_coordinates()?; - if let Ok(widget) = self.widget() { - let mut widget = widget.lock()?; - let widget = widget.as_mut()?; + self.widget.take_async().log(); - if widget.get_coordinates()? != coords { - widget.set_coordinates(self.get_coordinates()?)?; + let coords = self.get_coordinates()?.clone(); + if let Ok(widget) = self.widget_mut() { + if widget.get_coordinates()? != &coords { + widget.set_coordinates(&coords)?; widget.refresh()?; } else { widget.refresh()?; @@ -229,7 +253,7 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> { Ok(()) } fn get_drawlist(&self) -> HResult<String> { - if self.willbe.check().is_err() { + if self.widget().is_err() { let clear = self.get_clearlist()?; let (xpos, ypos) = self.get_coordinates()?.u16position(); let pos = crate::term::goto_xy(xpos, ypos); @@ -240,17 +264,11 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> { return self.get_clearlist() } - let widget = self.widget()?; - let widget = widget.lock()?; - let widget = widget.as_ref()?; - widget.get_drawlist() + self.widget()?.get_drawlist() } fn on_key(&mut self, key: termion::event::Key) -> HResult<()> { - if self.willbe.check().is_err() { return Ok(()) } - let widget = self.widget()?; - let mut widget = widget.lock()?; - let widget = widget.as_mut()?; - widget.on_key(key) + if self.widget().is_err() { return Ok(()) } + self.widget_mut()?.on_key(key) } } @@ -267,7 +285,7 @@ impl PartialEq for Previewer { } pub struct Previewer { - widget: WillBeWidget<Box<dyn Widget + Send>>, + widget: AsyncWidget<Box<dyn Widget + Send>>, core: WidgetCore, file: Option<File>, selection: Option<File>, @@ -278,11 +296,10 @@ pub struct Previewer { impl Previewer { pub fn new(core: &WidgetCore) -> Previewer { let core_ = core.clone(); - let willbe = WillBeWidget::new(&core, Box::new(move |_| { - Ok(Box::new(crate::textview::TextView::new_blank(&core_)) - as Box<dyn Widget + Send>) + let widget = AsyncWidget::new(&core, Box::new(move |_| { + Ok(Box::new(TextView::new_blank(&core_)) as Box<dyn Widget + Send>) })); - Previewer { widget: willbe, + Previewer { widget: widget, core: core.clone(), file: None, selection: None, @@ -290,10 +307,11 @@ impl Previewer { } fn become_preview(&mut self, - widget: HResult<WillBeWidget<WidgetO>>) { - let coordinates = self.get_coordinates().unwrap().clone(); - self.widget = widget.unwrap(); - self.widget.set_coordinates(&coordinates).ok(); + widget: HResult<AsyncWidget<WidgetO>>) -> HResult<()> { + let coordinates = self.get_coordinates()?.clone(); + self.widget = widget?; + self.widget.set_coordinates(&coordinates)?; + Ok(()) } pub fn set_stale(&mut self) -> HResult<()> { @@ -315,7 +333,8 @@ impl Previewer { self.widget.set_stale().ok(); - self.become_preview(Ok(WillBeWidget::new(&self.core, Box::new(move |stale| { + self.become_preview(Ok(AsyncWidget::new(&self.core, + Box::new(move |stale| { kill_proc().unwrap(); let file = file.clone(); @@ -344,15 +363,14 @@ impl Previewer { blank.animate_slide_up().log(); return Ok(blank) } - })))); - Ok(()) + })))) } pub fn reload(&mut self) { if let Some(file) = self.file.clone() { self.file = None; let cache = self.cached_files.take(); - self.set_file(&file, self.selection.clone(), cache); + self.set_file(&file, self.selection.clone(), cache).log(); } } @@ -403,7 +421,9 @@ impl Previewer { Ok(Box::new(textview)) } - fn preview_external(file: &File, core: &WidgetCore, stale: Arc<Mutex<bool>>) + fn preview_external(file: &File, + core: &WidgetCore, + stale: Arc<Mutex<bool>>) -> Result<Box<dyn Widget + Send>, HError> { let process = std::process::Command::new("scope.sh") diff --git a/src/proclist.rs b/src/proclist.rs index a4efabf..98645c8 100644 --- a/src/proclist.rs +++ b/src/proclist.rs @@ -15,7 +15,6 @@ use crate::widget::{Widget, Events, WidgetCore}; use crate::coordinates::Coordinates; use crate::dirty::Dirtyable; use crate::hbox::HBox; -use crate::preview::WillBeWidget; use crate::fail::{HResult, HError, ErrorLog}; use crate::term; use crate::files::{File, OsStrTools}; @@ -299,7 +298,7 @@ impl ListView<Vec<Process>> { #[derive(PartialEq)] enum ProcViewWidgets { List(ListView<Vec<Process>>), - TextView(WillBeWidget<TextView>), + TextView(TextView), } impl Widget for ProcViewWidgets { @@ -348,7 +347,7 @@ impl HBox<ProcViewWidgets> { _ => unreachable!() } } - fn get_textview(&mut self) -> &mut WillBeWidget<TextView> { + fn get_textview(&mut self) -> &mut TextView { match &mut self.widgets[1] { ProcViewWidgets::TextView(textview) => textview, _ => unreachable!() @@ -360,8 +359,7 @@ impl ProcView { pub fn new(core: &WidgetCore) -> ProcView { let tcore = core.clone(); let listview = ListView::new(&core, vec![]); - let textview = Box::new(move |_| Ok(TextView::new_blank(&tcore))); - let textview = WillBeWidget::new(&core, textview); + let textview = TextView::new_blank(&tcore); let mut hbox = HBox::new(&core); hbox.push_widget(ProcViewWidgets::List(listview)); hbox.push_widget(ProcViewWidgets::TextView(textview)); @@ -382,7 +380,7 @@ impl ProcView { self.hbox.get_listview_mut() } - fn get_textview(&mut self) -> &mut WillBeWidget<TextView> { + fn get_textview(&mut self) -> &mut TextView { self.hbox.get_textview() } @@ -399,13 +397,8 @@ impl ProcView { pub fn remove_proc(&mut self) -> HResult<()> { if self.get_listview_mut().content.len() == 0 { return Ok(()) } self.get_listview_mut().remove_proc()?; - self.get_textview().change_to(Box::new(move |_, core| { - let mut textview = TextView::new_blank(&core); - textview.refresh().log(); - textview.animate_slide_up().log(); - Ok(textview) - })).log(); - Ok(()) + self.get_textview().clear(); + self.get_textview().set_text("") } fn show_output(&mut self) -> HResult<()> { @@ -414,48 +407,45 @@ impl ProcView { } let output = self.get_listview_mut().selected_proc()?.output.lock()?.clone(); - self.get_textview().change_to(Box::new(move |_, core| { - let mut textview = TextView::new_blank(&core); - textview.set_text(&output).log(); - textview.animate_slide_up().log(); - Ok(textview) - })).log(); + self.get_textview().set_text(&output).log(); + self.get_textview().animate_slide_up().log(); + self.viewing = Some(self.get_listview_mut().get_selection()); Ok(()) } pub fn toggle_follow(&mut self) -> HResult<()> { - self.get_textview().widget()?.lock()?.as_mut()?.toggle_follow(); + self.get_textview().toggle_follow(); Ok(()) } pub fn scroll_up(&mut self) -> HResult<()> { - self.get_textview().widget()?.lock()?.as_mut()?.scroll_up(); + self.get_textview().scroll_up(); Ok(()) } pub fn scroll_down(&mut self) -> HResult<()> { - self.get_textview().widget()?.lock()?.as_mut()?.scroll_down(); + self.get_textview().scroll_down(); Ok(()) } pub fn page_up(&mut self) -> HResult<()> { - self.get_textview().widget()?.lock()?.as_mut()?.page_up(); + self.get_textview().page_up(); Ok(()) } pub fn page_down(&mut self) -> HResult<()> { - self.get_textview().widget()?.lock()?.as_mut()?.page_down(); + self.get_textview().page_down(); Ok(()) } pub fn scroll_top(&mut self) -> HResult<()> { - self.get_textview().widget()?.lock()?.as_mut()?.scroll_top(); + self.get_textview().scroll_top(); Ok(()) } pub fn scroll_bottom(&mut self) -> HResult<()> { - self.get_textview().widget()?.lock()?.as_mut()?.scroll_bottom(); + self.get_textview().scroll_bottom(); Ok(()) } } |