Consolidate external inputs with rules
This commit is contained in:
parent
3b943cb828
commit
b7d0271f4e
@ -48,20 +48,18 @@ impl<Output: Clone + 'static> Graph<Output> {
|
||||
return self.add_node(RuleNode::new(rule));
|
||||
}
|
||||
|
||||
pub fn add_input<I, F>(&mut self, mut f: F) -> Input<I::Output>
|
||||
pub fn add_invalidatable_rule<R, V, F>(&mut self, mut f: F) -> Input<V>
|
||||
where
|
||||
I: ExternalInput + 'static,
|
||||
I::Output: Clone,
|
||||
F: FnMut(InvalidationSignal) -> I,
|
||||
R: Rule<V> + 'static,
|
||||
V: Clone + 'static,
|
||||
F: FnMut(InvalidationSignal) -> R,
|
||||
{
|
||||
let node_idx = Rc::new(Cell::new(None));
|
||||
let signal = InvalidationSignal {
|
||||
node_idx: Rc::clone(&node_idx),
|
||||
graph: Rc::clone(&self.node_graph),
|
||||
};
|
||||
let input = f(signal);
|
||||
let node = ExternalInputNode::<I>::new(input);
|
||||
let input = self.add_node(node);
|
||||
let input = self.add_rule(f(signal));
|
||||
node_idx.set(Some(input.node_idx));
|
||||
input
|
||||
}
|
||||
@ -306,6 +304,7 @@ impl<R: Rule<V> + 'static, V: Clone + 'static> Node<V> for RuleNode<R, V> {
|
||||
}
|
||||
|
||||
fn update(&mut self) {
|
||||
self.valid = true;
|
||||
let new_value = self.rule.evaluate();
|
||||
*self.value.borrow_mut() = Some(new_value);
|
||||
}
|
||||
@ -323,47 +322,6 @@ impl<R: Rule<V> + 'static, V: Clone + 'static> Node<V> for RuleNode<R, V> {
|
||||
}
|
||||
}
|
||||
|
||||
struct ExternalInputNode<I: ExternalInput> {
|
||||
input: I,
|
||||
value: Rc<RefCell<Option<I::Output>>>,
|
||||
valid: bool,
|
||||
}
|
||||
|
||||
impl<I: ExternalInput> ExternalInputNode<I> {
|
||||
fn new(input: I) -> Self {
|
||||
Self {
|
||||
input,
|
||||
value: Rc::new(RefCell::new(None)),
|
||||
valid: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: ExternalInput> Node<I::Output> for ExternalInputNode<I> {
|
||||
fn is_valid(&self) -> bool {
|
||||
self.valid
|
||||
}
|
||||
|
||||
fn invalidate(&mut self) {
|
||||
self.valid = false;
|
||||
}
|
||||
|
||||
fn visit_inputs(&mut self, _visitor: &mut dyn FnMut(NodeIndex<u32>) -> ()) {}
|
||||
|
||||
fn update(&mut self) {
|
||||
self.valid = true;
|
||||
*self.value.borrow_mut() = Some(self.input.value());
|
||||
}
|
||||
|
||||
fn value_rc(&self) -> Rc<RefCell<Option<I::Output>>> {
|
||||
Rc::clone(&self.value)
|
||||
}
|
||||
|
||||
fn value(&self) -> I::Output {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Rule<Output> {
|
||||
fn visit_inputs(&mut self, visitor: &mut impl InputVisitor);
|
||||
|
||||
@ -374,12 +332,6 @@ pub trait InputVisitor {
|
||||
fn visit<T>(&mut self, input: &mut Input<T>);
|
||||
}
|
||||
|
||||
pub trait ExternalInput {
|
||||
type Output;
|
||||
|
||||
fn value(&mut self) -> Self::Output;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -434,18 +386,18 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn external_input() {
|
||||
fn invalidatable_rule() {
|
||||
struct Inc(i32);
|
||||
impl ExternalInput for Inc {
|
||||
type Output = i32;
|
||||
fn value(&mut self) -> i32 {
|
||||
impl Rule<i32> for Inc {
|
||||
fn visit_inputs(&mut self, _visitor: &mut impl InputVisitor) {}
|
||||
fn evaluate(&mut self) -> i32 {
|
||||
self.0 += 1;
|
||||
return self.0;
|
||||
}
|
||||
}
|
||||
let mut graph = Graph::new();
|
||||
let mut invalidate = None;
|
||||
let input = graph.add_input(|inv| {
|
||||
let input = graph.add_invalidatable_rule(|inv| {
|
||||
invalidate = Some(inv);
|
||||
Inc(0)
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user