projection: remove_arg
This commit is contained in:
parent
2563e06000
commit
5eefcbb4d1
8 changed files with 63 additions and 28 deletions
|
@ -42,7 +42,7 @@ where Item: 'static
|
|||
top: Arc<dyn GridView<Item = OuterViewPort<dyn GridView<Item = Item>>>>,
|
||||
chunks: HashMap<Point2<i16>, Chunk<Item>>,
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn GridView<Item = Item>>>>,
|
||||
proj_helper: ProjectionHelper<Self>
|
||||
proj_helper: ProjectionHelper<Point2<i16>, Self>
|
||||
}
|
||||
|
||||
impl<Item> View for Flatten<Item>
|
||||
|
@ -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<i16>) {
|
||||
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) {
|
||||
|
|
|
@ -44,7 +44,7 @@ pub struct Add {
|
|||
a: Arc<dyn SequenceView<Item = usize>>, // PosInt, Little Endian
|
||||
b: Arc<dyn SequenceView<Item = usize>>, // PosInt, Little Endian
|
||||
c: VecBuffer<usize>,
|
||||
_proj_helper: ProjectionHelper<Self>
|
||||
_proj_helper: ProjectionHelper<usize, Self>
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub struct LeveledTermView {
|
|||
level: usize,
|
||||
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
|
||||
proj_helper: ProjectionHelper<Self>
|
||||
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<i16>| {
|
||||
p.cast.notify(pos);
|
||||
|
|
|
@ -562,7 +562,7 @@ struct ListEditorView {
|
|||
cur_cursor: Option<ListCursor>,
|
||||
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = ListEditorViewSegment>>>>,
|
||||
proj_helper: ProjectionHelper<Self>
|
||||
proj_helper: ProjectionHelper<usize, Self>
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -22,7 +22,7 @@ pub struct ListDecorator {
|
|||
item_style: TerminalStyle,
|
||||
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>>>>,
|
||||
proj_helper: ProjectionHelper<Self>,
|
||||
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<RwLock<ObserverBroadcast<dyn GridView<Item = OuterViewPort<dyn TerminalView>>>>>,
|
||||
proj_helper: ProjectionHelper<Self>,
|
||||
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));
|
||||
|
|
|
@ -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<P: Send + Sync + 'static> {
|
||||
keepalive: Vec<Arc<dyn Any + Send + Sync>>,
|
||||
pub struct ProjectionHelper<ArgKey, P>
|
||||
where ArgKey: Clone + Hash + Eq,
|
||||
P: Send + Sync + 'static
|
||||
{
|
||||
keepalive: HashMap<ArgKey, (usize, Arc<dyn Any + Send + Sync>)>,
|
||||
proj: Arc<RwLock<Weak<RwLock<P>>>>,
|
||||
update_hooks: Arc<RwLock<Vec<Arc<dyn UpdateTask>>>>
|
||||
}
|
||||
|
||||
impl<P: Send + Sync + 'static> ProjectionHelper<P> {
|
||||
impl<ArgKey, P> ProjectionHelper<ArgKey, P>
|
||||
where ArgKey: Clone + Hash + Eq,
|
||||
P: Send + Sync + 'static
|
||||
{
|
||||
pub fn new(update_hooks: Arc<RwLock<Vec<Arc<dyn UpdateTask>>>>) -> Self {
|
||||
ProjectionHelper {
|
||||
keepalive: Vec::new(),
|
||||
keepalive: HashMap::new(),
|
||||
proj: Arc::new(RwLock::new(Weak::new())),
|
||||
update_hooks
|
||||
}
|
||||
|
@ -50,31 +57,31 @@ impl<P: Send + Sync + 'static> ProjectionHelper<P> {
|
|||
|
||||
pub fn new_singleton_arg<Item: 'static>(
|
||||
&mut self,
|
||||
arg_key: ArgKey,
|
||||
port: OuterViewPort<dyn SingletonView<Item = Item>>,
|
||||
notify: impl Fn(&mut P, &()) + Send + Sync + 'static
|
||||
) -> Arc<RwLock<Option<Arc<dyn SingletonView<Item = Item>>>>> {
|
||||
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<Item: 'static>(
|
||||
&mut self,
|
||||
arg_key: ArgKey,
|
||||
port: OuterViewPort<dyn SequenceView<Item = Item>>,
|
||||
notify: impl Fn(&mut P, &usize) + Send + Sync + 'static
|
||||
) -> Arc<RwLock<Option<Arc<dyn SequenceView<Item = Item>>>>> {
|
||||
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<Key: Hash + Eq + Clone + Send + Sync + std::fmt::Debug + 'static, Item: 'static>(
|
||||
&mut self,
|
||||
arg_key: ArgKey,
|
||||
port: OuterViewPort<dyn IndexView<Key, Item = Item>>,
|
||||
notify: impl Fn(&mut P, &Key) + Send + Sync + 'static
|
||||
) -> Arc<RwLock<Option<Arc<dyn IndexView<Key, Item = Item>>>>> {
|
||||
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<P: Send + Sync + 'static> ProjectionHelper<P> {
|
|||
D: ChannelData<Item = V::Msg> + 'static
|
||||
>(
|
||||
&mut self,
|
||||
arg_key: ArgKey,
|
||||
src_update: Arc<dyn UpdateTask>,
|
||||
notify: impl Fn(&mut P, &V::Msg) + Send + Sync + 'static,
|
||||
(tx, rx): (ChannelSender<D>, ChannelReceiver<D>)
|
||||
)
|
||||
|
@ -90,6 +99,8 @@ impl<P: Send + Sync + 'static> ProjectionHelper<P> {
|
|||
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<P: Send + Sync + 'static> ProjectionHelper<P> {
|
|||
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
|
||||
|
|
|
@ -39,7 +39,7 @@ where Item: 'static
|
|||
top: Arc<dyn SequenceView<Item = OuterViewPort<dyn SequenceView<Item = Item>>>>,
|
||||
chunks: BTreeMap<usize, Chunk<Item>>,
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = Item>>>>,
|
||||
proj_helper: ProjectionHelper<Self>
|
||||
proj_helper: ProjectionHelper<usize, Self>
|
||||
}
|
||||
|
||||
impl<Item> View for Flatten<Item>
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ use {
|
|||
pub struct TerminalCompositor {
|
||||
layers: Vec<Arc<dyn TerminalView>>,
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
|
||||
proj_helper: ProjectionHelper<Self>
|
||||
proj_helper: ProjectionHelper<usize, Self>
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
@ -41,8 +41,10 @@ impl TerminalCompositor {
|
|||
}
|
||||
|
||||
pub fn push(&mut self, v: OuterViewPort<dyn TerminalView>) {
|
||||
let idx = self.layers.len();
|
||||
self.layers.push(
|
||||
self.proj_helper.new_index_arg(
|
||||
idx,
|
||||
v,
|
||||
|s: &mut Self, pos| {
|
||||
s.cast.notify(pos);
|
||||
|
|
Loading…
Reference in a new issue