Make InvalidationSignal not generic over synchronicity
This commit is contained in:
parent
a556b14188
commit
365d2db571
@ -103,13 +103,11 @@ impl<O: 'static, S: Synchronicity> GraphBuilder<O, S> {
|
|||||||
pub fn add_invalidatable_value<V: NodeValue>(
|
pub fn add_invalidatable_value<V: NodeValue>(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: V,
|
value: V,
|
||||||
) -> (Input<V>, ValueInvalidationSignal<V, S>) {
|
) -> (Input<V>, ValueInvalidationSignal<V>) {
|
||||||
let input = self.add_node(InvalidatableConstNode::new(value));
|
let input = self.add_node(InvalidatableConstNode::new(value));
|
||||||
let signal = ValueInvalidationSignal {
|
let signal = ValueInvalidationSignal {
|
||||||
node_idx: input.node_idx,
|
|
||||||
value: Rc::clone(&input.value),
|
value: Rc::clone(&input.value),
|
||||||
graph: Rc::clone(&self.node_graph),
|
signal: self.make_invalidation_signal(&input),
|
||||||
graph_is_valid: Rc::clone(&self.is_valid),
|
|
||||||
};
|
};
|
||||||
(input, signal)
|
(input, signal)
|
||||||
}
|
}
|
||||||
@ -162,16 +160,26 @@ impl<O: 'static, S: Synchronicity> GraphBuilder<O, S> {
|
|||||||
pub fn add_invalidatable_rule<R: Rule>(
|
pub fn add_invalidatable_rule<R: Rule>(
|
||||||
&mut self,
|
&mut self,
|
||||||
rule: R,
|
rule: R,
|
||||||
) -> (Input<R::Output>, InvalidationSignal<S>) {
|
) -> (Input<R::Output>, InvalidationSignal) {
|
||||||
let input = self.add_rule(rule);
|
let input = self.add_rule(rule);
|
||||||
let signal = InvalidationSignal {
|
let signal = self.make_invalidation_signal(&input);
|
||||||
node_idx: Rc::new(Cell::new(Some(input.node_idx))),
|
|
||||||
graph: Rc::clone(&self.node_graph),
|
|
||||||
graph_is_valid: Rc::clone(&self.is_valid),
|
|
||||||
};
|
|
||||||
(input, signal)
|
(input, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_invalidation_signal<V>(&self, input: &Input<V>) -> InvalidationSignal {
|
||||||
|
let node_idx = input.node_idx;
|
||||||
|
let graph = Rc::clone(&self.node_graph);
|
||||||
|
let graph_is_valid = Rc::clone(&self.is_valid);
|
||||||
|
InvalidationSignal {
|
||||||
|
do_invalidate: Rc::new(Box::new(move || {
|
||||||
|
graph_is_valid.set(false);
|
||||||
|
let mut graph = graph.borrow_mut();
|
||||||
|
let node = &mut graph[node_idx];
|
||||||
|
node.invalidate();
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a graph from this builder, consuming the builder.
|
/// Creates a graph from this builder, consuming the builder.
|
||||||
///
|
///
|
||||||
/// To successfully build a graph, there must be an output node set (using either
|
/// To successfully build a graph, there must be an output node set (using either
|
||||||
@ -259,20 +267,13 @@ impl<O: 'static> GraphBuilder<O, Asynchronous> {
|
|||||||
///
|
///
|
||||||
/// Returns an [`Input`] representing the newly-added node, which can be used to construct further rules,
|
/// Returns an [`Input`] representing the newly-added node, which can be used to construct further rules,
|
||||||
/// as well as an [`InvalidationSignal`] which can be used to indicate that the node has been invalidated.
|
/// as well as an [`InvalidationSignal`] which can be used to indicate that the node has been invalidated.
|
||||||
pub fn add_invalidatable_async_rule<R, F>(&mut self, mut f: F) -> Input<R::Output>
|
pub fn add_invalidatable_async_rule<R: AsyncRule>(
|
||||||
where
|
&mut self,
|
||||||
R: AsyncRule,
|
rule: R,
|
||||||
F: FnMut(InvalidationSignal<Asynchronous>) -> R,
|
) -> (Input<R::Output>, InvalidationSignal) {
|
||||||
{
|
let input = self.add_async_rule(rule);
|
||||||
let node_idx = Rc::new(Cell::new(None));
|
let signal = self.make_invalidation_signal(&input);
|
||||||
let signal = InvalidationSignal {
|
(input, signal)
|
||||||
node_idx: Rc::clone(&node_idx),
|
|
||||||
graph: Rc::clone(&self.node_graph),
|
|
||||||
graph_is_valid: Rc::clone(&self.is_valid),
|
|
||||||
};
|
|
||||||
let input = self.add_async_rule(f(signal));
|
|
||||||
node_idx.set(Some(input.node_idx));
|
|
||||||
input
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,33 +298,25 @@ impl<O: 'static> Graph<O, Asynchronous> {
|
|||||||
///
|
///
|
||||||
/// `InvalidationSignal` implements `Clone`, so the signal can be cloned and used from multiple places.
|
/// `InvalidationSignal` implements `Clone`, so the signal can be cloned and used from multiple places.
|
||||||
// TODO: there's a lot happening here, make sure this doesn't create a reference cycle
|
// TODO: there's a lot happening here, make sure this doesn't create a reference cycle
|
||||||
// TODO: would be better if this didn't have to be generic over Synchronicity
|
pub struct InvalidationSignal {
|
||||||
pub struct InvalidationSignal<Synch: Synchronicity> {
|
do_invalidate: Rc<Box<dyn Fn() -> ()>>,
|
||||||
node_idx: Rc<Cell<Option<NodeId>>>,
|
|
||||||
graph: Rc<RefCell<NodeGraph<Synch>>>,
|
|
||||||
graph_is_valid: Rc<Cell<bool>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Synchronicity> InvalidationSignal<S> {
|
impl InvalidationSignal {
|
||||||
/// Tell the graph that the node corresponding to this signal is now invalid.
|
/// Tell the graph that the node corresponding to this signal is now invalid.
|
||||||
///
|
///
|
||||||
/// Note: Calling this method does not trigger a graph evaluation, it merely marks the corresponding
|
/// Note: Calling this method does not trigger a graph evaluation, it merely marks the corresponding
|
||||||
/// node as invalid. The graph will not be re-evaluated until [`Graph::evaluate`] or
|
/// node as invalid. The graph will not be re-evaluated until [`Graph::evaluate`] or
|
||||||
/// [`Graph::evaluate_async`] is next called.
|
/// [`Graph::evaluate_async`] is next called.
|
||||||
pub fn invalidate(&self) {
|
pub fn invalidate(&self) {
|
||||||
self.graph_is_valid.set(false);
|
(self.do_invalidate)();
|
||||||
let mut graph = self.graph.borrow_mut();
|
|
||||||
let node = &mut graph[self.node_idx.get().unwrap()];
|
|
||||||
node.invalidate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Synchronicity> Clone for InvalidationSignal<S> {
|
impl Clone for InvalidationSignal {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
node_idx: Rc::clone(&self.node_idx),
|
do_invalidate: Rc::clone(&self.do_invalidate),
|
||||||
graph: Rc::clone(&self.graph),
|
|
||||||
graph_is_valid: Rc::clone(&self.graph_is_valid),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,14 +324,12 @@ impl<S: Synchronicity> Clone for InvalidationSignal<S> {
|
|||||||
/// A type representing a node with an externally injected value.
|
/// A type representing a node with an externally injected value.
|
||||||
///
|
///
|
||||||
/// See [`GraphBuilder::add_invalidatable_value`].
|
/// See [`GraphBuilder::add_invalidatable_value`].
|
||||||
pub struct ValueInvalidationSignal<V, Synch: Synchronicity> {
|
pub struct ValueInvalidationSignal<V> {
|
||||||
node_idx: NodeId,
|
|
||||||
value: Rc<RefCell<Option<V>>>,
|
value: Rc<RefCell<Option<V>>>,
|
||||||
graph: Rc<RefCell<NodeGraph<Synch>>>,
|
signal: InvalidationSignal,
|
||||||
graph_is_valid: Rc<Cell<bool>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: NodeValue, S: Synchronicity> ValueInvalidationSignal<V, S> {
|
impl<V: NodeValue> ValueInvalidationSignal<V> {
|
||||||
/// Get a reference to current value for the node corresponding to this signal.
|
/// Get a reference to current value for the node corresponding to this signal.
|
||||||
pub fn value(&self) -> impl Deref<Target = V> + '_ {
|
pub fn value(&self) -> impl Deref<Target = V> + '_ {
|
||||||
Ref::map(self.value.borrow(), |opt| {
|
Ref::map(self.value.borrow(), |opt| {
|
||||||
@ -361,10 +351,16 @@ impl<V: NodeValue, S: Synchronicity> ValueInvalidationSignal<V, S> {
|
|||||||
.node_value_eq(&value)
|
.node_value_eq(&value)
|
||||||
{
|
{
|
||||||
*current_value = Some(value);
|
*current_value = Some(value);
|
||||||
self.graph_is_valid.set(false);
|
self.signal.invalidate();
|
||||||
let mut graph = self.graph.borrow_mut();
|
}
|
||||||
let node = &mut graph[self.node_idx];
|
}
|
||||||
node.invalidate();
|
}
|
||||||
|
|
||||||
|
impl<V> Clone for ValueInvalidationSignal<V> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
value: Rc::clone(&self.value),
|
||||||
|
signal: self.signal.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user