buffers: store inner viewport instead of cast

This commit is contained in:
Michael Sippel 2022-06-17 15:48:13 +02:00
parent 0ded47410c
commit 87ed4ef1ca
Signed by: senvas
GPG key ID: F96CF119C34B64A6
8 changed files with 75 additions and 79 deletions

View file

@ -44,12 +44,17 @@ where
self.cast.write().unwrap().reset(view); self.cast.write().unwrap().reset(view);
} }
pub fn get_cast(&self) -> Arc<RwLock<ObserverBroadcast<V>>> {
self.cast.clone()
}
pub fn add_observer(&self, observer: Arc<RwLock<dyn Observer<V>>>) { pub fn add_observer(&self, observer: Arc<RwLock<dyn Observer<V>>>) {
self.update(); self.update();
self.cast self.cast
.write() .write()
.unwrap() .unwrap()
.add_observer(Arc::downgrade(&observer)); .add_observer(Arc::downgrade(&observer));
observer observer
.write() .write()
.unwrap() .unwrap()

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{InnerViewPort, Observer, ObserverBroadcast, View}, core::{InnerViewPort, ViewPort, Observer, ObserverBroadcast, View},
index::{IndexArea, IndexView}, index::{IndexArea, IndexView},
}, },
std::sync::RwLock, std::sync::RwLock,
@ -42,7 +42,7 @@ where
Item: Clone + Send + Sync + 'static, Item: Clone + Send + Sync + 'static,
{ {
data: Arc<RwLock<HashMap<Key, Item>>>, data: Arc<RwLock<HashMap<Key, Item>>>,
cast: Arc<RwLock<ObserverBroadcast<dyn IndexView<Key, Item = Item>>>>, port: InnerViewPort<dyn IndexView<Key, Item = Item>>,
} }
impl<Key, Item> IndexBuffer<Key, Item> impl<Key, Item> IndexBuffer<Key, Item>
@ -50,19 +50,23 @@ where
Key: Clone + Hash + Eq + Send + Sync + 'static, Key: Clone + Hash + Eq + Send + Sync + 'static,
Item: Clone + Send + Sync + 'static, Item: Clone + Send + Sync + 'static,
{ {
pub fn new(port: InnerViewPort<dyn IndexView<Key, Item = Item>>) -> Self { pub fn with_port(port: InnerViewPort<dyn IndexView<Key, Item = Item>>) -> Self {
let data = Arc::new(RwLock::new(HashMap::<Key, Item>::new())); let data = Arc::new(RwLock::new(HashMap::<Key, Item>::new()));
port.set_view(Some(Arc::new(IndexBufferView(data.clone())))); port.set_view(Some(Arc::new(IndexBufferView(data.clone()))));
IndexBuffer { IndexBuffer {
data, data,
cast: port.get_broadcast(), port
} }
} }
pub fn new() -> Self {
IndexBuffer::with_port(ViewPort::new().into_inner())
}
pub fn insert(&mut self, key: Key, item: Item) { pub fn insert(&mut self, key: Key, item: Item) {
self.data.write().unwrap().insert(key.clone(), item); self.data.write().unwrap().insert(key.clone(), item);
self.cast.notify(&IndexArea::Set(vec![key])); self.port.notify(&IndexArea::Set(vec![key]));
} }
pub fn insert_iter<T>(&mut self, iter: T) pub fn insert_iter<T>(&mut self, iter: T)
@ -76,6 +80,6 @@ where
pub fn remove(&mut self, key: Key) { pub fn remove(&mut self, key: Key) {
self.data.write().unwrap().remove(&key); self.data.write().unwrap().remove(&key);
self.cast.notify(&IndexArea::Set(vec![key])); self.port.notify(&IndexArea::Set(vec![key]));
} }
} }

View file

@ -51,7 +51,7 @@ impl Add {
radix, radix,
a: proj_helper.new_sequence_arg(0, a, |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()), b: proj_helper.new_sequence_arg(1, b, |s: &mut Self, _digit_idx| s.update()),
c: VecBuffer::new(c), c: VecBuffer::with_port(c),
_proj_helper: proj_helper, _proj_helper: proj_helper,
})); }));
add add

View file

