Simplify Synchronicity trait

This commit is contained in:
Shadowfacts 2024-11-02 23:56:51 -04:00
parent 6d1e505590
commit 36bcbe3c9c
3 changed files with 18 additions and 37 deletions

View File

@ -59,7 +59,7 @@ use node::{ErasedNode, NodeValue};
use petgraph::visit::{IntoEdgeReferences, NodeIndexable}; use petgraph::visit::{IntoEdgeReferences, NodeIndexable};
use petgraph::{stable_graph::StableDiGraph, visit::EdgeRef}; use petgraph::{stable_graph::StableDiGraph, visit::EdgeRef};
use rule::{AsyncRule, Input, InputVisitor, Rule}; use rule::{AsyncRule, Input, InputVisitor, Rule};
use std::cell::{Cell, Ref, RefCell}; use std::cell::{Cell, RefCell};
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};

View File

@ -10,7 +10,7 @@ pub(crate) struct ErasedNode<Synch: Synchronicity> {
is_valid: Box<dyn Fn(&Box<dyn Any>) -> bool>, is_valid: Box<dyn Fn(&Box<dyn Any>) -> bool>,
invalidate: Box<dyn Fn(&mut Box<dyn Any>) -> ()>, invalidate: Box<dyn Fn(&mut Box<dyn Any>) -> ()>,
visit_inputs: Box<dyn Fn(&Box<dyn Any>, &mut dyn FnMut(NodeId) -> ()) -> ()>, visit_inputs: Box<dyn Fn(&Box<dyn Any>, &mut dyn FnMut(NodeId) -> ()) -> ()>,
update: Synch::UpdateFn, update: Box<dyn for<'a> Fn(&'a mut Box<dyn Any>) -> Synch::UpdateResult<'a>>,
} }
impl<S: Synchronicity> ErasedNode<S> { impl<S: Synchronicity> ErasedNode<S> {
@ -32,7 +32,10 @@ impl<S: Synchronicity> ErasedNode<S> {
let x = any.downcast_ref::<Box<dyn Node<V, S>>>().unwrap(); let x = any.downcast_ref::<Box<dyn Node<V, S>>>().unwrap();
x.visit_inputs(visitor); x.visit_inputs(visitor);
}), }),
update: S::make_update_fn::<V>(), update: Box::new(|any| {
let x = any.downcast_mut::<Box<dyn Node<V, S>>>().unwrap();
x.update()
}),
} }
} }
@ -164,7 +167,7 @@ impl<V: NodeValue, S: Synchronicity> Node<V, S> for InvalidatableConstNode<V, S>
self.valid = true; self.valid = true;
// This node is only invalidate when node_value_eq between the old/new value is false, // This node is only invalidate when node_value_eq between the old/new value is false,
// so it is always the case that the update method has changed the value. // so it is always the case that the update method has changed the value.
S::make_update_result(true) S::make_update_result(true, crate::synchronicity::private::Token)
} }
fn value_rc(&self) -> &Rc<RefCell<Option<V>>> { fn value_rc(&self) -> &Rc<RefCell<Option<V>>> {
@ -222,7 +225,7 @@ impl<R: Rule, S: Synchronicity> Node<R::Output, S> for RuleNode<R, R::Output, S>
*value = Some(new_value); *value = Some(new_value);
} }
S::make_update_result(value_changed) S::make_update_result(value_changed, crate::synchronicity::private::Token)
} }
fn value_rc(&self) -> &Rc<RefCell<Option<R::Output>>> { fn value_rc(&self) -> &Rc<RefCell<Option<R::Output>>> {

View File

@ -4,41 +4,31 @@
//! The [`Synchronicity`] trait is sealed to outside implementors, and you generally do not need to refer //! The [`Synchronicity`] trait is sealed to outside implementors, and you generally do not need to refer
//! directly to the [`Synchronous`] or [`Asynchronous`] types. //! directly to the [`Synchronous`] or [`Asynchronous`] types.
use crate::node::{Node, NodeValue};
use std::any::Any;
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
mod private { pub(crate) mod private {
pub trait Sealed {} pub trait Sealed {}
impl Sealed for super::Synchronous {} impl Sealed for super::Synchronous {}
impl Sealed for super::Asynchronous {} impl Sealed for super::Asynchronous {}
impl Sealed for bool {}
impl<'a> Sealed for <super::Asynchronous as super::Synchronicity>::UpdateResult<'a> {}
pub struct Token;
} }
pub trait Synchronicity: private::Sealed + 'static { pub trait Synchronicity: private::Sealed + 'static {
// TODO: do we need the associated type? can this just be a method update_node(Box<dyn Node<V>>)? type UpdateResult<'a>: private::Sealed;
type UpdateFn; // Necessary for synchronous nodes that can be part of an async graph to return the
fn make_update_fn<V: NodeValue>() -> Self::UpdateFn; // appropriate result based on the type of graph they're in.
fn make_update_result<'a>(result: bool, _: private::Token) -> Self::UpdateResult<'a>;
type UpdateResult<'a>;
fn make_update_result<'a>(result: bool) -> Self::UpdateResult<'a>;
} }
pub struct Synchronous; pub struct Synchronous;
impl Synchronicity for Synchronous { impl Synchronicity for Synchronous {
type UpdateFn = Box<dyn Fn(&mut Box<dyn Any>) -> bool>;
fn make_update_fn<V: NodeValue>() -> Self::UpdateFn {
Box::new(|any| {
let x = any.downcast_mut::<Box<dyn Node<V, Self>>>().unwrap();
x.update()
})
}
type UpdateResult<'a> = bool; type UpdateResult<'a> = bool;
fn make_update_result<'a>(result: bool) -> Self::UpdateResult<'a> { fn make_update_result<'a>(result: bool, _: private::Token) -> Self::UpdateResult<'a> {
result result
} }
} }
@ -46,21 +36,9 @@ impl Synchronicity for Synchronous {
pub struct Asynchronous; pub struct Asynchronous;
impl Synchronicity for Asynchronous { impl Synchronicity for Asynchronous {
type UpdateFn =
Box<dyn for<'a> Fn(&'a mut Box<dyn Any>) -> Pin<Box<dyn Future<Output = bool> + 'a>>>;
fn make_update_fn<V: NodeValue>() -> Self::UpdateFn {
Box::new(|any| {
Box::pin({
let x = any.downcast_mut::<Box<dyn Node<V, Self>>>().unwrap();
x.update()
})
})
}
type UpdateResult<'a> = Pin<Box<dyn Future<Output = bool> + 'a>>; type UpdateResult<'a> = Pin<Box<dyn Future<Output = bool> + 'a>>;
fn make_update_result<'a>(result: bool) -> Self::UpdateResult<'a> { fn make_update_result<'a>(result: bool, _: private::Token) -> Self::UpdateResult<'a> {
Box::pin(std::future::ready(result)) Box::pin(std::future::ready(result))
} }
} }