OuterViewPort: map_value() & map_key()

This commit is contained in:
Michael Sippel 2020-12-08 15:51:24 +01:00
parent 2da96c5482
commit 852e1807db
Signed by: senvas
GPG key ID: F96CF119C34B64A6
2 changed files with 105 additions and 15 deletions

View file

@ -1,5 +1,6 @@
#![feature(trait_alias)]
#![feature(assoc_char_funcs)]
pub mod view;
pub mod port;
@ -32,7 +33,7 @@ impl<T: Clone + Eq + Send + Sync + 'static> SingletonBuffer<T> {
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<T: Clone + Eq + Send + Sync + 'static> SingletonBuffer<T> {
}
}
impl<T: Clone + Send + Sync> View for Vec<T> {
type Key = usize;
type Value = T;
fn view(&self, key: usize) -> Option<T> {
self.get(key).cloned()
}
}
struct VecBuffer<T: Clone + Eq + Send + Sync + 'static> {
data: Arc<RwLock<Vec<T>>>,
port: InnerViewPort<usize, T>
}
impl<T: Clone + Eq + Send + Sync + 'static> VecBuffer<T> {
fn new(port: InnerViewPort<usize, T>) -> 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::<i16>::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;
}

View file

@ -1,6 +1,6 @@
use {
std::{
sync::{Arc, Weak, RwLock},
sync::{Arc, RwLock},
collections::HashSet,
hash::Hash,
},
@ -81,6 +81,43 @@ impl<K: Eq + Hash + Send + Sync + 'static, V: Send + Sync + 'static> OuterViewPo
}
}
impl<K: Clone + Eq + Hash + Send + Sync + 'static, V: Send + Sync + 'static> OuterViewPort<K, V> {
pub fn map_value<
V2: Clone + Send + Sync + 'static,
F: Fn(Option<V>) -> Option<V2> + Send + Sync + 'static
>(
self,
f: F
) -> OuterViewPort<K, V2> {
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<K2, V> {
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<K: Send + Sync + 'static, V: Send + Sync + 'static> InnerViewPort<K, V> {