make Observer::reset() mutable
use RwLock in ObserverBroadcast
This commit is contained in:
parent
86562614cc
commit
5007fdea3c
4 changed files with 34 additions and 39 deletions
|
@ -1,7 +1,7 @@
|
|||
use {
|
||||
crate::core::View,
|
||||
std::{
|
||||
ops::Deref,
|
||||
ops::{Deref, DerefMut},
|
||||
sync::{Arc, Weak, RwLock}
|
||||
}
|
||||
};
|
||||
|
@ -12,21 +12,19 @@ use {
|
|||
<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
\*/
|
||||
pub trait Observer<V: View + ?Sized> : Send + Sync {
|
||||
fn reset(&self, view: Option<Arc<V>>) {}
|
||||
fn reset(&mut self, view: Option<Arc<V>>) {}
|
||||
fn notify(&self, msg: &V::Msg);
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
impl<V: View + ?Sized, O: Observer<V>> Observer<V> for RwLock<O> {
|
||||
fn notify(&self, msg: &V::Msg) {
|
||||
self.read().unwrap().notify(&msg);
|
||||
}
|
||||
impl<V: View + ?Sized, O: Observer<V>> Observer<V> for Arc<RwLock<O>> {
|
||||
fn reset(&mut self, view: Option<Arc<V>>) {
|
||||
self.write().unwrap().reset(view);
|
||||
}
|
||||
|
||||
impl<V: View + ?Sized, O: Observer<V>> Observer<V> for Arc<O> {
|
||||
fn notify(&self, msg: &V::Msg) {
|
||||
self.deref().notify(&msg);
|
||||
self.read().unwrap().notify(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +49,7 @@ impl<V: View + ?Sized, T: Observer<V>> ObserverExt<V> for T {
|
|||
\*/
|
||||
|
||||
pub struct ObserverBroadcast<V: View + ?Sized> {
|
||||
observers: Vec<Weak<dyn Observer<V>>>
|
||||
observers: Vec<Weak<RwLock<dyn Observer<V>>>>
|
||||
}
|
||||
|
||||
impl<V: View + ?Sized> ObserverBroadcast<V> {
|
||||
|
@ -61,7 +59,7 @@ impl<V: View + ?Sized> ObserverBroadcast<V> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_observer(&mut self, obs: Weak<dyn Observer<V>>) {
|
||||
pub fn add_observer(&mut self, obs: Weak<RwLock<dyn Observer<V>>>) {
|
||||
self.cleanup();
|
||||
self.observers.push(obs);
|
||||
}
|
||||
|
@ -70,21 +68,21 @@ impl<V: View + ?Sized> ObserverBroadcast<V> {
|
|||
self.observers.retain(|o| o.strong_count() > 0);
|
||||
}
|
||||
|
||||
fn iter(&self) -> impl Iterator<Item = Arc<dyn Observer<V>>> + '_ {
|
||||
fn iter(&self) -> impl Iterator<Item = Arc<RwLock<dyn Observer<V>>>> + '_ {
|
||||
self.observers.iter().filter_map(|o| o.upgrade())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View + ?Sized> Observer<V> for ObserverBroadcast<V> {
|
||||
fn reset(&self, view: Option<Arc<V>>) {
|
||||
fn reset(&mut self, view: Option<Arc<V>>) {
|
||||
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<V, F> Observer<V> for ResetFnObserver<V, F>
|
|||
where V: View + ?Sized,
|
||||
F: Fn(Option<Arc<V>>) + Send + Sync {
|
||||
fn notify(&self, msg: &V::Msg) {}
|
||||
fn reset(&self, view: Option<Arc<V>>) {
|
||||
fn reset(&mut self, view: Option<Arc<V>>) {
|
||||
(self.f)(view);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,12 +41,12 @@ impl<V: View + ?Sized> ViewPort<V> {
|
|||
|
||||
pub fn set_view(&self, view: Option<Arc<V>>) {
|
||||
*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<dyn Observer<V>>) {
|
||||
pub fn add_observer(&self, observer: Arc<RwLock<dyn Observer<V>>>) {
|
||||
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<V> {
|
||||
|
@ -106,7 +106,7 @@ impl<V: View + ?Sized + 'static> OuterViewPort<V> {
|
|||
self.0.view.clone()
|
||||
}
|
||||
|
||||
pub fn add_observer(&self, observer: Arc<dyn Observer<V>>) -> Arc<RwLock<Option<Arc<V>>>> {
|
||||
pub fn add_observer(&self, observer: Arc<RwLock<dyn Observer<V>>>) -> Arc<RwLock<Option<Arc<V>>>> {
|
||||
self.0.add_observer(observer);
|
||||
self.get_view_arc()
|
||||
}
|
||||
|
|
|
@ -15,19 +15,17 @@ use {
|
|||
|
||||
struct CompositeLayer {
|
||||
comp: Weak<RwLock<TerminalCompositeView>>,
|
||||
idx: usize,
|
||||
view: RwLock<Option<Arc<dyn TerminalView>>>
|
||||
idx: usize
|
||||
}
|
||||
|
||||
impl Observer<dyn TerminalView> for CompositeLayer {
|
||||
fn reset(&self, view: Option<Arc<dyn TerminalView>>) {
|
||||
fn reset(&mut self, view: Option<Arc<dyn TerminalView>>) {
|
||||
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<dyn TerminalView> 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<dyn TerminalView> for CompositeLayer {
|
|||
|
||||
pub struct TerminalCompositeView {
|
||||
idx_count: usize,
|
||||
layers: HashMap<usize, Arc<CompositeLayer>>,
|
||||
layers: HashMap<usize, (Arc<RwLock<CompositeLayer>>, Option<Arc<dyn TerminalView>>)>,
|
||||
range: Option<Range<Point2<i16>>>,
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>
|
||||
}
|
||||
|
@ -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);
|
||||
|
|
|
@ -44,7 +44,7 @@ pub enum TerminalEvent {
|
|||
|
||||
pub struct Terminal {
|
||||
writer: Arc<TermOutWriter>,
|
||||
observer: Arc<TermOutObserver>,
|
||||
observer: Arc<RwLock<TermOutObserver>>,
|
||||
|
||||
events: ChannelReceiver<Vec<TerminalEvent>>,
|
||||
_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<dyn TerminalView> for TermOutObserver {
|
||||
fn reset(&self, view: Option<Arc<dyn TerminalView>>) {
|
||||
fn reset(&mut self, view: Option<Arc<dyn TerminalView>>) {
|
||||
self.writer.reset();
|
||||
|
||||
let (w, h) = termion::terminal_size().unwrap();
|
||||
|
|
Loading…
Reference in a new issue