index/sequence: get() always return Option

This commit is contained in:
Michael Sippel 2021-01-16 20:19:52 +01:00
parent b62bfa54a0
commit 4fceafcac4
Signed by: senvas
GPG key ID: F96CF119C34B64A6
11 changed files with 49 additions and 98 deletions

View file

@ -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;

View file

@ -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>>) {

View file

@ -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,
{

View file

@ -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)
}

View file

@ -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) {

View file

@ -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)
}

View file

@ -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())
}
}

View file

@ -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> {

View file

@ -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();

View file

@ -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;

View file

@ -18,7 +18,7 @@ use {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub trait TerminalView = GridView<Item = Option<TerminalAtom>>;
pub trait TerminalView = GridView<Item = TerminalAtom>;
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>