diff --git a/src/main.rs b/src/main.rs index 76fccbb..2f46611 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![feature(trait_alias)] +#![feature(assoc_char_funcs)] pub mod view; pub mod port; @@ -32,7 +33,7 @@ impl SingletonBuffer { port.set_view_fn({ let data = data.clone(); - move |new_val| data.read().unwrap().clone() + move |_| data.read().unwrap().clone() }); SingletonBuffer { @@ -51,36 +52,88 @@ impl SingletonBuffer { } } + + +impl View for Vec { + type Key = usize; + type Value = T; + + fn view(&self, key: usize) -> Option { + self.get(key).cloned() + } +} + + +struct VecBuffer { + data: Arc>>, + port: InnerViewPort +} + +impl VecBuffer { + fn new(port: InnerViewPort) -> Self { + let data = Arc::new(RwLock::new(Vec::new())); + port.set_view(data.clone()); + VecBuffer { data, port } + } + + fn push(&mut self, val: T) { + self.port.notify({ + let mut d = self.data.write().unwrap(); + let len = d.len(); + d.push(val); + len + }); + } +} + #[async_std::main] async fn main() { - let view_port = port::ViewPort::<(), char>::new(); + let digits = port::ViewPort::new(); + let mut buf = VecBuffer::new(digits.inner()); - let mut buf = SingletonBuffer::new(view_port.inner()); + let digit_view = digits.outer() - let view = view_port.outer().get_view(); - let mut stream = view_port.outer().stream().map({ - move |_| view.view(()).unwrap() + // digit encoding + .map_value( + |digit| + if let Some(digit) = digit { + char::from_digit(digit, 16) + } else { + None + } + ) + + // simple horizontal layout + .map_key( + |idx| Vector2::::new(idx as i16, 0), + |pos| pos.x as usize + ); + + let view = digit_view.get_view(); + let mut stream = digit_view.stream().map({ + move |idx| (idx, view.view(idx)) }); let fut = task::spawn({ async move { - while let Some(val) = stream.next().await { - println!("{}", val); + while let Some((idx, val)) = stream.next().await { + println!("v[{:?}] = {:?}", idx, val); } println!("end print task"); } }); - buf.update('a'); - buf.update('b'); + buf.push(0); + buf.push(1); task::sleep(std::time::Duration::from_secs(1)).await; - buf.update('c'); - buf.update('d'); + buf.push(2); + buf.push(3); task::sleep(std::time::Duration::from_secs(1)).await; - buf.update('e'); + buf.push(4); drop(buf); - drop(view_port); + drop(digits); + drop(digit_view); fut.await; } diff --git a/src/port.rs b/src/port.rs index 9f99a7b..5874217 100644 --- a/src/port.rs +++ b/src/port.rs @@ -1,6 +1,6 @@ use { std::{ - sync::{Arc, Weak, RwLock}, + sync::{Arc, RwLock}, collections::HashSet, hash::Hash, }, @@ -81,6 +81,43 @@ impl OuterViewPo } } +impl OuterViewPort { + pub fn map_value< + V2: Clone + Send + Sync + 'static, + F: Fn(Option) -> Option + Send + Sync + 'static + >( + self, + f: F + ) -> OuterViewPort { + let port = ViewPort::new(); + let view = self.add_observer_fn({ + let dst = port.inner(); + move |key| dst.notify(key) + }); + port.inner().set_view_fn(move |key| f(view.view(key))); + port.outer() + } + + pub fn map_key< + K2: Clone + Send + Sync + 'static, + F1: Fn(K) -> K2 + Send + Sync + 'static, + F2: Fn(K2) -> K + Send + Sync + 'static + >( + self, + f1: F1, + f2: F2 + ) -> OuterViewPort { + let port = ViewPort::new(); + let view = self.add_observer_fn({ + let dst = port.inner(); + move |key| dst.notify(f1(key)) + }); + port.inner().set_view_fn(move |key| view.view(f2(key))); + port.outer() + } +} + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> impl InnerViewPort {