From 5007fdea3c1b20a8bc1773bc4c5f51b99edca26a Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 11 Jan 2021 01:18:32 +0100 Subject: [PATCH] make Observer::reset() mutable use RwLock in ObserverBroadcast --- src/core/observer.rs | 30 ++++++++++++++---------------- src/core/port.rs | 8 ++++---- src/terminal/compositor.rs | 27 ++++++++++++--------------- src/terminal/terminal.rs | 8 ++++---- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/core/observer.rs b/src/core/observer.rs index b02f2fe..07931df 100644 --- a/src/core/observer.rs +++ b/src/core/observer.rs @@ -1,7 +1,7 @@ use { crate::core::View, std::{ - ops::Deref, + ops::{Deref, DerefMut}, sync::{Arc, Weak, RwLock} } }; @@ -12,24 +12,22 @@ use { <<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> \*/ pub trait Observer : Send + Sync { - fn reset(&self, view: Option>) {} + fn reset(&mut self, view: Option>) {} fn notify(&self, msg: &V::Msg); } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -impl> Observer for RwLock { +impl> Observer for Arc> { + fn reset(&mut self, view: Option>) { + self.write().unwrap().reset(view); + } + fn notify(&self, msg: &V::Msg) { self.read().unwrap().notify(&msg); } } -impl> Observer for Arc { - fn notify(&self, msg: &V::Msg) { - self.deref().notify(&msg); - } -} - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub trait ObserverExt : Observer { @@ -51,7 +49,7 @@ impl> ObserverExt for T { \*/ pub struct ObserverBroadcast { - observers: Vec>> + observers: Vec>>> } impl ObserverBroadcast { @@ -61,7 +59,7 @@ impl ObserverBroadcast { } } - pub fn add_observer(&mut self, obs: Weak>) { + pub fn add_observer(&mut self, obs: Weak>>) { self.cleanup(); self.observers.push(obs); } @@ -70,21 +68,21 @@ impl ObserverBroadcast { self.observers.retain(|o| o.strong_count() > 0); } - fn iter(&self) -> impl Iterator>> + '_ { + fn iter(&self) -> impl Iterator>>> + '_ { self.observers.iter().filter_map(|o| o.upgrade()) } } impl Observer for ObserverBroadcast { - fn reset(&self, view: Option>) { + fn reset(&mut self, view: Option>) { for o in self.iter() { - o.reset(view.clone()); + o.write().unwrap().reset(view.clone()); } } fn notify(&self, msg: &V::Msg) { for o in self.iter() { - o.notify(&msg); + o.read().unwrap().notify(&msg); } } } @@ -141,7 +139,7 @@ impl Observer for ResetFnObserver where V: View + ?Sized, F: Fn(Option>) + Send + Sync { fn notify(&self, msg: &V::Msg) {} - fn reset(&self, view: Option>) { + fn reset(&mut self, view: Option>) { (self.f)(view); } } diff --git a/src/core/port.rs b/src/core/port.rs index 66078cb..334941d 100644 --- a/src/core/port.rs +++ b/src/core/port.rs @@ -41,12 +41,12 @@ impl ViewPort { pub fn set_view(&self, view: Option>) { *self.view.write().unwrap() = view.clone(); - self.observers.read().unwrap().reset(view); + self.observers.write().unwrap().reset(view); } - pub fn add_observer(&self, observer: Arc>) { + pub fn add_observer(&self, observer: Arc>>) { self.observers.write().unwrap().add_observer(Arc::downgrade(&observer)); - observer.reset(self.view.read().unwrap().clone()); + observer.write().unwrap().reset(self.view.read().unwrap().clone()); } pub fn inner(&self) -> InnerViewPort { @@ -106,7 +106,7 @@ impl OuterViewPort { self.0.view.clone() } - pub fn add_observer(&self, observer: Arc>) -> Arc>>> { + pub fn add_observer(&self, observer: Arc>>) -> Arc>>> { self.0.add_observer(observer); self.get_view_arc() } diff --git a/src/terminal/compositor.rs b/src/terminal/compositor.rs index c66e97d..ad346b5 100644 --- a/src/terminal/compositor.rs +++ b/src/terminal/compositor.rs @@ -15,19 +15,17 @@ use { struct CompositeLayer { comp: Weak>, - idx: usize, - view: RwLock>> + idx: usize } impl Observer for CompositeLayer { - fn reset(&self, view: Option>) { + fn reset(&mut self, view: Option>) { let comp = self.comp.upgrade().unwrap(); let mut c = comp.write().unwrap(); { - let mut v = self.view.write().unwrap(); - let old_view = v.clone(); - *v = view.clone(); + let old_view = c.layers[&self.idx].1.clone(); + c.layers.get_mut(&self.idx).unwrap().1 = view.clone(); if let Some(old_view) = old_view { if let Some(range) = old_view.range() { @@ -35,7 +33,7 @@ impl Observer for CompositeLayer { } } - if let Some(view) = v.as_ref() { + if let Some(view) = view.as_ref() { if let Some(range) = view.range() { c.cast.notify_each(GridWindowIterator::from(range)); } @@ -55,7 +53,7 @@ impl Observer for CompositeLayer { pub struct TerminalCompositeView { idx_count: usize, - layers: HashMap>, + layers: HashMap>, Option>)>, range: Option>>, cast: Arc>> } @@ -73,7 +71,7 @@ impl TerminalCompositeView { Some(new_range), Some(old_range) ) = ( - if let Some(view) = layer.view.read().unwrap().clone() { + if let Some(view) = layer.1.as_ref() { view.range().clone() } else { None @@ -106,7 +104,7 @@ impl ImplIndexView for TerminalCompositeView { for idx in 0 .. self.idx_count { if let Some(l) = self.layers.get(&idx) { - if let Some(view) = l.view.read().unwrap().as_ref() { + if let Some(view) = l.1.as_ref() { if let Some(range) = view.range() { if pos.x < range.start.x || pos.x >= range.end.x || @@ -160,13 +158,12 @@ impl TerminalCompositor { let idx = comp.idx_count; comp.idx_count += 1; - let layer = Arc::new(CompositeLayer { + let layer = Arc::new(RwLock::new(CompositeLayer { comp: Arc::downgrade(&self.view), - idx: idx, - view: RwLock::new(None) - }); + idx: idx + })); - comp.layers.insert(idx, layer.clone()); + comp.layers.insert(idx, (layer.clone(), None)); drop(comp); v.add_observer(layer); diff --git a/src/terminal/terminal.rs b/src/terminal/terminal.rs index 3123f38..193de9c 100644 --- a/src/terminal/terminal.rs +++ b/src/terminal/terminal.rs @@ -44,7 +44,7 @@ pub enum TerminalEvent { pub struct Terminal { writer: Arc, - observer: Arc, + observer: Arc>, events: ChannelReceiver>, _signal_handle: signal_hook_async_std::Handle @@ -62,10 +62,10 @@ impl Terminal { view: port.get_view_arc() }); - let observer = Arc::new(TermOutObserver { + let observer = Arc::new(RwLock::new(TermOutObserver { dirty_pos_tx, writer: writer.clone() - }); + })); port.add_observer(observer.clone()); @@ -122,7 +122,7 @@ struct TermOutObserver { } impl Observer for TermOutObserver { - fn reset(&self, view: Option>) { + fn reset(&mut self, view: Option>) { self.writer.reset(); let (w, h) = termion::terminal_size().unwrap();