diff options
Diffstat (limited to 'src/preview.rs')
-rw-r--r-- | src/preview.rs | 133 |
1 files changed, 85 insertions, 48 deletions
diff --git a/src/preview.rs b/src/preview.rs index dd78c78..dda2e68 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -29,19 +29,21 @@ fn kill_proc() -> HResult<()> { } pub fn is_stale(stale: &Arc<Mutex<bool>>) -> HResult<bool> { - Ok(*(stale.lock()?)) + let stale = *(stale.try_lock().unwrap()); + Ok(stale) } -enum State<T: Send> { - Is(T), +enum State { + Is, Becoming, - Taken, Fail } struct WillBe<T: Send> { - pub state: State<T>, - rx: std::sync::mpsc::Receiver<T>, + pub state: Arc<Mutex<State>>, + pub thing: Arc<Mutex<Option<T>>>, + on_ready: Arc<Mutex<Option<Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>>>>, + rx: Option<std::sync::mpsc::Receiver<T>>, stale: Arc<Mutex<bool>> } @@ -49,42 +51,58 @@ impl<T: Send + 'static> WillBe<T> where { pub fn new_become(closure: HClosure<T>) -> WillBe<T> { let (tx,rx) = std::sync::mpsc::channel(); - let mut willbe = WillBe { state: State::Becoming, - rx: rx, + let mut willbe = WillBe { state: Arc::new(Mutex::new(State::Becoming)), + thing: Arc::new(Mutex::new(None)), + on_ready: Arc::new(Mutex::new(None)), + rx: Some(rx), stale: Arc::new(Mutex::new(false)) }; willbe.run(closure, tx); willbe } fn run(&mut self, closure: HClosure<T>, tx: std::sync::mpsc::Sender<T>) { + let state = self.state.clone(); let stale = self.stale.clone(); + let thing = self.thing.clone(); + let on_ready_fn = self.on_ready.clone(); std::thread::spawn(move|| { - let thing = closure(stale); - match thing { - Ok(thing) => { tx.send(thing).ok(); }, + let got_thing = closure(stale); + match got_thing { + Ok(got_thing) => { + *thing.try_lock().unwrap() = Some(got_thing); + *state.try_lock().unwrap() = State::Is; + match *on_ready_fn.lock().unwrap() { + Some(ref on_ready) => { on_ready(thing.clone()); }, + None => {} + } + }, Err(err) => { dbg!(err); } } }); } pub fn set_stale(&mut self) -> HResult<()> { - *self.stale.lock()? = true; + *self.stale.try_lock()? = true; Ok(()) } - pub fn check(&mut self) -> Result<(), Error> { - match self.state { - State::Is(_) => Ok(()), - _ => { - let thing = self.rx.try_recv()?; - self.state = State::Is(thing); - Ok(()) - } + pub fn check(&self) -> HResult<()> { + match *self.state.try_lock()? { + State::Is => Ok(()), + _ => Err(HError::WillBeNotReady) } } - pub fn wait(self) -> Result<T, std::sync::mpsc::RecvError> { - self.rx.recv() + pub fn on_ready(&mut self, + fun: Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>) + -> HResult<()> { + if self.check().is_ok() { + fun(self.thing.clone()); + //*self.on_ready.try_lock()? = None; + } else { + *self.on_ready.try_lock()? = Some(fun); + } + Ok(()) } } @@ -98,21 +116,30 @@ impl<W: Widget + Send> PartialEq for WillBeWidget<W> { } } -struct WillBeWidget<T: Widget + Send> { +pub struct WillBeWidget<T: Widget + Send> { willbe: WillBe<T>, coordinates: Coordinates } impl<T: Widget + Send + 'static> WillBeWidget<T> { - fn new(closure: HClosure<T>) -> WillBeWidget<T> { + pub fn new(closure: HClosure<T>) -> WillBeWidget<T> { + let mut willbe = WillBe::new_become(Box::new(move |stale| closure(stale))); + willbe.on_ready(Box::new(|_| { + crate::window::send_event(crate::window::Events::WidgetReady); + Ok(()) })); + WillBeWidget { - willbe: WillBe::new_become(Box::new(move |stale| closure(stale))), + willbe: willbe, coordinates: Coordinates::new() } } pub fn set_stale(&mut self) -> HResult<()> { self.willbe.set_stale() } + pub fn widget(&self) -> HResult<Arc<Mutex<Option<T>>>> { + self.willbe.check()?; + Ok(self.willbe.thing.clone()) + } } // impl<T: Widget + Send> WillBeWidget<T> { @@ -126,41 +153,46 @@ impl<T: Widget + Send + 'static> WillBeWidget<T> { // } //} -impl<T: Widget + Send> Widget for WillBeWidget<T> { +impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> { fn get_coordinates(&self) -> &Coordinates { &self.coordinates } fn set_coordinates(&mut self, coordinates: &Coordinates) { - if self.coordinates == *coordinates { - return; - } self.coordinates = coordinates.clone(); - match &mut self.willbe.state { - State::Is(widget) => { - widget.set_coordinates(&coordinates.clone()); - self.refresh(); - } - _ => {} + + { + if self.willbe.check().is_err() { return } + let widget = self.widget().unwrap(); + let mut widget = widget.try_lock().unwrap(); + let widget = widget.as_mut().unwrap(); + widget.set_coordinates(&coordinates.clone()); } + + self.refresh(); } fn render_header(&self) -> String { "".to_string() } fn refresh(&mut self) { - match &mut self.willbe.state { - State::Is(widget) => { - widget.refresh(); - } - _ => {} - } + if self.willbe.check().is_err() { return } + let widget = self.widget().unwrap(); + let mut widget = widget.try_lock().unwrap(); + let widget = widget.as_mut().unwrap(); + widget.refresh(); } fn get_drawlist(&self) -> String { - match &self.willbe.state { - State::Is(widget) => { - widget.get_drawlist() - }, - _ => { "".to_string() } - } + if self.willbe.check().is_err() { return "".to_string() } + let widget = self.widget().unwrap(); + let widget = widget.try_lock().unwrap(); + let widget = widget.as_ref().unwrap(); + widget.get_drawlist() + } + fn on_key(&mut self, key: termion::event::Key) { + if self.willbe.check().is_err() { return } + let widget = self.widget().unwrap(); + let mut widget = widget.try_lock().unwrap(); + let widget = widget.as_mut().unwrap(); + widget.on_key(key); } } @@ -177,6 +209,7 @@ impl PartialEq for Previewer { pub struct Previewer { widget: WillBeWidget<Box<dyn Widget + Send>>, + file: Option<File> } @@ -186,7 +219,8 @@ impl Previewer { Ok(Box::new(crate::textview::TextView::new_blank()) as Box<dyn Widget + Send>) })); - Previewer { widget: willbe } + Previewer { widget: willbe, + file: None} } fn become_preview(&mut self, @@ -197,6 +231,9 @@ impl Previewer { } pub fn set_file(&mut self, file: &File) { + if Some(file) == self.file.as_ref() { return } + self.file = Some(file.clone()); + let coordinates = self.get_coordinates().clone(); let file = file.clone(); |