#![feature(trait_alias)] #![feature(assoc_char_funcs)] pub mod view; pub mod port; pub mod channel; use { async_std::{ prelude::*, task, stream }, std::{ sync::{Arc, RwLock} }, cgmath::{Vector2}, crate::{ view::{View, Observer}, port::{InnerViewPort, OuterViewPort} } }; struct SingletonBuffer { data: Arc>>, port: InnerViewPort<(), T> } impl SingletonBuffer { fn new( port: InnerViewPort<(), T> ) -> Self { let data = Arc::new(RwLock::new(None)); port.set_view_fn({ let data = data.clone(); move |_| data.read().unwrap().clone() }); SingletonBuffer { data, port } } fn update(&mut self, new_value: T) { let mut data = self.data.write().unwrap(); if *data != Some(new_value.clone()) { *data = Some(new_value); drop(data); self.port.notify(()); } } } 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 digits = port::ViewPort::new(); let mut buf = VecBuffer::new(digits.inner()); let digit_view = digits.outer() // 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((idx, val)) = stream.next().await { println!("v[{:?}] = {:?}", idx, val); } println!("end print task"); } }); buf.push(0); buf.push(1); task::sleep(std::time::Duration::from_secs(1)).await; buf.push(2); buf.push(3); task::sleep(std::time::Duration::from_secs(1)).await; buf.push(4); drop(buf); drop(digits); drop(digit_view); fut.await; }