OuterViewPort: map_value() & map_key()
This commit is contained in:
parent
2da96c5482
commit
852e1807db
2 changed files with 105 additions and 15 deletions
81
src/main.rs
81
src/main.rs
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
|
#![feature(assoc_char_funcs)]
|
||||||
|
|
||||||
pub mod view;
|
pub mod view;
|
||||||
pub mod port;
|
pub mod port;
|
||||||
|
@ -32,7 +33,7 @@ impl<T: Clone + Eq + Send + Sync + 'static> SingletonBuffer<T> {
|
||||||
|
|
||||||
port.set_view_fn({
|
port.set_view_fn({
|
||||||
let data = data.clone();
|
let data = data.clone();
|
||||||
move |new_val| data.read().unwrap().clone()
|
move |_| data.read().unwrap().clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
SingletonBuffer {
|
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_std::main]
|
||||||
async fn 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();
|
// digit encoding
|
||||||
let mut stream = view_port.outer().stream().map({
|
.map_value(
|
||||||
move |_| view.view(()).unwrap()
|
|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({
|
let fut = task::spawn({
|
||||||
async move {
|
async move {
|
||||||
while let Some(val) = stream.next().await {
|
while let Some((idx, val)) = stream.next().await {
|
||||||
println!("{}", val);
|
println!("v[{:?}] = {:?}", idx, val);
|
||||||
}
|
}
|
||||||
println!("end print task");
|
println!("end print task");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
buf.update('a');
|
buf.push(0);
|
||||||
buf.update('b');
|
buf.push(1);
|
||||||
task::sleep(std::time::Duration::from_secs(1)).await;
|
task::sleep(std::time::Duration::from_secs(1)).await;
|
||||||
buf.update('c');
|
buf.push(2);
|
||||||
buf.update('d');
|
buf.push(3);
|
||||||
task::sleep(std::time::Duration::from_secs(1)).await;
|
task::sleep(std::time::Duration::from_secs(1)).await;
|
||||||
buf.update('e');
|
buf.push(4);
|
||||||
|
|
||||||
drop(buf);
|
drop(buf);
|
||||||
drop(view_port);
|
drop(digits);
|
||||||
|
drop(digit_view);
|
||||||
|
|
||||||
fut.await;
|
fut.await;
|
||||||
}
|
}
|
||||||
|
|
39
src/port.rs
39
src/port.rs
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
std::{
|
std::{
|
||||||
sync::{Arc, Weak, RwLock},
|
sync::{Arc, RwLock},
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
hash::Hash,
|
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> {
|
impl<K: Send + Sync + 'static, V: Send + Sync + 'static> InnerViewPort<K, V> {
|
||||||
|
|
Loading…
Reference in a new issue