mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 13:30:48 +00:00
Restructure node graph proxy architecture
This commit is contained in:
parent
cb337fd338
commit
90e465b35c
11 changed files with 128 additions and 81 deletions
3
node-graph/.gitmodules
vendored
Normal file
3
node-graph/.gitmodules
vendored
Normal 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
22
node-graph/Cargo.lock
generated
|
@ -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
1
node-graph/dyn-any
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit dd588ea0f72c0e12d86506047652b38f644bd5ca
|
|
@ -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"]}
|
||||
|
|
|
@ -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>(),
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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,)*
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue