diff --git a/node-graph/Cargo.lock b/node-graph/Cargo.lock index 3817bd193..0a495403e 100644 --- a/node-graph/Cargo.lock +++ b/node-graph/Cargo.lock @@ -93,12 +93,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "const-default" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" - [[package]] name = "countme" version = "3.0.1" @@ -241,9 +235,6 @@ dependencies = [ [[package]] name = "graphene-core" version = "0.1.0" -dependencies = [ - "const-default", -] [[package]] name = "graphene-std" diff --git a/node-graph/gcore/Cargo.toml b/node-graph/gcore/Cargo.toml index 34c2f65a0..487ae7b3d 100644 --- a/node-graph/gcore/Cargo.toml +++ b/node-graph/gcore/Cargo.toml @@ -6,9 +6,5 @@ description = "Api definitions for graphene" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[features] -const_default = ["const-default"] -default = ["const_default"] [dependencies] -const-default = { version = "1.0", optional = true } diff --git a/node-graph/gcore/src/generic.rs b/node-graph/gcore/src/generic.rs index 585d4fc9d..c361ad9d3 100644 --- a/node-graph/gcore/src/generic.rs +++ b/node-graph/gcore/src/generic.rs @@ -2,11 +2,10 @@ use std::{borrow::Borrow, marker::PhantomData}; use crate::Node; pub struct FnNode O, In, O>(T, PhantomData, PhantomData); -impl O, In, O> Node for FnNode { - type Output<'a> = O where Self: 'a; - type Input<'a> = In where Self: 'a; +impl<'n, T: Fn(&In) -> O, In, O: 'n> Node<'n, In> for FnNode { + type Output = O; - fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a> { + fn eval(&'n self, input: &'n In) -> Self::Output { self.0(input.borrow()) } } @@ -23,11 +22,12 @@ pub struct FnNodeWithState O, In, O, State>( PhantomData, PhantomData, ); -impl O, In, O, State> Node for FnNodeWithState { - type Output<'a> = O where Self: 'a; - type Input<'a> = In where Self: 'a; +impl<'n, T: Fn(&In, &State) -> O, In, O: 'n, State> Node<'n, In> + for FnNodeWithState +{ + type Output = O; - fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a> { + fn eval(&'n self, input: &'n In) -> Self::Output { self.0(input.borrow(), &self.1) } } diff --git a/node-graph/gcore/src/lib.rs b/node-graph/gcore/src/lib.rs index f7f9e6030..4271730d1 100644 --- a/node-graph/gcore/src/lib.rs +++ b/node-graph/gcore/src/lib.rs @@ -1,90 +1,57 @@ -#![feature(generic_associated_types)] pub mod generic; pub mod ops; pub mod structural; pub mod value; -use std::{any::Any, borrow::Borrow, ops::Deref}; +use std::any::Any; #[rustfmt::skip] -pub trait Node { - // 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 Input<'i> where Self: 'i; - type Output<'o> where Self: 'o; +pub trait Node< 'n, Input> { + type Output : 'n; - fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a>; + fn eval(&'n self, input: &'n Input) -> Self::Output; } -pub trait SimpleNode<'n, I, O> { - fn eval_simple(&self, input: &I) -> &O; +pub trait Exec<'n> { + type Output: 'n; + fn exec(&'n self) -> Self::Output; } - -impl SimpleNode<'n, I, O>, I, O> Node for T { - type Input<'i> = &'i I where Self: 'i; - type Output<'o> = &'o O where Self: 'o; - - fn eval<'a, In: Borrow>>(&'a self, input: In) -> Self::Output<'a> { - self.eval_simple(input.borrow()) +impl<'n, T: Exec<'n>> Node<'n, ()> for T { + type Output = >::Output; + fn eval(&'n self, _input: &()) -> Self::Output { + self.exec() } } -#[rustfmt::skip] -pub trait OutputNode<'a, T>: Node = T> where Self: 'a {} -#[rustfmt::skip] -pub trait ArgNode<'a, T>: OutputNode<'a, T> + Node = ()> where Self: 'a {} - -pub trait AnyRef: Node { - fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Output<'a> - where - Self::Input<'a>: 'static + Copy; +pub trait DynamicInput<'n> { + fn set_kwarg_by_name( + &mut self, + name: &str, + value: &'n dyn Node<'n, (), Output = &'n (dyn Any + 'static)>, + ); + fn set_arg_by_index( + &mut self, + index: usize, + value: &'n dyn Node<'n, (), Output = &'n (dyn Any + 'static)>, + ); } -impl AnyRef for T { - fn any<'a>(&'a self, input: &'a dyn Any) -> Self::Output<'a> +pub trait AnyRef<'n, I>: Node<'n, I> { + fn any(&'n self, input: &'n dyn Any) -> Self::Output where - Self::Input<'a>: 'static + Copy, + I: 'static + Copy; +} + +impl<'n, T: Node<'n, I>, I> AnyRef<'n, I> for T { + fn any(&'n self, input: &'n dyn Any) -> Self::Output + where + I: 'static + Copy, { - self.eval::<&Self::Input<'a>>(input.downcast_ref::>().unwrap_or_else( - || { - panic!( - "Node was evaluated with wrong input. The input has to be of type: {}", - std::any::type_name::>(), - ) - }, - )) + self.eval(input.downcast_ref::().unwrap_or_else(|| { + panic!( + "Node was evaluated with wrong input. The input has to be of type: {}", + std::any::type_name::(), + ) + })) } } - -trait Ref: Node {} -impl<'a, T: 'a, N: Node = &'a T> + 'a> Ref for N {} - -pub trait ExecPtr<'n, T>: Node { - fn fn_ptr(&self) -> &T; -} - -impl<'n, T: 'n, N: Ref> ExecPtr<'n, T> for N -where - for<'a> &'a (): Borrow<::Input<'a>>, - for<'a> &'a T: From>, -{ - fn fn_ptr(&self) -> &T { - let value: &T = self.eval(&()).into(); - value - } -} - -pub trait Exec: Node -where - for<'a> &'a (): Borrow<::Input<'a>>, -{ - fn exec(&self) -> Self::Output<'_> { - self.eval(&()) - } -} -impl Exec for T where for<'a> &'a (): Borrow<::Input<'a>> {} - -pub trait DynamicInput { - fn set_kwarg_by_name(&mut self, name: &str, value: &dyn Any); - fn set_arg_by_index(&mut self, index: usize, value: &dyn Any); -} diff --git a/node-graph/gcore/src/ops.rs b/node-graph/gcore/src/ops.rs index 670b7eb9f..2da62e04a 100644 --- a/node-graph/gcore/src/ops.rs +++ b/node-graph/gcore/src/ops.rs @@ -4,21 +4,20 @@ use crate::Node; #[derive(Default)] pub struct AddNode(PhantomData); -impl Node for AddNode { - 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 +impl<'n, T: std::ops::Add + Copy + 'n> Node<'n, (T, T)> for AddNode { + type Output = ::Output; + fn eval(&'n self, input: &'n (T, T)) -> T::Output { + let (ref a, ref b) = input.borrow(); + *a + *b } } #[derive(Default)] /// Destructures a Tuple of two values and returns the first one pub struct FstNode(PhantomData, PhantomData); -impl Node for FstNode { - type Output<'a> = &'a T where Self: 'a; - type Input<'a> = &'a (T, U) where Self: 'a; - fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a> { +impl<'n, T: Copy + 'n, U> Node<'n, (T, U)> for FstNode { + type Output = &'n T; + fn eval(&'n self, input: &'n (T, U)) -> Self::Output { let &(ref a, _) = input.borrow(); a } @@ -27,10 +26,9 @@ impl Node for FstNode { #[derive(Default)] /// Destructures a Tuple of two values and returns the first one pub struct SndNode(PhantomData, PhantomData); -impl Node for SndNode { - type Output<'a> = &'a U where Self: 'a; - type Input<'a> = &'a (T, U) where Self: 'a; - fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a> { +impl<'n, T, U: Copy + 'n> Node<'n, (T, U)> for SndNode { + type Output = &'n U; + fn eval(&'n self, input: &'n (T, U)) -> Self::Output { let &(_, ref b) = input.borrow(); b } diff --git a/node-graph/gcore/src/structural.rs b/node-graph/gcore/src/structural.rs index d3feec5fb..dffbfd1dc 100644 --- a/node-graph/gcore/src/structural.rs +++ b/node-graph/gcore/src/structural.rs @@ -1,60 +1,51 @@ -use std::{any::Any, borrow::Borrow}; +use std::marker::PhantomData; -use crate::{DynamicInput, Node}; -pub struct ComposeNode<'n, FIRST, SECOND> { +use crate::Node; + +pub struct ComposeNode<'n, Input, Inter, FIRST, SECOND> { first: &'n FIRST, second: &'n SECOND, + _phantom: PhantomData<&'n Input>, + _phantom2: PhantomData, } -impl<'n, FIRST, SECOND> Node for ComposeNode<'n, FIRST, SECOND> +impl<'n, Input: 'n, Inter: 'n, First, Second> Node<'n, Input> + for ComposeNode<'n, Input, Inter, First, Second> where - FIRST: Node, - SECOND: Node, - for<'a> FIRST::Output<'a>: Borrow>, + First: Node<'n, Input, Output = &'n Inter>, + Second: Node<'n, Inter>, /*+ Node<>::Output<'n>>*/ { - type Input<'a> = FIRST::Input<'a> where Self: 'a; - type Output<'a> = SECOND::Output<'a> where Self: 'a; + type Output = >::Output; - fn eval<'a, I: Borrow>>(&'a self, input: I) -> Self::Output<'a> { + fn eval(&'n self, input: &'n Input) -> Self::Output { // 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); + let arg: &Inter = self.first.eval(input); self.second.eval(arg) } } -impl<'n, FIRST, SECOND> ComposeNode<'n, FIRST, SECOND> +impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND> where - FIRST: Node, + FIRST: Node<'n, Input>, { pub fn new(first: &'n FIRST, second: &'n SECOND) -> Self { - ComposeNode::<'n, FIRST, SECOND> { first, second } + ComposeNode::<'n, Input, Inter, FIRST, SECOND> { + first, + second, + _phantom: PhantomData, + _phantom2: PhantomData, + } } } -pub trait After: Sized { - fn after<'a, First: Node>(&'a self, first: &'a First) -> ComposeNode<'a, First, Self> { +pub trait After: Sized { + fn after<'n, First: Node<'n, I>>( + &'n self, + first: &'n First, + ) -> ComposeNode<'n, I, >::Output, First, Self> { ComposeNode::new(first, self) } } -impl After for Second {} - -pub struct ProxyNode(T); -impl Node for ProxyNode { - type Output<'a> = &'a T where Self: 'a; - type Input<'a> = &'a () where Self: 'a; - - fn eval<'a, I: Borrow>>(&'a self, _input: I) -> Self::Output<'a> { - &self.0 - } -} -impl DynamicInput for ProxyNode { - fn set_kwarg_by_name(&mut self, name: &str, value: &dyn Any) { - self.0.set_kwarg_by_name(name, value) - } - - fn set_arg_by_index(&mut self, index: usize, value: &dyn Any) { - self.0.set_arg_by_index(index, value) - } -} +impl Node<'n, I>, I> After for Second {} diff --git a/node-graph/gcore/src/value.rs b/node-graph/gcore/src/value.rs index edae1647f..64df2eb1b 100644 --- a/node-graph/gcore/src/value.rs +++ b/node-graph/gcore/src/value.rs @@ -1,39 +1,34 @@ -use std::{borrow::Borrow, marker::PhantomData}; - -use const_default::ConstDefault; +use std::{any::Any, marker::PhantomData}; use crate::{Exec, Node}; pub struct IntNode; -impl Node for IntNode { - type Input<'o> = (); - type Output<'i> = u32; - fn eval<'a, I: Borrow>>(&self, _input: I) -> u32 { +impl<'n, const N: u32> Exec<'n> for IntNode { + type Output = u32; + fn exec(&self) -> u32 { N } } #[derive(Default)] -pub struct ValueNode(T); -impl Node for ValueNode { - type Input<'i> = () where T: 'i; - type Output<'o> = &'o T where T: 'o; - fn eval<'a, I: Borrow>>(&'a self, _input: I) -> &T { +pub struct ValueNode<'n, T>(T, PhantomData<&'n ()>); +impl<'n, T: 'n> Exec<'n> for ValueNode<'n, T> { + type Output = &'n T; + fn exec(&'n self) -> &'n T { &self.0 } } -impl ValueNode { - pub const fn new(value: T) -> ValueNode { - ValueNode(value) +impl<'n, T> ValueNode<'n, T> { + pub const fn new(value: T) -> ValueNode<'n, T> { + ValueNode(value, PhantomData) } } #[derive(Default)] pub struct DefaultNode(PhantomData); -impl Node for DefaultNode { - type Input<'i> = () where T: 'i; - type Output<'o> = T where T: 'o; - fn eval<'a, I: Borrow>>(&'a self, _input: I) -> T { +impl<'n, T: Default + 'n> Exec<'n> for DefaultNode { + type Output = T; + fn exec(&self) -> T { T::default() } } @@ -43,23 +38,33 @@ impl DefaultNode { } } -pub struct DefaultRefNode(ValueNode); -impl Node for DefaultRefNode { - type Input<'i> = () where T: 'i; - type Output<'o> = &'o T where T: 'o; - fn eval<'a, I: Borrow>>(&'a self, _input: I) -> &'a T { +pub struct AnyRefNode<'n, N: Node<'n, I, Output = &'n O>, I, O>( + &'n N, + PhantomData<&'n I>, + PhantomData<&'n O>, +); +impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'static> Node<'n, I> for AnyRefNode<'n, N, I, O> { + type Output = &'n (dyn Any + 'static); + fn eval(&'n self, input: &'n I) -> Self::Output { + let value: &O = self.0.eval(input); + value + } +} +impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'static> AnyRefNode<'n, N, I, O> { + pub fn new(n: &'n N) -> AnyRefNode<'n, N, I, O> { + AnyRefNode(n, PhantomData, PhantomData) + } +} + +pub struct DefaultRefNode<'n, T>(ValueNode<'n, T>); +impl<'n, T: 'n> Exec<'n> for DefaultRefNode<'n, T> { + type Output = &'n T; + fn exec(&'n self) -> &'n T { self.0.exec() } } -#[cfg(feature = "const_default")] -impl DefaultRefNode { - pub const fn new() -> DefaultRefNode { - DefaultRefNode(ValueNode::new(T::DEFAULT)) - } -} -#[cfg(not(feature = "const_default"))] -impl DefaultRefNode { - pub fn new() -> DefaultRefNode { +impl<'n, T: Default> Default for DefaultRefNode<'n, T> { + fn default() -> DefaultRefNode<'n, T> { DefaultRefNode(ValueNode::new(T::default())) } } diff --git a/node-graph/gstd/src/lib.rs b/node-graph/gstd/src/lib.rs index dd9bbebba..62abb18b1 100644 --- a/node-graph/gstd/src/lib.rs +++ b/node-graph/gstd/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(generic_associated_types)] +//#![feature(generic_associated_types)] #[cfg(feature = "caching")] pub mod caching; diff --git a/node-graph/gstd/src/main.rs b/node-graph/gstd/src/main.rs index b7d2cf6c3..f2e26325b 100644 --- a/node-graph/gstd/src/main.rs +++ b/node-graph/gstd/src/main.rs @@ -1,4 +1,5 @@ -#![feature(generic_associated_types)] +//#![feature(generic_associated_types)] +use graphene_std::value::{AnyRefNode, ValueNode}; use graphene_std::*; /*fn mul(a: f32, b: f32) -> f32 { @@ -6,41 +7,50 @@ use graphene_std::*; }*/ mod mul { - use graphene_std::{ - value::DefaultNode, value::DefaultRefNode, ArgNode, DynamicInput, ExecPtr, Node, - }; - use std::{any::Any, ops::Deref}; - const A: DefaultRefNode = DefaultRefNode::new(); - const B: DefaultRefNode = DefaultRefNode::new(); - type F32Node<'n> = &'n dyn ExecPtr<'n, f32, Output<'n> = &'n f32, Input<'n> = ()>; + use graphene_std::{DynamicInput, Node}; + use std::any::Any; + type F32Node<'n> = &'n (dyn Node<'n, (), Output = &'n (dyn Any + 'static)> + 'n); + #[derive(Copy, Clone)] pub struct MulNode<'n> { - a: F32Node<'n>, - b: F32Node<'n>, + pub a: Option>, + pub b: Option>, } - impl<'n> Node for MulNode<'n> { - type Input<'i> = () where Self: 'i; - type Output<'o> = f32 where Self: 'o; - fn eval<'a, I>(&'a self, input: I) -> ::Output<'a> - where - I: std::borrow::Borrow>, - { - let a = self.a.fn_ptr(); - let b = self.b.fn_ptr(); + impl<'n> Node<'n, ()> for MulNode<'n> { + type Output = f32; + fn eval(&'n self, _input: &'n ()) -> >::Output { + let a: &f32 = self + .a + .map(|v| v.eval(&()).downcast_ref().unwrap()) + .unwrap_or(&2.); + let b: &f32 = self + .b + .map(|v| v.eval(&()).downcast_ref().unwrap()) + .unwrap_or(&1.); a * b } } - impl<'n> MulNode<'n> { - pub const fn new() -> Self { - Self { a: &A, b: &B } - } + macro_rules! new { + () => { + mul::MulNode { a: None, b: None } + }; } - impl DynamicInput for MulNode<'_> { - fn set_kwarg_by_name(&mut self, _: &str, _: &(dyn std::any::Any + 'static)) { + pub(crate) use new; + + impl<'i: 'f, 'f> DynamicInput<'f> for MulNode<'f> { + fn set_kwarg_by_name( + &mut self, + name: &str, + value: &'f dyn Node<'f, (), Output = &'f (dyn Any + 'static)>, + ) { todo!() } - fn set_arg_by_index(&mut self, index: usize, input: &(dyn std::any::Any + 'static)) { + fn set_arg_by_index( + &mut self, + index: usize, + value: &'f dyn Node<'f, (), Output = &'f (dyn Any + 'static)>, + ) { match index { - 0 => self.a = input.downcast_ref::<&dyn ExecPtr<'_, f32>>().unwrap(), + 0 => self.a = Some(value), _ => todo!(), } } @@ -48,14 +58,26 @@ mod mul { } fn main() { - let mut mul = mul::MulNode::new(); + //let mut mul = mul::MulNode::new(); + let a = ValueNode::new(3.4f32); + let any_a = AnyRefNode::new(&a); + let _mul2 = mul::MulNode { + a: None, + b: Some(&any_a), + }; + let mut mul2 = mul::new!(); + //let cached = memo::CacheNode::new(&mul1); + //let foo = value::AnyRefNode::new(&cached); + mul2.set_arg_by_index(0, &any_a); let int = value::IntNode::<32>; - let _add: u32 = ops::AddNode::::default().eval((int.exec(), int.exec())); - let fnode = generic::FnNode::new(|(a, b): &(i32, i32)| a - b); + int.eval(&()); + println!("{}", mul2.eval(&())); + //let _add: u32 = ops::AddNode::::default().eval((int.exec(), int.exec())); + //let fnode = generic::FnNode::new(|(a, b): &(i32, i32)| a - b); //let sub = fnode.any(&("a", 2)); - let cache = memo::CacheNode::new(&fnode); - let cached_result = cache.eval(&(2, 3)); + //let cache = memo::CacheNode::new(&fnode); + //let cached_result = cache.eval(&(2, 3)); - println!("{}", cached_result) + //println!("{}", cached_result) } diff --git a/node-graph/gstd/src/memo.rs b/node-graph/gstd/src/memo.rs index c89abc214..8413048d3 100644 --- a/node-graph/gstd/src/memo.rs +++ b/node-graph/gstd/src/memo.rs @@ -1,25 +1,23 @@ -use graphene_core::{ExecPtr, Node}; +use graphene_core::Node; use once_cell::sync::OnceCell; -use std::{any::Any, borrow::Borrow, ops::Deref}; /// Caches the output of a given Node and acts as a proxy -pub struct CacheNode<'n, 'c, CachedNode: Node + 'c> { +pub struct CacheNode<'n, CachedNode: Node<'n, Input>, Input> { node: &'n CachedNode, - cache: OnceCell>, + cache: OnceCell, } -impl<'n: 'c, 'c, CashedNode: Node> Node for CacheNode<'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::Output<'a> { +impl<'n, CashedNode: Node<'n, Input>, Input> Node<'n, Input> for CacheNode<'n, CashedNode, Input> { + type Output = &'n CashedNode::Output; + fn eval(&'n self, input: &'n Input) -> Self::Output { self.cache.get_or_init(|| self.node.eval(input)) } } -impl<'n, 'c, CachedNode: Node> CacheNode<'n, 'c, CachedNode> { +impl<'n, CachedNode: Node<'n, Input>, Input> CacheNode<'n, CachedNode, Input> { pub fn clear(&'n mut self) { self.cache = OnceCell::new(); } - pub fn new(node: &'n CachedNode) -> CacheNode<'n, 'c, CachedNode> { + pub fn new(node: &'n CachedNode) -> CacheNode<'n, CachedNode, Input> { CacheNode { node, cache: OnceCell::new(),