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 {
|
use {
|
||||||
crate::core::View,
|
crate::core::View,
|
||||||
std::{
|
std::{
|
||||||
ops::Deref,
|
ops::{Deref, DerefMut},
|
||||||
sync::{Arc, Weak, RwLock}
|
sync::{Arc, Weak, RwLock}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -12,24 +12,22 @@ use {
|
||||||
<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
\*/
|
\*/
|
||||||
pub trait Observer<V: View + ?Sized> : Send + Sync {
|
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);
|
fn notify(&self, msg: &V::Msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
impl<V: View + ?Sized, O: Observer<V>> Observer<V> for RwLock<O> {
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
fn notify(&self, msg: &V::Msg) {
|
fn notify(&self, msg: &V::Msg) {
|
||||||
self.read().unwrap().notify(&msg);
|
self.read().unwrap().notify(&msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: View + ?Sized, O: Observer<V>> Observer<V> for Arc<O> {
|
|
||||||
fn notify(&self, msg: &V::Msg) {
|
|
||||||
self.deref().notify(&msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
pub trait ObserverExt<V: View + ?Sized> : Observer<V> {
|
pub trait ObserverExt<V: View + ?Sized> : Observer<V> {
|
||||||
|
@ -51,7 +49,7 @@ impl<V: View + ?Sized, T: Observer<V>> ObserverExt<V> for T {
|
||||||
\*/
|
\*/
|
||||||
|
|
||||||
pub struct ObserverBroadcast<V: View + ?Sized> {
|
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> {
|
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.cleanup();
|
||||||
self.observers.push(obs);
|
self.observers.push(obs);
|
||||||
}
|
}
|
||||||
|
@ -70,21 +68,21 @@ impl<V: View + ?Sized> ObserverBroadcast<V> {
|
||||||
self.observers.retain(|o| o.strong_count() > 0);
|
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())
|
self.observers.iter().filter_map(|o| o.upgrade())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: View + ?Sized> Observer<V> for ObserverBroadcast<V> {
|
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() {
|
for o in self.iter() {
|
||||||
o.reset(view.clone());
|
o.write().unwrap().reset(view.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn notify(&self, msg: &V::Msg) {
|
fn notify(&self, msg: &V::Msg) {
|
||||||
for o in self.iter() {
|
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,
|
where V: View + ?Sized,
|
||||||
F: Fn(Option<Arc<V>>) + Send + Sync {
|
F: Fn(Option<Arc<V>>) + Send + Sync {
|
||||||
fn notify(&self, msg: &V::Msg) {}
|
fn notify(&self, msg: &V::Msg) {}
|
||||||
fn reset(&self, view: Option<Arc<V>>) {
|
fn reset(&mut self, view: Option<Arc<V>>) {
|
||||||
(self.f)(view);
|
(self.f)(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,12 @@ impl<V: View + ?Sized> ViewPort<V> {
|
||||||
|
|
||||||
pub fn set_view(&self, view: Option<Arc<V>>) {
|
pub fn set_view(&self, view: Option<Arc<V>>) {
|
||||||
*self.view.write().unwrap() = view.clone();
|
*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));
|
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> {
|
pub fn inner(&self) -> InnerViewPort<V> {
|
||||||
|
@ -106,7 +106,7 @@ impl<V: View + ?Sized + 'static> OuterViewPort<V> {
|
||||||
self.0.view.clone()
|
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.0.add_observer(observer);
|
||||||
self.get_view_arc()
|
self.get_view_arc()
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,19 +15,17 @@ use {
|
||||||
|
|
||||||
struct CompositeLayer {
|
struct CompositeLayer {
|
||||||
comp: Weak<RwLock<TerminalCompositeView>>,
|
comp: Weak<RwLock<TerminalCompositeView>>,
|
||||||
idx: usize,
|
idx: usize
|
||||||
view: RwLock<Option<Arc<dyn TerminalView>>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Observer<dyn TerminalView> for CompositeLayer {
|
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 comp = self.comp.upgrade().unwrap();
|
||||||
let mut c = comp.write().unwrap();
|
let mut c = comp.write().unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut v = self.view.write().unwrap();
|
let old_view = c.layers[&self.idx].1.clone();
|
||||||
let old_view = v.clone();
|
c.layers.get_mut(&self.idx).unwrap().1 = view.clone();
|
||||||
*v = view.clone();
|
|
||||||
|
|
||||||
if let Some(old_view) = old_view {
|
if let Some(old_view) = old_view {
|
||||||
if let Some(range) = old_view.range() {
|
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() {
|
if let Some(range) = view.range() {
|
||||||
c.cast.notify_each(GridWindowIterator::from(range));
|
c.cast.notify_each(GridWindowIterator::from(range));
|
||||||
}
|
}
|
||||||
|
@ -55,7 +53,7 @@ impl Observer<dyn TerminalView> for CompositeLayer {
|
||||||
|
|
||||||
pub struct TerminalCompositeView {
|
pub struct TerminalCompositeView {
|
||||||
idx_count: usize,
|
idx_count: usize,
|
||||||
layers: HashMap<usize, Arc<CompositeLayer>>,
|
layers: HashMap<usize, (Arc<RwLock<CompositeLayer>>, Option<Arc<dyn TerminalView>>)>,
|
||||||
range: Option<Range<Point2<i16>>>,
|
range: Option<Range<Point2<i16>>>,
|
||||||
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>
|
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>
|
||||||
}
|
}
|
||||||
|
@ -73,7 +71,7 @@ impl TerminalCompositeView {
|
||||||
Some(new_range),
|
Some(new_range),
|
||||||
Some(old_range)
|
Some(old_range)
|
||||||
) = (
|
) = (
|
||||||
if let Some(view) = layer.view.read().unwrap().clone() {
|
if let Some(view) = layer.1.as_ref() {
|
||||||
view.range().clone()
|
view.range().clone()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -106,7 +104,7 @@ impl ImplIndexView for TerminalCompositeView {
|
||||||
|
|
||||||
for idx in 0 .. self.idx_count {
|
for idx in 0 .. self.idx_count {
|
||||||
if let Some(l) = self.layers.get(&idx) {
|
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 let Some(range) = view.range() {
|
||||||
if pos.x < range.start.x ||
|
if pos.x < range.start.x ||
|
||||||
pos.x >= range.end.x ||
|
pos.x >= range.end.x ||
|
||||||
|
@ -160,13 +158,12 @@ impl TerminalCompositor {
|
||||||
let idx = comp.idx_count;
|
let idx = comp.idx_count;
|
||||||
comp.idx_count += 1;
|
comp.idx_count += 1;
|
||||||
|
|
||||||
let layer = Arc::new(CompositeLayer {
|
let layer = Arc::new(RwLock::new(CompositeLayer {
|
||||||
comp: Arc::downgrade(&self.view),
|
comp: Arc::downgrade(&self.view),
|
||||||
idx: idx,
|
idx: idx
|
||||||
view: RwLock::new(None)
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
comp.layers.insert(idx, layer.clone());
|
comp.layers.insert(idx, (layer.clone(), None));
|
||||||
drop(comp);
|
drop(comp);
|
||||||
|
|
||||||
v.add_observer(layer);
|
v.add_observer(layer);
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub enum TerminalEvent {
|
||||||
|
|
||||||
pub struct Terminal {
|
pub struct Terminal {
|
||||||
writer: Arc<TermOutWriter>,
|
writer: Arc<TermOutWriter>,
|
||||||
observer: Arc<TermOutObserver>,
|
observer: Arc<RwLock<TermOutObserver>>,
|
||||||
|
|
||||||
events: ChannelReceiver<Vec<TerminalEvent>>,
|
events: ChannelReceiver<Vec<TerminalEvent>>,
|
||||||
_signal_handle: signal_hook_async_std::Handle
|
_signal_handle: signal_hook_async_std::Handle
|
||||||
|
@ -62,10 +62,10 @@ impl Terminal {
|
||||||
view: port.get_view_arc()
|
view: port.get_view_arc()
|
||||||
});
|
});
|
||||||
|
|
||||||
let observer = Arc::new(TermOutObserver {
|
let observer = Arc::new(RwLock::new(TermOutObserver {
|
||||||
dirty_pos_tx,
|
dirty_pos_tx,
|
||||||
writer: writer.clone()
|
writer: writer.clone()
|
||||||
});
|
}));
|
||||||
|
|
||||||
port.add_observer(observer.clone());
|
port.add_observer(observer.clone());
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ struct TermOutObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Observer<dyn TerminalView> for 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();
|
self.writer.reset();
|
||||||
|
|
||||||
let (w, h) = termion::terminal_size().unwrap();
|
let (w, h) = termion::terminal_size().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue