mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 06:38:12 +08:00
Restructure node graph proxy architecture
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "non-static-any"]
|
||||||
|
path = non-static-any
|
||||||
|
url = git@github.com:TrueDoctor/non-static-any.git
|
||||||
Generated
+22
@@ -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
+1
Submodule node-graph/dyn-any added at dd588ea0f7
@@ -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
@@ -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>(),
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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,)*
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user