diff --git a/output/src/ops.rs b/output/src/ops.rs index 4c6ea2a..7eba655 100644 --- a/output/src/ops.rs +++ b/output/src/ops.rs @@ -2,6 +2,7 @@ mod align; pub use self::align::*; mod bsp; pub use self::bsp::*; mod cond; pub use self::cond::*; mod map; pub use self::map::*; +mod memo; pub use self::memo::*; mod stack; pub use self::stack::*; //mod reduce; pub use self::reduce::*; mod thunk; pub use self::thunk::*; diff --git a/output/src/ops/memo.rs b/output/src/ops/memo.rs new file mode 100644 index 0000000..07e2d93 --- /dev/null +++ b/output/src/ops/memo.rs @@ -0,0 +1,30 @@ +use crate::*; +use std::sync::{Arc, RwLock}; + +#[derive(Debug, Default)] pub struct Memo { + pub value: T, + pub view: Arc> +} + +impl Memo { + pub fn new (value: T, view: U) -> Self { + Self { value, view: Arc::new(view.into()) } + } + pub fn update ( + &mut self, + newval: T, + render: impl Fn(&mut U, &T, &T)->R + ) -> Option { + if newval != self.value { + let result = render(&mut*self.view.write().unwrap(), &newval, &self.value); + self.value = newval; + return Some(result); + } + None + } +} + +/// Clear a pre-allocated buffer, then write into it. +#[macro_export] macro_rules! rewrite { + ($buf:ident, $($rest:tt)*) => { |$buf,_,_|{ $buf.clear(); write!($buf, $($rest)*) } } +}