diff --git a/node-graph/src/main.rs b/node-graph/src/main.rs index 70f0e2f0..f9ec98b3 100644 --- a/node-graph/src/main.rs +++ b/node-graph/src/main.rs @@ -7,22 +7,23 @@ pub mod nodes; use iter::insert_after_nth; use nodes::*; +#[rustfmt::skip] pub trait Node { - type Out<'a> - where - Self: 'a; - type Input<'a> - where - Self: 'a; - fn eval<'a, T: Borrow>>(&'a self, input: T) -> Self::Out<'a>; + // Self: 'a means that Self has to live at least as long as 'a (the input and output) + // this ensures that the node does not spontaneously disappear during evaluation + type Output<'a> where Self: 'a; + type Input<'a> where Self: 'a; + + fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a>; } + pub trait AnyRef: Node { - fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Out<'a> + fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Output<'a> where Self::Input<'a>: 'static + Copy; } impl AnyRef for T { - fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Out<'a> + fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Output<'a> where Self::Input<'a>: 'static + Copy, { @@ -30,20 +31,14 @@ impl AnyRef for T { } } -/* trait After { - type Out<'a> - where - Self: 'a; - fn after<'a>( - &'a self, - first: &'a FIRST, - ) -> ComposeNode<'a, FIRST, SECOND, INTERMEDIATE>; -}*/ + fn after<'a, FIRST: Node>(&'a self, first: &'a FIRST) -> ComposeNode<'a, FIRST, SECOND>; +} fn main() { let int = IntNode::<32>; let add: u32 = AddNode::::default().any(&(int.eval(&()), int.eval(&())) as &dyn Any); + /* let curry: CurryNthArgNode<'_, _, _, u32, u32, 0> = CurryNthArgNode::new(&AddNode, &int); let composition = curry.after(&curry); diff --git a/node-graph/src/nodes.rs b/node-graph/src/nodes.rs index 90ef5649..f2a5bc66 100644 --- a/node-graph/src/nodes.rs +++ b/node-graph/src/nodes.rs @@ -3,12 +3,12 @@ use std::{ marker::PhantomData, }; -use crate::{insert_after_nth, /*After,*/ Node}; +use crate::{insert_after_nth, After, Node}; use once_cell::sync::OnceCell; pub struct IntNode; impl Node for IntNode { - type Out<'a> = u32; + type Output<'a> = u32; type Input<'a> = (); fn eval<'a, I: Borrow>>(&self, _input: I) -> u32 { N @@ -18,9 +18,9 @@ impl Node for IntNode { #[derive(Default)] pub struct ValueNode(T); impl Node for ValueNode { - type Out<'a> = &'a T where T: 'a; - type Input<'a> = () where T: 'a; - fn eval<'n, I: Borrow>>(&'n self, _input: I) -> &T { + type Output<'o> = &'o T where T: 'o; + type Input<'i> = () where T: 'i; + fn eval<'a, I: Borrow>>(&'a self, _input: I) -> &T { &self.0 } } @@ -34,7 +34,7 @@ impl ValueNode { #[derive(Default)] pub struct AddNode(PhantomData); impl Node for AddNode { - type Out<'a> = T::Output; + type Output<'a> = ::Output; type Input<'a> = (T, T); fn eval<'a, I: Borrow>>(&'a self, input: I) -> T::Output { input.borrow().0 + input.borrow().1 @@ -42,29 +42,71 @@ impl Node for AddNode { } /// Caches the output of a given Node and acts as a proxy -pub struct CacheNode<'n, 'c, CachedNode: Node + 'c> { +pub struct CachingNode<'n, 'c, CachedNode: Node + 'c> { node: &'n CachedNode, - cache: OnceCell>, + cache: OnceCell>, } -impl<'n: 'c, 'c, CashedNode: Node> Node for CacheNode<'n, 'c, CashedNode> { - type Out<'a> = &'a CashedNode::Out<'c> where 'c: 'a; +impl<'n: 'c, 'c, CashedNode: Node> Node for CachingNode<'n, 'c, CashedNode> { + type Output<'a> = &'a CashedNode::Output<'c> where 'c: 'a; type Input<'a> = CashedNode::Input<'c> where 'c: 'a; - fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Out<'a> { + fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a> { self.cache.get_or_init(|| self.node.eval(input)) } } -impl<'n, 'c, NODE: Node> CacheNode<'n, 'c, NODE> { +impl<'n, 'c, CachedNode: Node> CachingNode<'n, 'c, CachedNode> { pub fn clear(&'n mut self) { self.cache = OnceCell::new(); } - pub fn new(node: &'n NODE) -> CacheNode<'n, 'c, NODE> { - CacheNode { + pub fn new(node: &'n CachedNode) -> CachingNode<'n, 'c, CachedNode> { + CachingNode { node, cache: OnceCell::new(), } } } + +pub struct ComposeNode<'n, FIRST, SECOND> { + first: &'n FIRST, + second: &'n SECOND, +} + +impl<'n, FIRST, SECOND> Node for ComposeNode<'n, FIRST, SECOND> +where + FIRST: Node, + SECOND: Node, + for<'a> FIRST::Output<'a>: Borrow>, +{ + type Input<'a> = FIRST::Input<'a> where Self: 'a; + type Output<'a> = SECOND::Output<'a> where Self: 'a; + + fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a> { + // evaluate the first node with the given input + // and then pipe the result from the first computation + // into the second node + let arg = self.first.eval(input); + self.second.eval(arg) + } +} + +impl<'n, FIRST, SECOND> ComposeNode<'n, FIRST, SECOND> +where + FIRST: Node, +{ + pub fn new(first: &'n FIRST, second: &'n SECOND) -> Self { + ComposeNode::<'n, FIRST, SECOND> { first, second } + } +} + +impl<'n, SECOND: Node> After for SECOND { + fn after<'a, FIRST: Node>(&'a self, first: &'a FIRST) -> ComposeNode<'a, FIRST, SECOND> { + ComposeNode::<'a, FIRST, SECOND> { + first, + second: self, + } + } +} + /* /// Caches the output of a given Node and acts as a proxy /// Automatically resets if it receives different input @@ -159,60 +201,4 @@ impl<'n, CurryNode: Node<'n, Out>, ArgNode: Node<'n, Arg>, Arg: Clone, Out, cons } */ /* -pub struct ComposeNode<'n, FIRST, SECOND> -where - FIRST: Node, -{ - first: &'n FIRST, - second: &'n SECOND, - _phantom_data: PhantomData, -} - -impl<'n, FIRST, SECOND> Node for ComposeNode<'n, FIRST, SECOND> -where - FIRST: Node, - SECOND: Node, -{ - fn eval<'a, T: &Self::Input<'a>>(&'a self, input: T) -> &Self::Out<'a> { - self.second.eval(self.first.eval(input)) - //let curry = CurryNthArgNode::<'_, _, _, _, _, 0>::new(self.second, self.first); - //CurryNthArgNode::<'_, _, _, _, _, 0>::new(curry, ValueNode::new(input)).eval(input) - } - - type Out<'a> = SECOND::Out<'a> - where - Self: 'a; - - type Input<'a> = FIRST::Input<'a> - where - Self: 'a; -} -*/ -/* - -impl<'n, FIRST, SECOND, INTERMEDIATE: 'static> ComposeNode<'n, FIRST, SECOND, INTERMEDIATE> -where - FIRST: Node<'n, INTERMEDIATE>, -{ - pub fn new(first: &'n FIRST, second: &'n SECOND) -> Self { - ComposeNode::<'n, FIRST, SECOND, INTERMEDIATE> { - first, - second, - _phantom_data: PhantomData::default(), - } - } -} - -impl<'n, OUT, SECOND: Node<'n, OUT>> After<'n, OUT, SECOND> for SECOND { - fn after>( - &'n self, - first: &'n FIRST, - ) -> ComposeNode<'n, FIRST, SECOND, INTERMEDIATE> { - ComposeNode::<'n, FIRST, SECOND, INTERMEDIATE> { - first, - second: self, - _phantom_data: PhantomData::default(), - } - } -} */