From 5eefcbb4d1713c2b3d5636e290729a5ab46e94a5 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Tue, 24 Aug 2021 23:15:18 +0200 Subject: [PATCH] projection: remove_arg --- nested/src/grid/flatten.rs | 7 ++-- nested/src/integer/add.rs | 6 ++-- nested/src/leveled_term_view.rs | 3 +- nested/src/list/editor.rs | 4 ++- nested/src/list/sexpr.rs | 8 ++--- nested/src/projection.rs | 53 +++++++++++++++++++++++-------- nested/src/sequence/flatten.rs | 6 ++-- nested/src/terminal/compositor.rs | 4 ++- 8 files changed, 63 insertions(+), 28 deletions(-) diff --git a/nested/src/grid/flatten.rs b/nested/src/grid/flatten.rs index 7ffeceb..9792f7c 100644 --- a/nested/src/grid/flatten.rs +++ b/nested/src/grid/flatten.rs @@ -42,7 +42,7 @@ where Item: 'static top: Arc>>>, chunks: HashMap, Chunk>, cast: Arc>>>, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper, Self> } impl View for Flatten @@ -81,6 +81,7 @@ where Item: 'static Flatten { limit: Point2::new(0, 0), top: proj_helper.new_index_arg( + Point2::new(-1, -1), top_port, |s: &mut Self, chunk_idx| { s.update_chunk(*chunk_idx); @@ -101,6 +102,7 @@ where Item: 'static fn update_chunk(&mut self, chunk_idx: Point2) { if let Some(chunk_port) = self.top.get(&chunk_idx) { let view = self.proj_helper.new_index_arg( + chunk_idx, chunk_port.clone(), move |s: &mut Self, idx| { if let Some(chunk) = s.chunks.get(&chunk_idx) { @@ -134,8 +136,7 @@ where Item: 'static self.update_all_offsets(); chunk_port.0.update(); } else { - // todo: - //self.proj_helper.remove_arg(); + self.proj_helper.remove_arg(&chunk_idx); let mut dirty_idx = Vec::new(); if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { diff --git a/nested/src/integer/add.rs b/nested/src/integer/add.rs index 7955dcb..2a9f22a 100644 --- a/nested/src/integer/add.rs +++ b/nested/src/integer/add.rs @@ -44,7 +44,7 @@ pub struct Add { a: Arc>, // PosInt, Little Endian b: Arc>, // PosInt, Little Endian c: VecBuffer, - _proj_helper: ProjectionHelper + _proj_helper: ProjectionHelper } impl Add { @@ -58,8 +58,8 @@ impl Add { let add = Arc::new(RwLock::new( Add { radix, - a: proj_helper.new_sequence_arg(a, |s: &mut Self, _digit_idx| s.update()), - b: proj_helper.new_sequence_arg(b, |s: &mut Self, _digit_idx| s.update()), + a: proj_helper.new_sequence_arg(0, a, |s: &mut Self, _digit_idx| s.update()), + b: proj_helper.new_sequence_arg(1, b, |s: &mut Self, _digit_idx| s.update()), c: VecBuffer::new(c), _proj_helper: proj_helper } diff --git a/nested/src/leveled_term_view.rs b/nested/src/leveled_term_view.rs index 77565dd..919c6f8 100644 --- a/nested/src/leveled_term_view.rs +++ b/nested/src/leveled_term_view.rs @@ -19,7 +19,7 @@ pub struct LeveledTermView { level: usize, cast: Arc>>, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper<(), Self> } impl LeveledTermView { @@ -40,6 +40,7 @@ impl LeveledTermView { let v = Arc::new(RwLock::new( LeveledTermView { src: proj_helper.new_index_arg( + (), src_port, |p: &mut Self, pos: &Point2| { p.cast.notify(pos); diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs index 42e8bc8..c92a4a2 100644 --- a/nested/src/list/editor.rs +++ b/nested/src/list/editor.rs @@ -562,7 +562,7 @@ struct ListEditorView { cur_cursor: Option, cast: Arc>>>, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper } impl View for ListEditorView { @@ -629,6 +629,7 @@ impl ListEditorView { ListEditorView { cur_cursor: None, cursor: proj_helper.new_singleton_arg( + 0, cursor_port, |s: &mut Self, _msg| { let old_cursor = s.cur_cursor; @@ -678,6 +679,7 @@ impl ListEditorView { ); }), data: proj_helper.new_sequence_arg( + 1, data_port, |s: &mut Self, idx| { if let Some(cur) = s.cur_cursor { diff --git a/nested/src/list/sexpr.rs b/nested/src/list/sexpr.rs index f6cae55..73c6d35 100644 --- a/nested/src/list/sexpr.rs +++ b/nested/src/list/sexpr.rs @@ -22,7 +22,7 @@ pub struct ListDecorator { item_style: TerminalStyle, cast: Arc>>>>, - proj_helper: ProjectionHelper, + proj_helper: ProjectionHelper<(), Self>, } impl View for ListDecorator { @@ -77,7 +77,7 @@ impl ListDecorator { opening_port: make_label(opening), closing_port: make_label(closing), delim_port: make_label(delim), - items: proj_helper.new_sequence_arg(items_port, |s: &mut Self, item_idx| { + items: proj_helper.new_sequence_arg((), items_port, |s: &mut Self, item_idx| { s.cast.notify(&(*item_idx * 2 + 1)); s.cast.notify(&(*item_idx * 2 + 2)); }), @@ -137,7 +137,7 @@ pub struct VerticalSexprDecorator { item_style: TerminalStyle, cast: Arc>>>>, - proj_helper: ProjectionHelper, + proj_helper: ProjectionHelper<(), Self>, } impl View for VerticalSexprDecorator { @@ -214,7 +214,7 @@ impl VerticalSexprDecorator { let li = Arc::new(RwLock::new(VerticalSexprDecorator { opening_port: make_label(opening), closing_port: make_label(closing), - items: proj_helper.new_sequence_arg(items_port, |s: &mut Self, item_idx| { + items: proj_helper.new_sequence_arg((), items_port, |s: &mut Self, item_idx| { s.cast.notify(&Point2::new(1, *item_idx as i16)); s.cast.notify(&Point2::new(2, *item_idx as i16 - 1)); s.cast.notify(&Point2::new(2, *item_idx as i16)); diff --git a/nested/src/projection.rs b/nested/src/projection.rs index b0443c3..7ab80bd 100644 --- a/nested/src/projection.rs +++ b/nested/src/projection.rs @@ -3,7 +3,8 @@ use { cmp::{max}, any::Any, sync::{Arc, Weak}, - hash::Hash + hash::Hash, + collections::HashMap }, std::sync::RwLock, crate::{ @@ -26,16 +27,22 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -pub struct ProjectionHelper { - keepalive: Vec>, +pub struct ProjectionHelper +where ArgKey: Clone + Hash + Eq, + P: Send + Sync + 'static +{ + keepalive: HashMap)>, proj: Arc>>>, update_hooks: Arc>>> } -impl ProjectionHelper

{ +impl ProjectionHelper +where ArgKey: Clone + Hash + Eq, + P: Send + Sync + 'static +{ pub fn new(update_hooks: Arc>>>) -> Self { ProjectionHelper { - keepalive: Vec::new(), + keepalive: HashMap::new(), proj: Arc::new(RwLock::new(Weak::new())), update_hooks } @@ -50,31 +57,31 @@ impl ProjectionHelper

{ pub fn new_singleton_arg( &mut self, + arg_key: ArgKey, port: OuterViewPort>, notify: impl Fn(&mut P, &()) + Send + Sync + 'static ) -> Arc>>>> { - self.update_hooks.write().unwrap().push(Arc::new(port.0.clone())); - port.add_observer(self.new_arg(notify, set_channel())); + port.add_observer(self.new_arg(arg_key, Arc::new(port.0.clone()), notify, set_channel())); port.get_view_arc() } pub fn new_sequence_arg( &mut self, + arg_key: ArgKey, port: OuterViewPort>, notify: impl Fn(&mut P, &usize) + Send + Sync + 'static ) -> Arc>>>> { - self.update_hooks.write().unwrap().push(Arc::new(port.0.clone())); - port.add_observer(self.new_arg(notify, set_channel())); + port.add_observer(self.new_arg(arg_key, Arc::new(port.0.clone()), notify, set_channel())); port.get_view_arc() } pub fn new_index_arg( &mut self, + arg_key: ArgKey, port: OuterViewPort>, notify: impl Fn(&mut P, &Key) + Send + Sync + 'static ) -> Arc>>>> { - self.update_hooks.write().unwrap().push(Arc::new(port.0.clone())); - port.add_observer(self.new_arg(notify, set_channel())); + port.add_observer(self.new_arg(arg_key, Arc::new(port.0.clone()), notify, set_channel())); port.get_view_arc() } @@ -83,6 +90,8 @@ impl ProjectionHelper

{ D: ChannelData + 'static >( &mut self, + arg_key: ArgKey, + src_update: Arc, notify: impl Fn(&mut P, &V::Msg) + Send + Sync + 'static, (tx, rx): (ChannelSender, ChannelReceiver) ) @@ -90,6 +99,8 @@ impl ProjectionHelper

{ where V::Msg: Send + Sync + std::fmt::Debug, D::IntoIter: Send + Sync + 'static { + self.remove_arg(&arg_key); + let arg = Arc::new(RwLock::new( ProjectionArg { src: None, @@ -98,11 +109,27 @@ impl ProjectionHelper

{ rx, tx })); - self.keepalive.push(arg.clone()); + let mut hooks = self.update_hooks.write().unwrap(); + let idx = hooks.len(); + hooks.push(src_update); + hooks.push(arg.clone()); + self.keepalive.insert(arg_key, (idx, arg.clone())); - self.update_hooks.write().unwrap().push(arg.clone()); arg } + + pub fn remove_arg(&mut self, arg_key: &ArgKey) { + let mut hooks = self.update_hooks.write().unwrap(); + if let Some((idx, arg)) = self.keepalive.remove(arg_key) { + hooks.remove(idx); + hooks.remove(idx); + for (_, (j, _)) in self.keepalive.iter_mut() { + if *j > idx { + *j -= 2; + } + } + } + } } /// Special Observer which can access the state of the projection on notify diff --git a/nested/src/sequence/flatten.rs b/nested/src/sequence/flatten.rs index e317b8f..e6ca719 100644 --- a/nested/src/sequence/flatten.rs +++ b/nested/src/sequence/flatten.rs @@ -39,7 +39,7 @@ where Item: 'static top: Arc>>>, chunks: BTreeMap>, cast: Arc>>>, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper } impl View for Flatten @@ -77,6 +77,7 @@ where Item: 'static Flatten { length: 0, top: proj_helper.new_sequence_arg( + usize::MAX, top_port, |s: &mut Self, chunk_idx| { s.update_chunk(*chunk_idx); @@ -102,6 +103,7 @@ where Item: 'static offset: 0, // will be adjusted by update_offsets() later len: 0, view: self.proj_helper.new_sequence_arg( + chunk_idx, chunk_port.clone(), move |s: &mut Self, idx| { if let Some(chunk) = s.chunks.get(&chunk_idx) { @@ -127,7 +129,7 @@ where Item: 'static self.cast.notify_each(dirty_idx); } else { // todo: - //self.proj_helper.remove_arg(); + self.proj_helper.remove_arg(&chunk_idx); self.chunks.remove(&chunk_idx); diff --git a/nested/src/terminal/compositor.rs b/nested/src/terminal/compositor.rs index c2d64b3..6c92f0f 100644 --- a/nested/src/terminal/compositor.rs +++ b/nested/src/terminal/compositor.rs @@ -17,7 +17,7 @@ use { pub struct TerminalCompositor { layers: Vec>, cast: Arc>>, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -41,8 +41,10 @@ impl TerminalCompositor { } pub fn push(&mut self, v: OuterViewPort) { + let idx = self.layers.len(); self.layers.push( self.proj_helper.new_index_arg( + idx, v, |s: &mut Self, pos| { s.cast.notify(pos);