@ -1,8 +1,8 @@
use { use {
crate::{ crate::{
core::{OuterViewPort, ViewPort}, core::{OuterViewPort, ViewPort},
list::{sexpr::ListDecoration, ListEditor}, list::{PTYListEditor},
sequence::{SequenceView, SequenceViewExt}, sequence::{SequenceView, SequenceViewExt, decorator::{PTYSeqDecorate, SeqDecorStyle}},
singleton::{SingletonBuffer, SingletonView}, singleton::{SingletonBuffer, SingletonView},
terminal::{ terminal::{
TerminalAtom, TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalStyle, TerminalAtom, TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalStyle,
@ -13,29 +13,27 @@ use {
std::sync::Arc, std::sync::Arc,
std::sync::RwLock, std::sync::RwLock,
termion::event::{Event, Key}, termion::event::{Event, Key},
cgmath::Vector2
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct DigitEditor { pub struct DigitEditor {
radix: u32, radix: u32,
data: SingletonBuffer<Option<char>>, data: SingletonBuffer<Option<char>>
data_port: ViewPort<dyn SingletonView<Item = Option<char>>>,
} }
impl DigitEditor { impl DigitEditor {
pub fn new(radix: u32) -> Self { pub fn new(radix: u32) -> Self {
let data_port = ViewPort::new();
DigitEditor { DigitEditor {
radix, radix,
data: SingletonBuffer::new(None, data_port.inner()), data: SingletonBuffer::new(None),
data_port,
} }
} }
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> { pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
let radix = self.radix; let radix = self.radix;
self.data_port.outer().map(move |c| c?.to_digit(radix)) self.data.get_port().map(move |c| c?.to_digit(radix))
} }
} }
@ -43,8 +41,8 @@ impl TreeNav for DigitEditor {}
impl TerminalEditor for DigitEditor { impl TerminalEditor for DigitEditor {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> { fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
let radix = self.radix; let radix = self.radix;
self.data_port self.data
.outer() .get_port()
.map(move |c| { .map(move |c| {
TerminalAtom::new( TerminalAtom::new(
c.unwrap_or('?'), c.unwrap_or('?'),
@ -81,24 +79,24 @@ impl TerminalTreeEditor for DigitEditor {}
pub struct PosIntEditor { pub struct PosIntEditor {
radix: u32, radix: u32,
digits_editor: digits_editor: PTYListEditor<DigitEditor>
ListEditor<DigitEditor, Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync + 'static>>,
} }
impl PosIntEditor { impl PosIntEditor {
pub fn new(radix: u32) -> Self { pub fn new(radix: u32) -> Self {
PosIntEditor { PosIntEditor {
radix, radix,
digits_editor: ListEditor::new( digits_editor: PTYListEditor::new(
Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))), Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))),
crate::list::ListEditorStyle::Hex, SeqDecorStyle::Hex,
0
), ),
} }
} }
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> { pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = u32>> {
let radix = self.radix; let radix = self.radix;
self.digits_editor self.digits_editor.editor
.get_data_port() .get_data_port()
.filter_map(move |digit_editor| { .filter_map(move |digit_editor| {
digit_editor.read().unwrap().data.get()?.to_digit(radix) digit_editor.read().unwrap().data.get()?.to_digit(radix)
@ -132,44 +130,17 @@ impl TreeNav for PosIntEditor {
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult { fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
self.digits_editor.goto(cur) self.digits_editor.goto(cur)
} }
fn goto_home(&mut self) -> TreeNavResult { fn goby(&mut self, cur: Vector2<isize>) -> TreeNavResult {
self.digits_editor.goto_home() self.digits_editor.goby(cur)
}
fn goto_end(&mut self) -> TreeNavResult {
self.digits_editor.goto_end()
}
fn pxev(&mut self) -> TreeNavResult {
self.digits_editor.pxev()
}
fn nexd(&mut self) -> TreeNavResult {
self.digits_editor.nexd()
}
fn up(&mut self) -> TreeNavResult {
self.digits_editor.up()
}
fn dn(&mut self) -> TreeNavResult {
self.digits_editor.dn()
} }
} }
impl TerminalEditor for PosIntEditor { impl TerminalEditor for PosIntEditor {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> { fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
self.digits_editor self.digits_editor.editor
.get_seg_seq_view() .get_seg_seq_view()
.decorate( .pty_decorate(SeqDecorStyle::Hex, 0)
match self.radix {
2 => "0b",
8 => "0o",
10 => "0d",
16 => "0x",
_ => "",
},
"",
"",
0,
)
.to_grid_horizontal()
.flatten()
} }
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {

View file

@ -26,7 +26,7 @@ impl RadixProjection {
src_radix, src_radix,
dst_radix, dst_radix,
src_digits: None, src_digits: None,
dst_digits: RwLock::new(VecBuffer::new(dst_digits)), dst_digits: RwLock::new(VecBuffer::with_port(dst_digits)),
})); }));
src_digits.add_observer(proj.clone()); src_digits.add_observer(proj.clone());
proj proj

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{InnerViewPort, Observer, ObserverBroadcast, View}, core::{InnerViewPort, OuterViewPort, Observer, ObserverBroadcast, View, ViewPort},
singleton::SingletonView, singleton::SingletonView,
}, },
std::sync::RwLock, std::sync::RwLock,
@ -40,23 +40,31 @@ where
T: Clone + Send + Sync + 'static, T: Clone + Send + Sync + 'static,
{ {
value: Arc<RwLock<T>>, value: Arc<RwLock<T>>,
cast: Arc<RwLock<ObserverBroadcast<dyn SingletonView<Item = T>>>>, port: InnerViewPort<dyn SingletonView<Item = T>>
} }
impl<T> SingletonBuffer<T> impl<T> SingletonBuffer<T>
where where
T: Clone + Send + Sync + 'static, T: Clone + Send + Sync + 'static,
{ {
pub fn new(value: T, port: InnerViewPort<dyn SingletonView<Item = T>>) -> Self { pub fn with_port(value: T, port: InnerViewPort<dyn SingletonView<Item = T>>) -> Self {
let value = Arc::new(RwLock::new(value)); let value = Arc::new(RwLock::new(value));
port.set_view(Some(Arc::new(SingletonBufferView(value.clone())))); port.set_view(Some(Arc::new(SingletonBufferView(value.clone()))));
SingletonBuffer { SingletonBuffer {
value, value,
cast: port.get_broadcast(), port
} }
} }
pub fn new(value: T) -> Self {
SingletonBuffer::with_port(value, ViewPort::new().into_inner())
}
pub fn get_port(&self) -> OuterViewPort<dyn SingletonView<Item = T>> {
self.port.0.outer()
}
pub fn get(&self) -> T { pub fn get(&self) -> T {
self.value.read().unwrap().clone() self.value.read().unwrap().clone()
} }
@ -72,7 +80,7 @@ where
let mut v = self.value.write().unwrap(); let mut v = self.value.write().unwrap();
*v = new_value; *v = new_value;
drop(v); drop(v);
self.cast.notify(&()); self.port.notify(&());
} }
} }

View file

@ -28,10 +28,10 @@ pub fn read_ansi_from<R: Read + Unpin>(
let offset_port = ViewPort::<dyn SingletonView<Item = Vector2<i16>>>::new(); let offset_port = ViewPort::<dyn SingletonView<Item = Vector2<i16>>>::new();
let mut performer = PerfAtom { let mut performer = PerfAtom {
buf: IndexBuffer::new(buf_port.inner()), buf: IndexBuffer::with_port(buf_port.inner()),
size: SingletonBuffer::new(max_size, size_port.inner()), size: SingletonBuffer::with_port(max_size, size_port.inner()),
offset: SingletonBuffer::new(Vector2::new(0, 0), offset_port.inner()), offset: SingletonBuffer::with_port(Vector2::new(0, 0), offset_port.inner()),
cursor: SingletonBuffer::new(Point2::new(0, 0), cursor_port.inner()), cursor: SingletonBuffer::with_port(Point2::new(0, 0), cursor_port.inner()),
cursty: TerminalStyle::default(), cursty: TerminalStyle::default(),
curinv: false, curinv: false,
cursav: Point2::new(0, 0), cursav: Point2::new(0, 0),

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{InnerViewPort, Observer, ObserverBroadcast, View}, core::{InnerViewPort, OuterViewPort, Observer, ObserverBroadcast, View, ViewPort},
vec::VecDiff, vec::VecDiff,
}, },
std::sync::RwLock, std::sync::RwLock,
@ -27,7 +27,7 @@ where
T: Clone + Send + Sync + 'static, T: Clone + Send + Sync + 'static,
{ {
data: Arc<RwLock<Vec<T>>>, data: Arc<RwLock<Vec<T>>>,
cast: Arc<RwLock<ObserverBroadcast<RwLock<Vec<T>>>>>, port: InnerViewPort<RwLock<Vec<T>>>
} }
impl<T> VecBuffer<T> impl<T> VecBuffer<T>
@ -35,23 +35,31 @@ where
T: Clone + Send + Sync + 'static, T: Clone + Send + Sync + 'static,
{ {
pub fn with_data(data: Vec<T>, port: InnerViewPort<RwLock<Vec<T>>>) -> Self { pub fn with_data(data: Vec<T>, port: InnerViewPort<RwLock<Vec<T>>>) -> Self {
let mut b = VecBuffer::new(port); let data = Arc::new(RwLock::new(data));
for x in data.into_iter() {
b.push(x);
}
b
}
pub fn new(port: InnerViewPort<RwLock<Vec<T>>>) -> Self {
let data = Arc::new(RwLock::new(Vec::new()));
port.set_view(Some(data.clone())); port.set_view(Some(data.clone()));
for x in data.read().unwrap().iter().cloned() {
port.notify(&VecDiff::Push(x));
}
VecBuffer { VecBuffer {
data, data,
cast: port.get_broadcast(), port
} }
} }
pub fn with_port(port: InnerViewPort<RwLock<Vec<T>>>) -> Self {
VecBuffer::with_data(vec![], port)
}
pub fn new() -> Self {
VecBuffer::with_port(ViewPort::new().into_inner())
}
pub fn get_port(&self) -> OuterViewPort<RwLock<Vec<T>>> {
self.port.0.outer()
}
pub fn apply_diff(&mut self, diff: VecDiff<T>) { pub fn apply_diff(&mut self, diff: VecDiff<T>) {
let mut data = self.data.write().unwrap(); let mut data = self.data.write().unwrap();
match &diff { match &diff {
@ -73,7 +81,7 @@ where
} }
drop(data); drop(data);
self.cast.notify(&diff); self.port.notify(&diff);
} }
pub fn len(&self) -> usize { pub fn len(&self) -> usize {