buffers: store inner viewport instead of cast
This commit is contained in:
parent
0ded47410c
commit
87ed4ef1ca
8 changed files with 75 additions and 79 deletions
|
@ -44,12 +44,17 @@ where
|
|||
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>>>) {
|
||||
self.update();
|
||||
self.cast
|
||||
.write()
|
||||
.unwrap()
|
||||
.add_observer(Arc::downgrade(&observer));
|
||||
|
||||
observer
|
||||
.write()
|
||||
.unwrap()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{InnerViewPort, Observer, ObserverBroadcast, View},
|
||||
core::{InnerViewPort, ViewPort, Observer, ObserverBroadcast, View},
|
||||
index::{IndexArea, IndexView},
|
||||
},
|
||||
std::sync::RwLock,
|
||||
|
@ -42,7 +42,7 @@ where
|
|||
Item: Clone + Send + Sync + 'static,
|
||||
{
|
||||
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>
|
||||
|
@ -50,19 +50,23 @@ where
|
|||
Key: Clone + Hash + Eq + 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()));
|
||||
port.set_view(Some(Arc::new(IndexBufferView(data.clone()))));
|
||||
|
||||
IndexBuffer {
|
||||
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) {
|
||||
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)
|
||||
|
@ -76,6 +80,6 @@ where
|
|||
|
||||
pub fn remove(&mut self, key: Key) {
|
||||
self.data.write().unwrap().remove(&key);
|
||||
self.cast.notify(&IndexArea::Set(vec![key]));
|
||||
self.port.notify(&IndexArea::Set(vec![key]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ impl Add {
|
|||
radix,
|
||||
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),
|
||||
c: VecBuffer::with_port(c),
|
||||
_proj_helper: proj_helper,
|
||||
}));
|
||||
add
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{OuterViewPort, ViewPort},
|
||||
list::{sexpr::ListDecoration, ListEditor},
|
||||
sequence::{SequenceView, SequenceViewExt},
|
||||
list::{PTYListEditor},
|
||||
sequence::{SequenceView, SequenceViewExt, decorator::{PTYSeqDecorate, SeqDecorStyle}},
|
||||
singleton::{SingletonBuffer, SingletonView},
|
||||
terminal::{
|
||||
TerminalAtom, TerminalEditor, TerminalEditorResult, TerminalEvent, TerminalStyle,
|
||||
|
@ -13,29 +13,27 @@ use {
|
|||
std::sync::Arc,
|
||||
std::sync::RwLock,
|
||||
termion::event::{Event, Key},
|
||||
cgmath::Vector2
|
||||
};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub struct DigitEditor {
|
||||
radix: u32,
|
||||
data: SingletonBuffer<Option<char>>,
|
||||
data_port: ViewPort<dyn SingletonView<Item = Option<char>>>,
|
||||
data: SingletonBuffer<Option<char>>
|
||||
}
|
||||
|
||||
impl DigitEditor {
|
||||
pub fn new(radix: u32) -> Self {
|
||||
let data_port = ViewPort::new();
|
||||
DigitEditor {
|
||||
radix,
|
||||
data: SingletonBuffer::new(None, data_port.inner()),
|
||||
data_port,
|
||||
data: SingletonBuffer::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Option<u32>>> {
|
||||
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 {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
let radix = self.radix;
|
||||
self.data_port
|
||||
.outer()
|
||||
self.data
|
||||
.get_port()
|
||||
.map(move |c| {
|
||||
TerminalAtom::new(
|
||||
c.unwrap_or('?'),
|
||||
|
@ -81,24 +79,24 @@ impl TerminalTreeEditor for DigitEditor {}
|
|||
|
||||
pub struct PosIntEditor {
|
||||
radix: u32,
|
||||
digits_editor:
|
||||
ListEditor<DigitEditor, Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync + 'static>>,
|
||||
digits_editor: PTYListEditor<DigitEditor>
|
||||
}
|
||||
|
||||
impl PosIntEditor {
|
||||
pub fn new(radix: u32) -> Self {
|
||||
PosIntEditor {
|
||||
radix,
|
||||
digits_editor: ListEditor::new(
|
||||
digits_editor: PTYListEditor::new(
|
||||
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>> {
|
||||
let radix = self.radix;
|
||||
self.digits_editor
|
||||
self.digits_editor.editor
|
||||
.get_data_port()
|
||||
.filter_map(move |digit_editor| {
|
||||
digit_editor.read().unwrap().data.get()?.to_digit(radix)
|
||||
|
@ -132,44 +130,17 @@ impl TreeNav for PosIntEditor {
|
|||
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
|
||||
self.digits_editor.goto(cur)
|
||||
}
|
||||
fn goto_home(&mut self) -> TreeNavResult {
|
||||
self.digits_editor.goto_home()
|
||||
}
|
||||
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()
|
||||
fn goby(&mut self, cur: Vector2<isize>) -> TreeNavResult {
|
||||
self.digits_editor.goby(cur)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl TerminalEditor for PosIntEditor {
|
||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.digits_editor
|
||||
self.digits_editor.editor
|
||||
.get_seg_seq_view()
|
||||
.decorate(
|
||||
match self.radix {
|
||||
2 => "0b",
|
||||
8 => "0o",
|
||||
10 => "0d",
|
||||
16 => "0x",
|
||||
_ => "",
|
||||
},
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
)
|
||||
.to_grid_horizontal()
|
||||
.flatten()
|
||||
.pty_decorate(SeqDecorStyle::Hex, 0)
|
||||
}
|
||||
|
||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||
|
|
|
@ -26,7 +26,7 @@ impl RadixProjection {
|
|||
src_radix,
|
||||
dst_radix,
|
||||
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());
|
||||
proj
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{InnerViewPort, Observer, ObserverBroadcast, View},
|
||||
core::{InnerViewPort, OuterViewPort, Observer, ObserverBroadcast, View, ViewPort},
|
||||
singleton::SingletonView,
|
||||
},
|
||||
std::sync::RwLock,
|
||||
|
@ -40,23 +40,31 @@ where
|
|||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
value: Arc<RwLock<T>>,
|
||||
cast: Arc<RwLock<ObserverBroadcast<dyn SingletonView<Item = T>>>>,
|
||||
port: InnerViewPort<dyn SingletonView<Item = T>>
|
||||
}
|
||||
|
||||
impl<T> SingletonBuffer<T>
|
||||
where
|
||||
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));
|
||||
port.set_view(Some(Arc::new(SingletonBufferView(value.clone()))));
|
||||
|
||||
SingletonBuffer {
|
||||
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 {
|
||||
self.value.read().unwrap().clone()
|
||||
}
|
||||
|
@ -72,7 +80,7 @@ where
|
|||
let mut v = self.value.write().unwrap();
|
||||
*v = new_value;
|
||||
drop(v);
|
||||
self.cast.notify(&());
|
||||
self.port.notify(&());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@ pub fn read_ansi_from<R: Read + Unpin>(
|
|||
let offset_port = ViewPort::<dyn SingletonView<Item = Vector2<i16>>>::new();
|
||||
|
||||
let mut performer = PerfAtom {
|
||||
buf: IndexBuffer::new(buf_port.inner()),
|
||||
size: SingletonBuffer::new(max_size, size_port.inner()),
|
||||
offset: SingletonBuffer::new(Vector2::new(0, 0), offset_port.inner()),
|
||||
cursor: SingletonBuffer::new(Point2::new(0, 0), cursor_port.inner()),
|
||||
buf: IndexBuffer::with_port(buf_port.inner()),
|
||||
size: SingletonBuffer::with_port(max_size, size_port.inner()),
|
||||
offset: SingletonBuffer::with_port(Vector2::new(0, 0), offset_port.inner()),
|
||||
cursor: SingletonBuffer::with_port(Point2::new(0, 0), cursor_port.inner()),
|
||||
cursty: TerminalStyle::default(),
|
||||
curinv: false,
|
||||
cursav: Point2::new(0, 0),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use {
|
||||
crate::{
|
||||
core::{InnerViewPort, Observer, ObserverBroadcast, View},
|
||||
core::{InnerViewPort, OuterViewPort, Observer, ObserverBroadcast, View, ViewPort},
|
||||
vec::VecDiff,
|
||||
},
|
||||
std::sync::RwLock,
|
||||
|
@ -27,7 +27,7 @@ where
|
|||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
data: Arc<RwLock<Vec<T>>>,
|
||||
cast: Arc<RwLock<ObserverBroadcast<RwLock<Vec<T>>>>>,
|
||||
port: InnerViewPort<RwLock<Vec<T>>>
|
||||
}
|
||||
|
||||
impl<T> VecBuffer<T>
|
||||
|
@ -35,23 +35,31 @@ where
|
|||
T: Clone + Send + Sync + 'static,
|
||||
{
|
||||
pub fn with_data(data: Vec<T>, port: InnerViewPort<RwLock<Vec<T>>>) -> Self {
|
||||
let mut b = VecBuffer::new(port);
|
||||
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()));
|
||||
let data = Arc::new(RwLock::new(data));
|
||||
port.set_view(Some(data.clone()));
|
||||
|
||||
for x in data.read().unwrap().iter().cloned() {
|
||||
port.notify(&VecDiff::Push(x));
|
||||
}
|
||||
|
||||
VecBuffer {
|
||||
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>) {
|
||||
let mut data = self.data.write().unwrap();
|
||||
match &diff {
|
||||
|
@ -73,7 +81,7 @@ where
|
|||
}
|
||||
drop(data);
|
||||
|
||||
self.cast.notify(&diff);
|
||||
self.port.notify(&diff);
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
|
|
Loading…
Reference in a new issue