index/sequence: get() always return Option
This commit is contained in:
parent
b62bfa54a0
commit
4fceafcac4
11 changed files with 49 additions and 98 deletions
|
@ -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;
|
||||
|
|
|
@ -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>>) {
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
39
src/main.rs
39
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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -18,7 +18,7 @@ use {
|
|||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub trait TerminalView = GridView<Item = Option<TerminalAtom>>;
|
||||
pub trait TerminalView = GridView<Item = TerminalAtom>;
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
|
|
Loading…
Reference in a new issue