Restructure node graph proxy architecture

This commit is contained in:
Dennis
2022-04-03 19:25:07 +02:00
committed by Keavon Chambers
parent cb337fd338
commit 90e465b35c
11 changed files with 128 additions and 81 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "non-static-any"]
path = non-static-any
url = git@github.com:TrueDoctor/non-static-any.git
+22
View File
@@ -184,6 +184,24 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bda8e21c04aca2ae33ffc2fd8c23134f3cac46db123ba97bd9d3f3b8a4a85e1" 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]] [[package]]
name = "either" name = "either"
version = "1.6.1" version = "1.6.1"
@@ -235,11 +253,15 @@ dependencies = [
[[package]] [[package]]
name = "graphene-core" name = "graphene-core"
version = "0.1.0" version = "0.1.0"
dependencies = [
"dyn-any",
]
[[package]] [[package]]
name = "graphene-std" name = "graphene-std"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"dyn-any",
"graph-proc-macros", "graph-proc-macros",
"graphene-core", "graphene-core",
"lock_api", "lock_api",
Submodule node-graph/dyn-any added at dd588ea0f7
+2
View File
@@ -3,8 +3,10 @@ name = "graphene-core"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Api definitions for graphene" description = "Api definitions for graphene"
authors = ["Dennis Kobert <dennis@kobert.dev>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
dyn-any = {path = "../dyn-any", features = ["derive"]}
+19 -28
View File
@@ -3,6 +3,7 @@ pub mod ops;
pub mod structural; pub mod structural;
pub mod value; pub mod value;
use dyn_any::{downcast_ref, DynAny, StaticType};
use std::any::Any; use std::any::Any;
#[rustfmt::skip] #[rustfmt::skip]
@@ -12,42 +13,32 @@ pub trait Node< 'n, Input> {
fn eval(&'n self, input: &'n Input) -> Self::Output; fn eval(&'n self, input: &'n Input) -> Self::Output;
} }
pub trait Exec<'n> { pub trait Exec<'n>: Node<'n, ()> {
type Output: 'n; fn exec(&'n self) -> Self::Output {
fn exec(&'n self) -> Self::Output; self.eval(&())
}
impl<'n, T: Exec<'n>> Node<'n, ()> for T {
type Output = <Self as Exec<'n>>::Output;
fn eval(&'n self, _input: &()) -> Self::Output {
self.exec()
} }
} }
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> { pub trait DynamicInput<'n> {
fn set_kwarg_by_name( fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>);
&mut self, fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>);
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)>,
);
} }
pub trait AnyRef<'n, I>: Node<'n, I> { pub trait AnyRef<'n, I: StaticType<'n>>: Node<'n, I> {
fn any(&'n self, input: &'n dyn Any) -> Self::Output fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output;
where
I: 'static + Copy;
} }
impl<'n, T: Node<'n, I>, I> AnyRef<'n, I> for T { impl<'n, T: Node<'n, I>, I: StaticType<'n>> AnyRef<'n, I> for T {
fn any(&'n self, input: &'n dyn Any) -> Self::Output fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output {
where self.eval(downcast_ref::<I>(input).unwrap_or_else(|| {
I: 'static + Copy,
{
self.eval(input.downcast_ref::<I>().unwrap_or_else(|| {
panic!( panic!(
"Node was evaluated with wrong input. The input has to be of type: {}", "Node was evaluated with wrong input. The input has to be of type: {}",
std::any::type_name::<I>(), std::any::type_name::<I>(),
+13 -12
View File
@@ -1,20 +1,20 @@
use std::{any::Any, marker::PhantomData}; use std::{any::Any, marker::PhantomData};
use crate::{Exec, Node}; use crate::Node;
pub struct IntNode<const N: u32>; pub struct IntNode<const N: u32>;
impl<'n, const N: u32> Exec<'n> for IntNode<N> { impl<'n, const N: u32> Node<'n, ()> for IntNode<N> {
type Output = u32; type Output = u32;
fn exec(&self) -> u32 { fn eval(&self, _input: &()) -> u32 {
N N
} }
} }
#[derive(Default)] #[derive(Default)]
pub struct ValueNode<'n, T>(T, PhantomData<&'n ()>); 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; type Output = &'n T;
fn exec(&'n self) -> &'n T { fn eval(&self, _input: &()) -> &T {
&self.0 &self.0
} }
} }
@@ -26,9 +26,9 @@ impl<'n, T> ValueNode<'n, T> {
#[derive(Default)] #[derive(Default)]
pub struct DefaultNode<T>(PhantomData<T>); pub struct DefaultNode<T>(PhantomData<T>);
impl<'n, T: Default + 'n> Exec<'n> for DefaultNode<T> { impl<'n, T: Default + 'n> Node<'n, ()> for DefaultNode<T> {
type Output = T; type Output = T;
fn exec(&self) -> T { fn eval(&self, _input: &()) -> T {
T::default() T::default()
} }
} }
@@ -38,13 +38,14 @@ impl<T> DefaultNode<T> {
} }
} }
use dyn_any::{DynAny, StaticType};
pub struct AnyRefNode<'n, N: Node<'n, I, Output = &'n O>, I, O>( pub struct AnyRefNode<'n, N: Node<'n, I, Output = &'n O>, I, O>(
&'n N, &'n N,
PhantomData<&'n I>, PhantomData<&'n I>,
PhantomData<&'n O>, PhantomData<&'n O>,
); );
impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'static> Node<'n, I> for AnyRefNode<'n, N, I, O> { 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 Any + 'static); type Output = &'n (dyn DynAny<'n>);
fn eval(&'n self, input: &'n I) -> Self::Output { fn eval(&'n self, input: &'n I) -> Self::Output {
let value: &O = self.0.eval(input); let value: &O = self.0.eval(input);
value 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>); 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; type Output = &'n T;
fn exec(&'n self) -> &'n T { fn eval(&'n self, _input: &'n ()) -> &'n T {
self.0.exec() self.0.eval(&())
} }
} }
impl<'n, T: Default> Default for DefaultRefNode<'n, T> { impl<'n, T: Default> Default for DefaultRefNode<'n, T> {
+2
View File
@@ -3,6 +3,7 @@ name = "graphene-std"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Graphene standard library" description = "Graphene standard library"
authors = ["Dennis Kobert <dennis@kobert.dev>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -16,6 +17,7 @@ default = ["derive", "memoization"]
[dependencies] [dependencies]
graphene-core = {path = "../gcore"} graphene-core = {path = "../gcore"}
dyn-any = {path = "../dyn-any", features = ["derive"]}
graph-proc-macros = {path = "../proc-macro", optional = true} graph-proc-macros = {path = "../proc-macro", optional = true}
once_cell = {version= "1.10", optional = true} once_cell = {version= "1.10", optional = true}
ide = { version = "*", package = "ra_ap_ide", optional = true } ide = { version = "*", package = "ra_ap_ide", optional = true }
+52 -37
View File
@@ -1,56 +1,70 @@
//#![feature(generic_associated_types)] //#![feature(generic_associated_types)]
use dyn_any::StaticType;
use graphene_std::value::{AnyRefNode, ValueNode}; use graphene_std::value::{AnyRefNode, ValueNode};
use graphene_std::*; use graphene_std::*;
/*fn mul(a: f32, b: f32) -> f32 { /*fn mul(#[dyn_any(default)] a: f32, b: f32) -> f32 {
a * b a * b
}*/ }*/
mod mul { mod mul {
use graphene_std::{DynamicInput, Node}; use dyn_any::{downcast_ref, DynAny, StaticType};
use std::any::Any; use graphene_std::{DynAnyNode, DynNode, DynamicInput, Node};
type F32Node<'n> = &'n (dyn Node<'n, (), Output = &'n (dyn Any + 'static)> + 'n); pub struct MulNodeInput<'n> {
#[derive(Copy, Clone)] pub a: &'n f32,
pub struct MulNode<'n> { pub b: &'n f32,
pub a: Option<F32Node<'n>>,
pub b: Option<F32Node<'n>>,
} }
impl<'n> Node<'n, ()> for MulNode<'n> { #[derive(Copy, Clone)]
type Output = f32; pub struct MulNodeAnyProxy<'n> {
pub a: Option<DynAnyNode<'n>>,
pub b: Option<DynAnyNode<'n>>,
}
#[derive(Copy, Clone)]
pub struct MulNodeTypedProxy<'n> {
pub a: Option<DynNode<'n, &'n f32>>,
pub b: Option<DynNode<'n, &'n f32>>,
}
impl<'n> Node<'n, ()> for MulNodeAnyProxy<'n> {
type Output = MulNodeInput<'n>;
fn eval(&'n self, _input: &'n ()) -> <Self as graphene_std::Node<'n, ()>>::Output { fn eval(&'n self, _input: &'n ()) -> <Self as graphene_std::Node<'n, ()>>::Output {
let a = self.a.unwrap().eval(&());
let a: &f32 = self let a: &f32 = self
.a .a
.map(|v| v.eval(&()).downcast_ref().unwrap()) .map(|v| downcast_ref(v.eval(&())).unwrap())
.unwrap_or(&2.);
let b: &f32 = self
.b
.map(|v| v.eval(&()).downcast_ref().unwrap())
.unwrap_or(&1.); .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 ()) -> <Self as graphene_std::Node<'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 } mul::MulNode { a: None, b: None }
}; };
} }*/
pub(crate) use new; //pub(crate) use new;
impl<'i: 'f, 'f> DynamicInput<'f> for MulNode<'f> { impl<'n> DynamicInput<'n> for MulNodeAnyProxy<'n> {
fn set_kwarg_by_name( fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>) {
&mut self,
name: &str,
value: &'f dyn Node<'f, (), Output = &'f (dyn Any + 'static)>,
) {
todo!() todo!()
} }
fn set_arg_by_index( fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>) {
&mut self,
index: usize,
value: &'f dyn Node<'f, (), Output = &'f (dyn Any + 'static)>,
) {
match index { match index {
0 => self.a = Some(value), 0 => {
self.a = Some(value);
}
_ => todo!(), _ => todo!(),
} }
} }
@@ -59,20 +73,21 @@ mod mul {
fn main() { fn main() {
//let mut mul = mul::MulNode::new(); //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 any_a = AnyRefNode::new(&a);
let _mul2 = mul::MulNode { /*let _mul2 = mul::MulNodeInput {
a: None, a: None,
b: Some(&any_a), b: Some(&any_a),
}; };
let mut mul2 = mul::new!(); let mut mul2 = mul::new!();
//let cached = memo::CacheNode::new(&mul1); //let cached = memo::CacheNode::new(&mul1);
//let foo = value::AnyRefNode::new(&cached); //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>; let int = value::IntNode::<32>;
int.eval(&()); int.exec();
println!("{}", mul2.eval(&())); println!("{}", int.exec());
//let _add: u32 = ops::AddNode::<u32>::default().eval((int.exec(), int.exec())); //let _add: u32 = ops::AddNode::<u32>::default().eval((int.exec(), int.exec()));
//let fnode = generic::FnNode::new(|(a, b): &(i32, i32)| a - b); //let fnode = generic::FnNode::new(|(a, b): &(i32, i32)| a - b);
//let sub = fnode.any(&("a", 2)); //let sub = fnode.any(&("a", 2));
+10 -1
View File
@@ -1,4 +1,4 @@
use graphene_core::Node; use graphene_core::{Cache, Node};
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
/// Caches the output of a given Node and acts as a proxy /// 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);
+2 -2
View File
@@ -1,8 +1,8 @@
[package] [package]
name = "graph-proc-macros" name = "graph-proc-macros"
version = "0.1.0" version = "0.1.0"
authors = ["Graphite Authors <contact@graphite.design>"] authors = ["Dennis Kobert <dennis@kobert.dev>"]
edition = "2018" edition = "2021"
publish = false publish = false
[lib] [lib]
+2 -1
View File
@@ -79,7 +79,8 @@ fn generate_to_string(parsed: ItemFn, string: String) -> TokenStream {
let x = quote! { let x = quote! {
//#whole_function //#whole_function
mod #fn_name { 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 { struct #struct_name {
#(#idents: #types,)* #(#idents: #types,)*
} }