diff --git a/node-graph/.gitmodules b/node-graph/.gitmodules new file mode 100644 index 00000000..c2ad165c --- /dev/null +++ b/node-graph/.gitmodules @@ -0,0 +1,3 @@ +[submodule "non-static-any"] + path = non-static-any + url = git@github.com:TrueDoctor/non-static-any.git diff --git a/node-graph/Cargo.lock b/node-graph/Cargo.lock index 0a495403..53d3da95 100644 --- a/node-graph/Cargo.lock +++ b/node-graph/Cargo.lock @@ -184,6 +184,24 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" +[[package]] +name = "dyn-any" +version = "0.2.0" +dependencies = [ + "dyn-any-derive", +] + +[[package]] +name = "dyn-any-derive" +version = "0.2.0" +dependencies = [ + "dyn-any", + "proc-macro2", + "proc_macro_roids", + "quote", + "syn", +] + [[package]] name = "either" version = "1.6.1" @@ -235,11 +253,15 @@ dependencies = [ [[package]] name = "graphene-core" version = "0.1.0" +dependencies = [ + "dyn-any", +] [[package]] name = "graphene-std" version = "0.1.0" dependencies = [ + "dyn-any", "graph-proc-macros", "graphene-core", "lock_api", diff --git a/node-graph/dyn-any b/node-graph/dyn-any new file mode 160000 index 00000000..dd588ea0 --- /dev/null +++ b/node-graph/dyn-any @@ -0,0 +1 @@ +Subproject commit dd588ea0f72c0e12d86506047652b38f644bd5ca diff --git a/node-graph/gcore/Cargo.toml b/node-graph/gcore/Cargo.toml index 487ae7b3..692742dc 100644 --- a/node-graph/gcore/Cargo.toml +++ b/node-graph/gcore/Cargo.toml @@ -3,8 +3,10 @@ name = "graphene-core" version = "0.1.0" edition = "2021" description = "Api definitions for graphene" +authors = ["Dennis Kobert "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +dyn-any = {path = "../dyn-any", features = ["derive"]} diff --git a/node-graph/gcore/src/lib.rs b/node-graph/gcore/src/lib.rs index 4271730d..17e9d5cf 100644 --- a/node-graph/gcore/src/lib.rs +++ b/node-graph/gcore/src/lib.rs @@ -3,6 +3,7 @@ pub mod ops; pub mod structural; pub mod value; +use dyn_any::{downcast_ref, DynAny, StaticType}; use std::any::Any; #[rustfmt::skip] @@ -12,42 +13,32 @@ pub trait Node< 'n, Input> { fn eval(&'n self, input: &'n Input) -> Self::Output; } -pub trait Exec<'n> { - type Output: 'n; - fn exec(&'n self) -> Self::Output; -} -impl<'n, T: Exec<'n>> Node<'n, ()> for T { - type Output = >::Output; - fn eval(&'n self, _input: &()) -> Self::Output { - self.exec() +pub trait Exec<'n>: Node<'n, ()> { + fn exec(&'n self) -> Self::Output { + self.eval(&()) } } +impl<'n, T: Node<'n, ()>> Exec<'n> for T {} + +pub trait Cache { + fn clear(&mut self); +} + +pub type DynNode<'n, T> = &'n (dyn Node<'n, (), Output = T> + 'n); +pub type DynAnyNode<'n> = &'n (dyn Node<'n, (), Output = &'n dyn DynAny<'n>> + 'n); 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)>, - ); + fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>); + fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>); } -pub trait AnyRef<'n, I>: Node<'n, I> { - fn any(&'n self, input: &'n dyn Any) -> Self::Output - where - I: 'static + Copy; +pub trait AnyRef<'n, I: StaticType<'n>>: Node<'n, I> { + fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output; } -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(input.downcast_ref::().unwrap_or_else(|| { +impl<'n, T: Node<'n, I>, I: StaticType<'n>> AnyRef<'n, I> for T { + fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output { + self.eval(downcast_ref::(input).unwrap_or_else(|| { panic!( "Node was evaluated with wrong input. The input has to be of type: {}", std::any::type_name::(), diff --git a/node-graph/gcore/src/value.rs b/node-graph/gcore/src/value.rs index 64df2eb1..f8c010c4 100644 --- a/node-graph/gcore/src/value.rs +++ b/node-graph/gcore/src/value.rs @@ -1,20 +1,20 @@ use std::{any::Any, marker::PhantomData}; -use crate::{Exec, Node}; +use crate::Node; pub struct IntNode; -impl<'n, const N: u32> Exec<'n> for IntNode { +impl<'n, const N: u32> Node<'n, ()> for IntNode { type Output = u32; - fn exec(&self) -> u32 { + fn eval(&self, _input: &()) -> u32 { N } } #[derive(Default)] pub struct ValueNode<'n, T>(T, PhantomData<&'n ()>); -impl<'n, T: 'n> Exec<'n> for ValueNode<'n, T> { +impl<'n, T: 'n> Node<'n, ()> for ValueNode<'n, T> { type Output = &'n T; - fn exec(&'n self) -> &'n T { + fn eval(&self, _input: &()) -> &T { &self.0 } } @@ -26,9 +26,9 @@ impl<'n, T> ValueNode<'n, T> { #[derive(Default)] pub struct DefaultNode(PhantomData); -impl<'n, T: Default + 'n> Exec<'n> for DefaultNode { +impl<'n, T: Default + 'n> Node<'n, ()> for DefaultNode { type Output = T; - fn exec(&self) -> T { + fn eval(&self, _input: &()) -> T { T::default() } } @@ -38,13 +38,14 @@ impl DefaultNode { } } +use dyn_any::{DynAny, StaticType}; 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); +impl<'n, N: Node<'n, I, Output = &'n O>, I, O: DynAny<'n>> Node<'n, I> for AnyRefNode<'n, N, I, O> { + type Output = &'n (dyn DynAny<'n>); fn eval(&'n self, input: &'n I) -> Self::Output { let value: &O = self.0.eval(input); value @@ -57,10 +58,10 @@ impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'static> AnyRefNode<'n, N, I, O> } pub struct DefaultRefNode<'n, T>(ValueNode<'n, T>); -impl<'n, T: 'n> Exec<'n> for DefaultRefNode<'n, T> { +impl<'n, T: 'n> Node<'n, ()> for DefaultRefNode<'n, T> { type Output = &'n T; - fn exec(&'n self) -> &'n T { - self.0.exec() + fn eval(&'n self, _input: &'n ()) -> &'n T { + self.0.eval(&()) } } impl<'n, T: Default> Default for DefaultRefNode<'n, T> { diff --git a/node-graph/gstd/Cargo.toml b/node-graph/gstd/Cargo.toml index 004cc017..22e5608a 100644 --- a/node-graph/gstd/Cargo.toml +++ b/node-graph/gstd/Cargo.toml @@ -3,6 +3,7 @@ name = "graphene-std" version = "0.1.0" edition = "2021" description = "Graphene standard library" +authors = ["Dennis Kobert "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -16,6 +17,7 @@ default = ["derive", "memoization"] [dependencies] graphene-core = {path = "../gcore"} +dyn-any = {path = "../dyn-any", features = ["derive"]} graph-proc-macros = {path = "../proc-macro", optional = true} once_cell = {version= "1.10", optional = true} ide = { version = "*", package = "ra_ap_ide", optional = true } diff --git a/node-graph/gstd/src/main.rs b/node-graph/gstd/src/main.rs index f2e26325..3955ebbf 100644 --- a/node-graph/gstd/src/main.rs +++ b/node-graph/gstd/src/main.rs @@ -1,56 +1,70 @@ //#![feature(generic_associated_types)] +use dyn_any::StaticType; use graphene_std::value::{AnyRefNode, ValueNode}; use graphene_std::*; -/*fn mul(a: f32, b: f32) -> f32 { +/*fn mul(#[dyn_any(default)] a: f32, b: f32) -> f32 { a * b }*/ mod mul { - 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> { - pub a: Option>, - pub b: Option>, + use dyn_any::{downcast_ref, DynAny, StaticType}; + use graphene_std::{DynAnyNode, DynNode, DynamicInput, Node}; + pub struct MulNodeInput<'n> { + pub a: &'n f32, + pub b: &'n f32, } - impl<'n> Node<'n, ()> for MulNode<'n> { - type Output = f32; + #[derive(Copy, Clone)] + pub struct MulNodeAnyProxy<'n> { + pub a: Option>, + pub b: Option>, + } + #[derive(Copy, Clone)] + pub struct MulNodeTypedProxy<'n> { + pub a: Option>, + pub b: Option>, + } + impl<'n> Node<'n, ()> for MulNodeAnyProxy<'n> { + type Output = MulNodeInput<'n>; fn eval(&'n self, _input: &'n ()) -> >::Output { + let a = self.a.unwrap().eval(&()); 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()) + .map(|v| downcast_ref(v.eval(&())).unwrap()) .unwrap_or(&1.); - a * b + /*let b: &f32 = self + .b + .map(|v| v.eval(&()).downcast_ref::<&'n f32, &'n f32>().unwrap()) + .unwrap_or(&&2.); + a * b*/ + MulNodeInput { a, b: a } } } - macro_rules! new { + impl<'n> Node<'n, ()> for MulNodeTypedProxy<'n> { + type Output = MulNodeInput<'n>; + fn eval(&'n self, _input: &'n ()) -> >::Output { + let a = self.a.unwrap().eval(&()); + let b = self.b.unwrap().eval(&()); + MulNodeInput { a, b } + } + } + + /*macro_rules! new { () => { mul::MulNode { a: None, b: None } }; - } - pub(crate) use new; + }*/ + //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)>, - ) { + impl<'n> DynamicInput<'n> for MulNodeAnyProxy<'n> { + fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>) { todo!() } - fn set_arg_by_index( - &mut self, - index: usize, - value: &'f dyn Node<'f, (), Output = &'f (dyn Any + 'static)>, - ) { + fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>) { match index { - 0 => self.a = Some(value), + 0 => { + self.a = Some(value); + } _ => todo!(), } } @@ -59,20 +73,21 @@ mod mul { fn main() { //let mut mul = mul::MulNode::new(); - let a = ValueNode::new(3.4f32); + let f = (3.2f32, 3.1f32); + let a = ValueNode::new(1.); + let id = std::any::TypeId::of::<&f32>(); let any_a = AnyRefNode::new(&a); - let _mul2 = mul::MulNode { + /*let _mul2 = mul::MulNodeInput { 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); - + mul2.set_arg_by_index(0, &any_a);*/ let int = value::IntNode::<32>; - int.eval(&()); - println!("{}", mul2.eval(&())); + int.exec(); + println!("{}", int.exec()); //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)); diff --git a/node-graph/gstd/src/memo.rs b/node-graph/gstd/src/memo.rs index 8413048d..110c2775 100644 --- a/node-graph/gstd/src/memo.rs +++ b/node-graph/gstd/src/memo.rs @@ -1,4 +1,4 @@ -use graphene_core::Node; +use graphene_core::{Cache, Node}; use once_cell::sync::OnceCell; /// Caches the output of a given Node and acts as a proxy @@ -24,3 +24,12 @@ impl<'n, CachedNode: Node<'n, Input>, Input> CacheNode<'n, CachedNode, Input> { } } } +impl<'n, CachedNode: Node<'n, Input>, Input> Cache for CacheNode<'n, CachedNode, Input> { + fn clear(&mut self) { + self.cache = OnceCell::new(); + } +} + +use dyn_any::{DynAny, StaticType}; +#[derive(DynAny)] +struct Boo<'a>(&'a u8); diff --git a/node-graph/proc-macro/Cargo.toml b/node-graph/proc-macro/Cargo.toml index bf70dff8..f9c6e682 100644 --- a/node-graph/proc-macro/Cargo.toml +++ b/node-graph/proc-macro/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "graph-proc-macros" version = "0.1.0" -authors = ["Graphite Authors "] -edition = "2018" +authors = ["Dennis Kobert "] +edition = "2021" publish = false [lib] diff --git a/node-graph/proc-macro/src/lib.rs b/node-graph/proc-macro/src/lib.rs index e398e919..05e3862b 100644 --- a/node-graph/proc-macro/src/lib.rs +++ b/node-graph/proc-macro/src/lib.rs @@ -79,7 +79,8 @@ fn generate_to_string(parsed: ItemFn, string: String) -> TokenStream { let x = quote! { //#whole_function mod #fn_name { - #(const #const_idents: DefaultNode<#types> = DefaultNode::new();)* + #[derive(Copy, Clone)] + type F32Node<'n> = &'n (dyn Node<'n, (), Output = &'n (dyn Any + 'static)> + 'n); struct #struct_name { #(#idents: #types,)* }