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<V: GridView + ?Sized> { cast: Arc<RwLock<ObserverBroadcast<dyn GridView<Item = V::Item>>>> } -impl<V: 'static + GridView + ?Sized> GridOffset<V> -where V::Item: Default { +impl<V: 'static + GridView + ?Sized> GridOffset<V> { pub fn new(port: InnerViewPort<dyn GridView<Item = V::Item>>) -> Arc<RwLock<Self>> { let offset_view = Arc::new(RwLock::new( @@ -52,16 +51,11 @@ impl<V: GridView + ?Sized> View for GridOffset<V> { type Msg = Point2<i16>; } -impl<V: GridView + ?Sized> IndexView<Point2<i16>> for GridOffset<V> -where V::Item: Default { +impl<V: GridView + ?Sized> IndexView<Point2<i16>> for GridOffset<V> { type Item = V::Item; - fn get(&self, pos: &Point2<i16>) -> Self::Item { - if let Some(src) = self.src.as_ref() { - src.get(&(pos - self.offset)) - } else { - Self::Item::default() - } + fn get(&self, pos: &Point2<i16>) -> Option<Self::Item> { + self.src.as_ref()?.get(&(pos - self.offset)) } fn area(&self) -> Option<Vec<Point2<i16>>> { @@ -74,8 +68,7 @@ where V::Item: Default { } } -impl<V: GridView + ?Sized> Observer<V> for GridOffset<V> -where V::Item: Default { +impl<V: GridView + ?Sized> Observer<V> for GridOffset<V> { fn reset(&mut self, view: Option<Arc<V>>) { 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<Key: 'static, Item: 'static> OuterViewPort<dyn IndexView<Key, Item = Item>> { pub fn map_item< - DstItem: Default + 'static, + DstItem: 'static, F: Fn(&Item) -> DstItem + Send + Sync + 'static >( &self, @@ -43,7 +43,7 @@ where SrcView: IndexView<Key> + ?Sized, impl<Key, DstItem, SrcView, F> MapIndexItem<Key, DstItem, SrcView, F> where Key: 'static, - DstItem: Default + 'static, + DstItem: 'static, SrcView: IndexView<Key> + ?Sized + 'static, F: Fn(&SrcView::Item) -> DstItem + Send + Sync + 'static { @@ -72,18 +72,13 @@ where SrcView: IndexView<Key> + ?Sized, } impl<Key, DstItem, SrcView, F> IndexView<Key> for MapIndexItem<Key, DstItem, SrcView, F> -where DstItem: Default, - SrcView: IndexView<Key> + ?Sized, +where SrcView: IndexView<Key> + ?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::Item> { + self.src_view.as_ref()?.get(key).as_ref().map(&self.f) } fn area(&self) -> Option<Vec<Key>> { @@ -92,8 +87,7 @@ where DstItem: Default, } impl<Key, DstItem, SrcView, F> Observer<SrcView> for MapIndexItem<Key, DstItem, SrcView, F> -where DstItem: Default, - SrcView: IndexView<Key> + ?Sized, +where SrcView: IndexView<Key> + ?Sized, F: Fn(&SrcView::Item) -> DstItem + Send + Sync { fn reset(&mut self, view: Option<Arc<SrcView>>) { 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<SrcKey: 'static, Item: 'static + Default> OuterViewPort<dyn IndexView<SrcKey, Item = Item>> { +impl<SrcKey: 'static, Item: 'static> OuterViewPort<dyn IndexView<SrcKey, Item = Item>> { pub fn map_key< DstKey: 'static, F1: Fn(&SrcKey) -> DstKey + Send + Sync + 'static, @@ -49,7 +49,7 @@ impl<DstKey, SrcKey, SrcView, F1, F2> MapIndexKey<DstKey, SrcKey, SrcView, F1, F where DstKey: 'static, SrcKey: 'static, SrcView: IndexView<SrcKey> + ?Sized + 'static, - SrcView::Item: Default + 'static, + SrcView::Item: 'static, F1: Fn(&SrcKey) -> DstKey + Send + Sync + 'static, F2: Fn(&DstKey) -> Option<SrcKey> + Send + Sync + 'static, { @@ -82,18 +82,13 @@ where SrcView: IndexView<SrcKey> + ?Sized, impl<DstKey, SrcKey, SrcView, F1, F2> IndexView<DstKey> for MapIndexKey<DstKey, SrcKey, SrcView, F1, F2> where SrcView: IndexView<SrcKey> + ?Sized, - SrcView::Item: Default, F1: Fn(&SrcKey) -> DstKey + Send + Sync, F2: Fn(&DstKey) -> Option<SrcKey> + 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::Item> { + self.src_view.as_ref()?.get(&(self.f2)(key)?) } fn area(&self) -> Option<Vec<DstKey>> { @@ -103,7 +98,6 @@ where SrcView: IndexView<SrcKey> + ?Sized, impl<DstKey, SrcKey, SrcView, F1, F2> Observer<SrcView> for MapIndexKey<DstKey, SrcKey, SrcView, F1, F2> where SrcView: IndexView<SrcKey> + ?Sized, - SrcView::Item: Default, F1: Fn(&SrcKey) -> DstKey + Send + Sync, F2: Fn(&DstKey) -> Option<SrcKey> + 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<Key> : View<Msg = Key> { type Item; - fn get(&self, key: &Key) -> Self::Item; + fn get(&self, key: &Key) -> Option<Self::Item>; // todo: AreaIterator enum to switch between Allocated and Procedural area fn area(&self) -> Option<Vec<Key>> { @@ -28,7 +28,7 @@ pub trait IndexView<Key> : View<Msg = Key> { impl<Key, V: IndexView<Key>> IndexView<Key> for RwLock<V> { type Item = V::Item; - fn get(&self, key: &Key) -> Self::Item { + fn get(&self, key: &Key) -> Option<Self::Item> { self.read().unwrap().get(key) } @@ -40,7 +40,7 @@ impl<Key, V: IndexView<Key>> IndexView<Key> for RwLock<V> { impl<Key, V: IndexView<Key>> IndexView<Key> for Arc<V> { type Item = V::Item; - fn get(&self, key: &Key) -> Self::Item { + fn get(&self, key: &Key) -> Option<Self::Item> { 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<Self::Value>; fn area(&self) -> Option<Vec<Self::Key>> { None } @@ -68,7 +68,7 @@ impl<V: ImplIndexView> View for V { impl<V: ImplIndexView> IndexView<V::Key> for V { type Item = V::Value; - fn get(&self, key: &V::Key) -> Self::Item { + fn get(&self, key: &V::Key) -> Option<Self::Item> { (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::<dyn TerminalView>::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::<dyn TerminalView>::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::<dyn TerminalView>::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<i16>| 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<i16>; - type Value = Option<TerminalAtom>; + type Value = TerminalAtom; fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> { 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<i16>; - type Value = Option<TerminalAtom>; + type Value = TerminalAtom; fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> { if pos.y == 5 { @@ -206,7 +183,7 @@ impl ImplIndexView for TermLabel { struct ScrambleBackground; impl ImplIndexView for ScrambleBackground { type Key = Point2<i16>; - type Value = Option<TerminalAtom>; + type Value = TerminalAtom; fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> { 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<Msg = usize> { type Item; - fn get(&self, idx: usize) -> Self::Item; + fn get(&self, idx: &usize) -> Option<Self::Item>; fn len(&self) -> Option<usize>; } @@ -28,7 +28,7 @@ use std::{ impl<V: SequenceView> SequenceView for RwLock<V> { type Item = V::Item; - fn get(&self, idx: usize) -> Self::Item { + fn get(&self, idx: &usize) -> Option<Self::Item> { self.read().unwrap().get(idx) } @@ -40,7 +40,7 @@ impl<V: SequenceView> SequenceView for RwLock<V> { impl<V: SequenceView> SequenceView for Arc<V> { type Item = V::Item; - fn get(&self, idx: usize) -> Self::Item { + fn get(&self, idx: &usize) -> Option<Self::Item> { 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<SrcView> where SrcView: SequenceView + ?Sized + 'static { src_view: Option<Arc<SrcView>>, - cast: Arc<RwLock<ObserverBroadcast<dyn IndexView<usize, Item = Option<SrcView::Item>>>>> + cast: Arc<RwLock<ObserverBroadcast<dyn IndexView<usize, Item = SrcView::Item>>>> } impl<SrcView> Sequence2Index<SrcView> where SrcView: SequenceView + ?Sized + 'static { pub fn new( - port: InnerViewPort<dyn IndexView<usize, Item = Option<SrcView::Item>>> + port: InnerViewPort<dyn IndexView<usize, Item = SrcView::Item>> ) -> Arc<RwLock<Self>> { let s2i = Arc::new(RwLock::new( Sequence2Index { @@ -36,7 +36,7 @@ where SrcView: SequenceView + ?Sized + 'static { } impl<Item: 'static> OuterViewPort<dyn SequenceView<Item = Item>> { - pub fn to_index(&self) -> OuterViewPort<dyn IndexView<usize, Item = Option<Item>>> { + pub fn to_index(&self) -> OuterViewPort<dyn IndexView<usize, Item = Item>> { let port = ViewPort::new(); self.add_observer(Sequence2Index::new(port.inner())); port.into_outer() @@ -50,24 +50,15 @@ where SrcView: SequenceView + ?Sized + 'static { impl<SrcView> IndexView<usize> for Sequence2Index<SrcView> where SrcView: SequenceView + ?Sized + 'static { - type Item = Option<SrcView::Item>; + 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::Item> { + self.src_view.as_ref()?.get(key) } fn area(&self) -> Option<Vec<usize>> { - 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<T> SequenceView for VecSequence<T> 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<T> { + self.data.as_ref()? + .read().unwrap() + .get(*idx).cloned() } fn len(&self) -> Option<usize> { 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<i16>; - type Value = Option<TerminalAtom>; + type Value = TerminalAtom; fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> { 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<i16>; - type Value = Option<TerminalAtom>; + type Value = TerminalAtom; fn get(&self, pos: &Point2<i16>) -> Option<TerminalAtom> { 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<Item = Option<TerminalAtom>>; +pub trait TerminalView = GridView<Item = TerminalAtom>; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>