diff --git a/src/grid/offset.rs b/src/grid/offset.rs index ae5928d..459640d 100644 --- a/src/grid/offset.rs +++ b/src/grid/offset.rs @@ -22,8 +22,7 @@ pub struct GridOffset { cast: Arc>>> } -impl GridOffset -where V::Item: Default { +impl GridOffset { pub fn new(port: InnerViewPort>) -> Arc> { let offset_view = Arc::new(RwLock::new( @@ -52,16 +51,11 @@ impl View for GridOffset { type Msg = Point2; } -impl IndexView> for GridOffset -where V::Item: Default { +impl IndexView> for GridOffset { type Item = V::Item; - fn get(&self, pos: &Point2) -> Self::Item { - if let Some(src) = self.src.as_ref() { - src.get(&(pos - self.offset)) - } else { - Self::Item::default() - } + fn get(&self, pos: &Point2) -> Option { + self.src.as_ref()?.get(&(pos - self.offset)) } fn area(&self) -> Option>> { @@ -74,8 +68,7 @@ where V::Item: Default { } } -impl Observer for GridOffset -where V::Item: Default { +impl Observer for GridOffset { fn reset(&mut self, view: Option>) { let old_area = self.area(); self.src = view; diff --git a/src/index/map_item.rs b/src/index/map_item.rs index 0a3e874..f1d4b59 100644 --- a/src/index/map_item.rs +++ b/src/index/map_item.rs @@ -19,7 +19,7 @@ pub use { impl OuterViewPort> { pub fn map_item< - DstItem: Default + 'static, + DstItem: 'static, F: Fn(&Item) -> DstItem + Send + Sync + 'static >( &self, @@ -43,7 +43,7 @@ where SrcView: IndexView + ?Sized, impl MapIndexItem where Key: 'static, - DstItem: Default + 'static, + DstItem: 'static, SrcView: IndexView + ?Sized + 'static, F: Fn(&SrcView::Item) -> DstItem + Send + Sync + 'static { @@ -72,18 +72,13 @@ where SrcView: IndexView + ?Sized, } impl IndexView for MapIndexItem -where DstItem: Default, - SrcView: IndexView + ?Sized, +where SrcView: IndexView + ?Sized, F: Fn(&SrcView::Item) -> DstItem + Send + Sync { type Item = DstItem; - fn get(&self, key: &Key) -> Self::Item { - if let Some(v) = self.src_view.as_ref() { - (self.f)(&v.get(key)) - } else { - DstItem::default() - } + fn get(&self, key: &Key) -> Option { + self.src_view.as_ref()?.get(key).as_ref().map(&self.f) } fn area(&self) -> Option> { @@ -92,8 +87,7 @@ where DstItem: Default, } impl Observer for MapIndexItem -where DstItem: Default, - SrcView: IndexView + ?Sized, +where SrcView: IndexView + ?Sized, F: Fn(&SrcView::Item) -> DstItem + Send + Sync { fn reset(&mut self, view: Option>) { diff --git a/src/index/map_key.rs b/src/index/map_key.rs index 73cdce8..8138c3b 100644 --- a/src/index/map_key.rs +++ b/src/index/map_key.rs @@ -17,7 +17,7 @@ pub use { } }; -impl OuterViewPort> { +impl OuterViewPort> { pub fn map_key< DstKey: 'static, F1: Fn(&SrcKey) -> DstKey + Send + Sync + 'static, @@ -49,7 +49,7 @@ impl MapIndexKey + ?Sized + 'static, - SrcView::Item: Default + 'static, + SrcView::Item: 'static, F1: Fn(&SrcKey) -> DstKey + Send + Sync + 'static, F2: Fn(&DstKey) -> Option + Send + Sync + 'static, { @@ -82,18 +82,13 @@ where SrcView: IndexView + ?Sized, impl IndexView for MapIndexKey where SrcView: IndexView + ?Sized, - SrcView::Item: Default, F1: Fn(&SrcKey) -> DstKey + Send + Sync, F2: Fn(&DstKey) -> Option + Send + Sync, { type Item = SrcView::Item; - fn get(&self, key: &DstKey) -> Self::Item { - if let (Some(v), Some(k)) = (self.src_view.as_ref(), (self.f2)(key)) { - v.get(&k) - } else { - Self::Item::default() - } + fn get(&self, key: &DstKey) -> Option { + self.src_view.as_ref()?.get(&(self.f2)(key)?) } fn area(&self) -> Option> { @@ -103,7 +98,6 @@ where SrcView: IndexView + ?Sized, impl Observer for MapIndexKey where SrcView: IndexView + ?Sized, - SrcView::Item: Default, F1: Fn(&SrcKey) -> DstKey + Send + Sync, F2: Fn(&DstKey) -> Option + Send + Sync, { diff --git a/src/index/mod.rs b/src/index/mod.rs index 2ad17c7..8bcf20b 100644 --- a/src/index/mod.rs +++ b/src/index/mod.rs @@ -15,7 +15,7 @@ use { pub trait IndexView : View { type Item; - fn get(&self, key: &Key) -> Self::Item; + fn get(&self, key: &Key) -> Option; // todo: AreaIterator enum to switch between Allocated and Procedural area fn area(&self) -> Option> { @@ -28,7 +28,7 @@ pub trait IndexView : View { impl> IndexView for RwLock { type Item = V::Item; - fn get(&self, key: &Key) -> Self::Item { + fn get(&self, key: &Key) -> Option { self.read().unwrap().get(key) } @@ -40,7 +40,7 @@ impl> IndexView for RwLock { impl> IndexView for Arc { type Item = V::Item; - fn get(&self, key: &Key) -> Self::Item { + fn get(&self, key: &Key) -> Option { self.deref().get(key) } @@ -55,7 +55,7 @@ pub trait ImplIndexView : Send + Sync { type Key; type Value; - fn get(&self, key: &Self::Key) -> Self::Value; + fn get(&self, key: &Self::Key) -> Option; fn area(&self) -> Option> { None } @@ -68,7 +68,7 @@ impl View for V { impl IndexView for V { type Item = V::Value; - fn get(&self, key: &V::Key) -> Self::Item { + fn get(&self, key: &V::Key) -> Option { (self as &V).get(key) } diff --git a/src/main.rs b/src/main.rs index 878bba1..7b858a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -59,11 +59,6 @@ async fn main() { let edit_port = ViewPort::::new(); let mut editor = string_editor::StringEditor::new(edit_port.inner()); - compositor.push(edit_port.outer().map_key( - |pt| pt + Vector2::new(4, 2), - |pt| Some(pt - Vector2::new(4, 2)) - )); - let edit_offset_port = ViewPort::::new(); let edit_o = GridOffset::new(edit_offset_port.inner()); @@ -73,32 +68,11 @@ async fn main() { edit_offset_port .into_outer() // add a nice black background - .map_item(|atom| atom.map( - |a| a.add_style_back(TerminalStyle::bg_color((0,0,0))))) + .map_item(|a| a.add_style_back(TerminalStyle::bg_color((0,0,0)))) ); edit_o.write().unwrap().set_offset(Vector2::new(40, 4)); - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - // stupid label animation - let label_port = ViewPort::::new(); - compositor.push( - label_port.outer() - .map_item( - |atom| atom.map(|atom| - atom.add_style_back(TerminalStyle::fg_color((255, 255, 255))) - .add_style_back(TerminalStyle::bg_color((0, 0, 0)))) - ) - ); - task::spawn(async move { - loop { - label_port.set_view(Some(Arc::new(TermLabel(String::from("Hello"))))); - task::sleep(std::time::Duration::from_secs(1)).await; - label_port.set_view(Some(Arc::new(TermLabel(String::from("I'm a dynamic label"))))); - task::sleep(std::time::Duration::from_secs(1)).await; - } - }); - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> // Vec-Buffer let vec_port = ViewPort::new(); @@ -115,7 +89,7 @@ async fn main() { |pt: &Point2| if pt.y == 0 { Some(pt.x as usize) } else { None } ) .map_item( - |c| Some(TerminalAtom::new(c.clone()?, TerminalStyle::fg_color((200, 10, 10)))) + |c| TerminalAtom::new(*c, TerminalStyle::fg_color((200, 10, 10))) ); compositor.push(vec_term_view); @@ -123,6 +97,8 @@ async fn main() { vec_buf.push('a'); vec_buf.push('b'); vec_buf.push('c'); + vec_buf.insert(1, 'x'); + vec_buf.remove(2); /*\ <<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -151,6 +127,7 @@ async fn main() { Terminal Rendering <<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> \*/ + term_writer.show().await.ok(); } @@ -158,7 +135,7 @@ async fn main() { struct Checkerboard; impl ImplIndexView for Checkerboard { type Key = Point2; - type Value = Option; + type Value = TerminalAtom; fn get(&self, pos: &Point2) -> Option { if pos.x == 0 || pos.x == 1 || pos.x > 17 || pos.y == 0 || pos.y > 8 { @@ -183,7 +160,7 @@ impl ImplIndexView for Checkerboard { struct TermLabel(String); impl ImplIndexView for TermLabel { type Key = Point2; - type Value = Option; + type Value = TerminalAtom; fn get(&self, pos: &Point2) -> Option { if pos.y == 5 { @@ -206,7 +183,7 @@ impl ImplIndexView for TermLabel { struct ScrambleBackground; impl ImplIndexView for ScrambleBackground { type Key = Point2; - type Value = Option; + type Value = TerminalAtom; fn get(&self, pos: &Point2) -> Option { if ((pos.x/2) % 2 == 0) ^ (pos.y % 2 == 0) { diff --git a/src/sequence/mod.rs b/src/sequence/mod.rs index 813ad2d..e80e98a 100644 --- a/src/sequence/mod.rs +++ b/src/sequence/mod.rs @@ -14,7 +14,7 @@ use crate::core::View; pub trait SequenceView : View { type Item; - fn get(&self, idx: usize) -> Self::Item; + fn get(&self, idx: &usize) -> Option; fn len(&self) -> Option; } @@ -28,7 +28,7 @@ use std::{ impl SequenceView for RwLock { type Item = V::Item; - fn get(&self, idx: usize) -> Self::Item { + fn get(&self, idx: &usize) -> Option { self.read().unwrap().get(idx) } @@ -40,7 +40,7 @@ impl SequenceView for RwLock { impl SequenceView for Arc { type Item = V::Item; - fn get(&self, idx: usize) -> Self::Item { + fn get(&self, idx: &usize) -> Option { self.deref().get(idx) } diff --git a/src/sequence/seq2idx.rs b/src/sequence/seq2idx.rs index 78134cd..c42af0b 100644 --- a/src/sequence/seq2idx.rs +++ b/src/sequence/seq2idx.rs @@ -16,13 +16,13 @@ use { pub struct Sequence2Index where SrcView: SequenceView + ?Sized + 'static { src_view: Option>, - cast: Arc>>>> + cast: Arc>>> } impl Sequence2Index where SrcView: SequenceView + ?Sized + 'static { pub fn new( - port: InnerViewPort>> + port: InnerViewPort> ) -> Arc> { let s2i = Arc::new(RwLock::new( Sequence2Index { @@ -36,7 +36,7 @@ where SrcView: SequenceView + ?Sized + 'static { } impl OuterViewPort> { - pub fn to_index(&self) -> OuterViewPort>> { + pub fn to_index(&self) -> OuterViewPort> { let port = ViewPort::new(); self.add_observer(Sequence2Index::new(port.inner())); port.into_outer() @@ -50,24 +50,15 @@ where SrcView: SequenceView + ?Sized + 'static { impl IndexView for Sequence2Index where SrcView: SequenceView + ?Sized + 'static { - type Item = Option; + type Item = SrcView::Item; - fn get(&self, key: &usize) -> Self::Item { - if let Some(v) = self.src_view.as_ref() { - if *key < v.len().unwrap_or(usize::MAX) { - return Some(v.get(*key)); - } - } - None + fn get(&self, key: &usize) -> Option { + self.src_view.as_ref()?.get(key) } fn area(&self) -> Option> { - if let Some(v) = self.src_view.as_ref() { - if let Some(len) = v.len() { - return Some((0 .. len).collect()); - } - } - None + let len = self.src_view.as_ref()?.len()?; + Some((0 .. len).collect()) } } diff --git a/src/sequence/vec_buffer.rs b/src/sequence/vec_buffer.rs index 3543b9e..ce6cd6f 100644 --- a/src/sequence/vec_buffer.rs +++ b/src/sequence/vec_buffer.rs @@ -65,8 +65,9 @@ where T: Clone + Send + Sync + 'static { *l += 1; }, VecDiff::Remove(idx) => { - self.cast.notify(&idx); - *self.cur_len.write().unwrap() -= 1; + let mut l = self.cur_len.write().unwrap(); + *l -= 1; + self.cast.notify_each(*idx .. *l+1); }, VecDiff::Insert{ idx, val: _ } => { let mut l = self.cur_len.write().unwrap(); @@ -89,9 +90,10 @@ impl SequenceView for VecSequence where T: Clone + Send + Sync + 'static { type Item = T; - fn get(&self, idx: usize) -> T { - self.data.as_ref().unwrap() - .read().unwrap()[idx].clone() + fn get(&self, idx: &usize) -> Option { + self.data.as_ref()? + .read().unwrap() + .get(*idx).cloned() } fn len(&self) -> Option { diff --git a/src/string_editor.rs b/src/string_editor.rs index 91c6d72..7b20a89 100644 --- a/src/string_editor.rs +++ b/src/string_editor.rs @@ -26,7 +26,7 @@ pub struct StringEditorState { impl ImplIndexView for StringEditorState { type Key = Point2; - type Value = Option; + type Value = TerminalAtom; fn get(&self, pos: &Point2) -> Option { let data = self.data.read().unwrap(); diff --git a/src/terminal/compositor.rs b/src/terminal/compositor.rs index 8352e7e..a52b153 100644 --- a/src/terminal/compositor.rs +++ b/src/terminal/compositor.rs @@ -55,7 +55,7 @@ pub struct TerminalCompositeView { impl ImplIndexView for TerminalCompositeView { type Key = Point2; - type Value = Option; + type Value = TerminalAtom; fn get(&self, pos: &Point2) -> Option { let mut atom = None; diff --git a/src/terminal/mod.rs b/src/terminal/mod.rs index 1d02f02..65d8f8a 100644 --- a/src/terminal/mod.rs +++ b/src/terminal/mod.rs @@ -18,7 +18,7 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -pub trait TerminalView = GridView>; +pub trait TerminalView = GridView; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>