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
node-graph/.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "non-static-any"]
path = non-static-any
url = git@github.com:TrueDoctor/non-static-any.git

22
node-graph/Cargo.lock generated
View file

@ -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",

1
node-graph/dyn-any Submodule

@ -0,0 +1 @@
Subproject commit dd588ea0f72c0e12d86506047652b38f644bd5ca

View file

@ -3,8 +3,10 @@ name = "graphene-core"
version = "0.1.0"
edition = "2021"
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
[dependencies]
dyn-any = {path = "../dyn-any", features = ["derive"]}

View file

@ -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 = <Self as Exec<'n>>::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::<I>().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::<I>(input).unwrap_or_else(|| {
panic!(
"Node was evaluated with wrong input. The input has to be of type: {}",
std::any::type_name::<I>(),

View file

@ -1,20 +1,20 @@
use std::{any::Any, marker::PhantomData};
use crate::{Exec, Node};
use crate::Node;
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;
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<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;
fn exec(&self) -> T {
fn eval(&self, _input: &()) -> T {
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>(
&'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> {

View file

@ -3,6 +3,7 @@ name = "graphene-std"
version = "0.1.0"
edition = "2021"
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
@ -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 }

View file

@ -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<F32Node<'n>>,
pub b: Option<F32Node<'n>>,
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<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 {
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 ()) -> <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 }
};
}
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::<u32>::default().eval((int.exec(), int.exec()));
//let fnode = generic::FnNode::new(|(a, b): &(i32, i32)| a - b);
//let sub = fnode.any(&("a", 2));

View file

@ -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);

View file

@ -1,8 +1,8 @@
[package]
name = "graph-proc-macros"
version = "0.1.0"
authors = ["Graphite Authors <contact@graphite.design>"]
edition = "2018"
authors = ["Dennis Kobert <dennis@kobert.dev>"]
edition = "2021"
publish = false
[lib]

View file

@ -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,)*
}