mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 18:08:12 +08:00
Add GPU support for node graph
This commit is contained in:
Generated
+54
@@ -243,6 +243,15 @@ version = "0.4.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a"
|
checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glam"
|
||||||
|
version = "0.20.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f43e957e744be03f5801a55472f593d43fabdebf25a4585db250f04d86b1675f"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "graph-proc-macros"
|
name = "graph-proc-macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -259,6 +268,7 @@ name = "graphene-core"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dyn-any",
|
"dyn-any",
|
||||||
|
"spirv-std",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -358,6 +368,12 @@ version = "0.2.121"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libm"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
@@ -407,6 +423,16 @@ dependencies = [
|
|||||||
"windows-sys 0.28.0",
|
"windows-sys 0.28.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"libm",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.1"
|
version = "1.13.1"
|
||||||
@@ -1092,6 +1118,34 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spirv-std"
|
||||||
|
version = "0.4.0-alpha.12"
|
||||||
|
source = "git+https://github.com/EmbarkStudios/rust-gpu#685c79a9725f9fb68ce17dd00e742b98a03f3870"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"glam",
|
||||||
|
"num-traits",
|
||||||
|
"spirv-std-macros",
|
||||||
|
"spirv-types",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spirv-std-macros"
|
||||||
|
version = "0.4.0-alpha.12"
|
||||||
|
source = "git+https://github.com/EmbarkStudios/rust-gpu#685c79a9725f9fb68ce17dd00e742b98a03f3870"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"spirv-types",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spirv-types"
|
||||||
|
version = "0.4.0-alpha.12"
|
||||||
|
source = "git+https://github.com/EmbarkStudios/rust-gpu#685c79a9725f9fb68ce17dd00e742b98a03f3870"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "storage-map"
|
name = "storage-map"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|||||||
@@ -8,8 +8,12 @@ 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
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
#std = []
|
std = ["dyn-any"]
|
||||||
#default = ["std"]
|
default = ["gpu"]
|
||||||
|
gpu = ["spirv-std"]
|
||||||
|
nightly = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dyn-any = {path = "../dyn-any", features = ["derive"]}
|
dyn-any = {path = "../dyn-any", features = ["derive"], optional = true}
|
||||||
|
|
||||||
|
spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu", features = ["glam"] , optional = true}
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::Node;
|
use crate::Node;
|
||||||
pub struct FnNode<T: Fn(&In) -> O, In, O>(T, PhantomData<In>, PhantomData<O>);
|
pub struct FnNode<T: Fn(In) -> O, In, O>(T, PhantomData<In>, PhantomData<O>);
|
||||||
impl<'n, T: Fn(&In) -> O, In, O: 'n> Node<'n, In> for FnNode<T, In, O> {
|
impl<'n, T: Fn(In) -> O, In, O: 'n> Node<'n, In> for FnNode<T, In, O> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
|
||||||
fn eval(&'n self, input: &'n In) -> Self::Output {
|
fn eval(&'n self, input: In) -> Self::Output {
|
||||||
self.0(input.borrow())
|
self.0(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Fn(&In) -> O, In, O> FnNode<T, In, O> {
|
impl<T: Fn(In) -> O, In, O> FnNode<T, In, O> {
|
||||||
pub fn new(f: T) -> Self {
|
pub fn new(f: T) -> Self {
|
||||||
FnNode(f, PhantomData::default(), PhantomData::default())
|
FnNode(f, PhantomData::default(), PhantomData::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FnNodeWithState<T: Fn(&In, &State) -> O, In, O, State>(
|
pub struct FnNodeWithState<T: Fn(In, &State) -> O, In, O, State>(
|
||||||
T,
|
T,
|
||||||
State,
|
State,
|
||||||
PhantomData<In>,
|
PhantomData<In>,
|
||||||
PhantomData<O>,
|
PhantomData<O>,
|
||||||
);
|
);
|
||||||
impl<'n, T: Fn(&In, &State) -> O, In, O: 'n, State> Node<'n, In>
|
impl<'n, T: Fn(In, &State) -> O, In, O: 'n, State> Node<'n, In>
|
||||||
for FnNodeWithState<T, In, O, State>
|
for FnNodeWithState<T, In, O, State>
|
||||||
{
|
{
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
|
||||||
fn eval(&'n self, input: &'n In) -> Self::Output {
|
fn eval(&'n self, input: In) -> Self::Output {
|
||||||
self.0(input.borrow(), &self.1)
|
self.0(input, &self.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Fn(&In, &State) -> O, In, O, State> FnNodeWithState<T, In, O, State> {
|
impl<T: Fn(In, &State) -> O, In, O, State> FnNodeWithState<T, In, O, State> {
|
||||||
pub fn new(f: T, state: State) -> Self {
|
pub fn new(f: T, state: State) -> Self {
|
||||||
FnNodeWithState(f, state, PhantomData::default(), PhantomData::default())
|
FnNodeWithState(f, state, PhantomData::default(), PhantomData::default())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![cfg_attr(target_arch = "spirv", feature(register_attr), register_attr(spirv))]
|
||||||
|
|
||||||
pub mod generic;
|
pub mod generic;
|
||||||
pub mod ops;
|
pub mod ops;
|
||||||
@@ -9,12 +10,13 @@ pub mod value;
|
|||||||
pub trait Node< 'n, Input> {
|
pub trait Node< 'n, Input> {
|
||||||
type Output : 'n;
|
type Output : 'n;
|
||||||
|
|
||||||
fn eval(&'n self, input: &'n Input) -> Self::Output;
|
fn eval(&'n self, input: Input) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Fix exec trait
|
||||||
pub trait Exec<'n>: Node<'n, ()> {
|
pub trait Exec<'n>: Node<'n, ()> {
|
||||||
fn exec(&'n self) -> Self::Output {
|
fn exec(&'n self) -> Self::Output {
|
||||||
self.eval(&())
|
self.eval(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'n, T: Node<'n, ()>> Exec<'n> for T {}
|
impl<'n, T: Node<'n, ()>> Exec<'n> for T {}
|
||||||
@@ -23,7 +25,9 @@ pub trait Cache {
|
|||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gpu"))]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
#[cfg(not(feature = "gpu"))]
|
||||||
impl<'n, I, O: 'n> Node<'n, I> for alloc::boxed::Box<dyn Node<'n, I, Output = O>> {
|
impl<'n, I, O: 'n> Node<'n, I> for alloc::boxed::Box<dyn Node<'n, I, Output = O>> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
|
|
||||||
|
|||||||
+69
-10
@@ -1,35 +1,94 @@
|
|||||||
use core::{borrow::Borrow, marker::PhantomData, ops::Add};
|
use core::{marker::PhantomData, ops::Add};
|
||||||
|
|
||||||
use crate::Node;
|
use crate::Node;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct AddNode<T>(PhantomData<T>);
|
pub struct AddNode<T>(PhantomData<T>);
|
||||||
impl<'n, T: Add + Copy + 'n> Node<'n, (T, T)> for AddNode<T> {
|
impl<'n, T: Add + Copy + 'n> Node<'n, (T, T)> for AddNode<T> {
|
||||||
type Output = <T as Add>::Output;
|
type Output = <T as Add>::Output;
|
||||||
fn eval(&'n self, input: &'n (T, T)) -> T::Output {
|
fn eval(&'n self, input: (T, T)) -> T::Output {
|
||||||
let (ref a, ref b) = input.borrow();
|
let (a, b) = input;
|
||||||
*a + *b
|
a + b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
/// Destructures a Tuple of two values and returns the first one
|
/// Destructures a Tuple of two values and returns the first one
|
||||||
pub struct FstNode<T, U>(PhantomData<T>, PhantomData<U>);
|
pub struct FstNode<T, U>(PhantomData<T>, PhantomData<U>);
|
||||||
impl<'n, T: Copy + 'n, U> Node<'n, (T, U)> for FstNode<T, U> {
|
impl<'n, T: Copy + 'n, U> Node<'n, (T, U)> for FstNode<T, U> {
|
||||||
type Output = &'n T;
|
type Output = T;
|
||||||
fn eval(&'n self, input: &'n (T, U)) -> Self::Output {
|
fn eval(&'n self, input: (T, U)) -> Self::Output {
|
||||||
let &(ref a, _) = input.borrow();
|
let (a, _) = input;
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
/// Destructures a Tuple of two values and returns the first one
|
/// Destructures a Tuple of two values and returns the first one
|
||||||
pub struct SndNode<T, U>(PhantomData<T>, PhantomData<U>);
|
pub struct SndNode<T, U>(PhantomData<T>, PhantomData<U>);
|
||||||
impl<'n, T, U: Copy + 'n> Node<'n, (T, U)> for SndNode<T, U> {
|
impl<'n, T, U: Copy + 'n> Node<'n, (T, U)> for SndNode<T, U> {
|
||||||
type Output = &'n U;
|
type Output = U;
|
||||||
fn eval(&'n self, input: &'n (T, U)) -> Self::Output {
|
fn eval(&'n self, input: (T, U)) -> Self::Output {
|
||||||
let &(_, ref b) = input.borrow();
|
let (_, b) = input;
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Default)]
|
||||||
|
/// Destructures a Tuple of two values and returns the first one
|
||||||
|
pub struct DupNode<T>(PhantomData<T>);
|
||||||
|
impl<'n, T: Copy + 'n> Node<'n, T> for DupNode<T> {
|
||||||
|
type Output = (T, T);
|
||||||
|
fn eval(&'n self, input: T) -> Self::Output {
|
||||||
|
(input, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "spirv")]
|
||||||
|
pub mod gpu {
|
||||||
|
//#![deny(warnings)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct PushConsts {
|
||||||
|
n: u32,
|
||||||
|
node: u32,
|
||||||
|
}
|
||||||
|
use super::*;
|
||||||
|
use crate::{structural::ComposeNodeOwned, Node};
|
||||||
|
//use crate::Node;
|
||||||
|
use spirv_std::glam::UVec3;
|
||||||
|
const ADD: AddNode<u32> = AddNode(PhantomData);
|
||||||
|
const OPERATION: ComposeNodeOwned<'_, (u32, u32), u32, FstNode<u32, u32>, DupNode<u32>> =
|
||||||
|
ComposeNodeOwned::new(FstNode(PhantomData, PhantomData), DupNode(PhantomData));
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
#[spirv(compute(threads(64)))]
|
||||||
|
pub fn spread(
|
||||||
|
#[spirv(global_invocation_id)] global_id: UVec3,
|
||||||
|
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
|
||||||
|
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [(u32, u32)],
|
||||||
|
#[spirv(push_constant)] push_consts: &PushConsts,
|
||||||
|
) {
|
||||||
|
let gid = global_id.x as usize;
|
||||||
|
// Only process up to n, which is the length of the buffers.
|
||||||
|
if global_id.x < push_consts.n {
|
||||||
|
y[gid] = OPERATION.eval(a[gid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(unused)]
|
||||||
|
#[spirv(compute(threads(64)))]
|
||||||
|
pub fn add(
|
||||||
|
#[spirv(global_invocation_id)] global_id: UVec3,
|
||||||
|
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
|
||||||
|
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [u32],
|
||||||
|
#[spirv(push_constant)] push_consts: &PushConsts,
|
||||||
|
) {
|
||||||
|
let gid = global_id.x as usize;
|
||||||
|
// Only process up to n, which is the length of the buffers.
|
||||||
|
if global_id.x < push_consts.n {
|
||||||
|
y[gid] = ADD.eval(a[gid]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,20 +12,36 @@ pub struct ComposeNode<'n, Input, Inter, FIRST, SECOND> {
|
|||||||
impl<'n, Input: 'n, Inter: 'n, First, Second> Node<'n, Input>
|
impl<'n, Input: 'n, Inter: 'n, First, Second> Node<'n, Input>
|
||||||
for ComposeNode<'n, Input, Inter, First, Second>
|
for ComposeNode<'n, Input, Inter, First, Second>
|
||||||
where
|
where
|
||||||
First: Node<'n, Input, Output = &'n Inter>,
|
First: Node<'n, Input, Output = Inter>,
|
||||||
Second: Node<'n, Inter>, /*+ Node<<First as Node<Input>>::Output<'n>>*/
|
Second: Node<'n, Inter>, /*+ Node<<First as Node<Input>>::Output<'n>>*/
|
||||||
{
|
{
|
||||||
type Output = <Second as Node<'n, Inter>>::Output;
|
type Output = <Second as Node<'n, Inter>>::Output;
|
||||||
|
|
||||||
fn eval(&'n self, input: &'n Input) -> Self::Output {
|
fn eval(&'n self, input: Input) -> Self::Output {
|
||||||
// evaluate the first node with the given input
|
// evaluate the first node with the given input
|
||||||
// and then pipe the result from the first computation
|
// and then pipe the result from the first computation
|
||||||
// into the second node
|
// into the second node
|
||||||
let arg: &Inter = self.first.eval(input);
|
let arg: Inter = self.first.eval(input);
|
||||||
self.second.eval(arg)
|
self.second.eval(arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND>
|
||||||
|
where
|
||||||
|
FIRST: Node<'n, Input>,
|
||||||
|
{
|
||||||
|
pub const fn new(first: &'n FIRST, second: &'n SECOND) -> Self {
|
||||||
|
ComposeNode::<'n, Input, Inter, FIRST, SECOND> {
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
_phantom2: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "nightly"))]
|
||||||
impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND>
|
impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND>
|
||||||
where
|
where
|
||||||
FIRST: Node<'n, Input>,
|
FIRST: Node<'n, Input>,
|
||||||
@@ -39,6 +55,54 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ComposeNodeOwned<'n, Input, Inter, FIRST, SECOND> {
|
||||||
|
first: FIRST,
|
||||||
|
second: SECOND,
|
||||||
|
_phantom: PhantomData<&'n Input>,
|
||||||
|
_phantom2: PhantomData<Inter>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, Input: 'n, Inter: 'n, First, Second> Node<'n, Input>
|
||||||
|
for ComposeNodeOwned<'n, Input, Inter, First, Second>
|
||||||
|
where
|
||||||
|
First: Node<'n, Input, Output = Inter>,
|
||||||
|
Second: Node<'n, Inter>,
|
||||||
|
{
|
||||||
|
type Output = <Second as Node<'n, Inter>>::Output;
|
||||||
|
|
||||||
|
fn eval(&'n self, input: Input) -> Self::Output {
|
||||||
|
// evaluate the first node with the given input
|
||||||
|
// and then pipe the result from the first computation
|
||||||
|
// into the second node
|
||||||
|
let arg: Inter = self.first.eval(input);
|
||||||
|
self.second.eval(arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, Input, Inter, First: 'n, Second> ComposeNodeOwned<'n, Input, Inter, First, Second>
|
||||||
|
where
|
||||||
|
First: Node<'n, Input, Output = Inter>,
|
||||||
|
{
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
pub const fn new(first: First, second: Second) -> Self {
|
||||||
|
ComposeNodeOwned::<'n, Input, Inter, First, Second> {
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
_phantom2: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "nightly"))]
|
||||||
|
pub fn new(first: First, second: Second) -> Self {
|
||||||
|
ComposeNodeOwned::<'n, Input, Inter, First, Second> {
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
_phantom2: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait After<I>: Sized {
|
pub trait After<I>: Sized {
|
||||||
fn after<'n, First: Node<'n, I>>(
|
fn after<'n, First: Node<'n, I>>(
|
||||||
|
|||||||
@@ -5,25 +5,20 @@ use crate::Node;
|
|||||||
pub struct IntNode<const N: u32>;
|
pub struct IntNode<const N: u32>;
|
||||||
impl<'n, const N: u32> Node<'n, ()> for IntNode<N> {
|
impl<'n, const N: u32> Node<'n, ()> for IntNode<N> {
|
||||||
type Output = u32;
|
type Output = u32;
|
||||||
fn eval(&self, _input: &()) -> u32 {
|
fn eval(&self, _input: ()) -> u32 {
|
||||||
N
|
N
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use dyn_any::{DynAny, StaticType, StaticTypeSized};
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ValueNode<'n, T>(T, PhantomData<&'n ()>);
|
pub struct ValueNode<'n, T>(T, PhantomData<&'n ()>);
|
||||||
impl<'n, T: 'n> Node<'n, ()> for ValueNode<'n, T> {
|
impl<'n, T: 'n> Node<'n, ()> for ValueNode<'n, T> {
|
||||||
type Output = &'n T;
|
type Output = &'n T;
|
||||||
fn eval(&self, _input: &()) -> &T {
|
fn eval(&self, _input: ()) -> &T {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T: StaticTypeSized> StaticType for ValueNode<'n, T> {
|
|
||||||
type Static = ValueNode<'static, <T as StaticTypeSized>::Static>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'n, T> ValueNode<'n, T> {
|
impl<'n, T> ValueNode<'n, T> {
|
||||||
pub const fn new(value: T) -> ValueNode<'n, T> {
|
pub const fn new(value: T) -> ValueNode<'n, T> {
|
||||||
ValueNode(value, PhantomData)
|
ValueNode(value, PhantomData)
|
||||||
@@ -34,7 +29,7 @@ impl<'n, T> ValueNode<'n, T> {
|
|||||||
pub struct DefaultNode<T>(PhantomData<T>);
|
pub struct DefaultNode<T>(PhantomData<T>);
|
||||||
impl<'n, T: Default + 'n> Node<'n, ()> for DefaultNode<T> {
|
impl<'n, T: Default + 'n> Node<'n, ()> for DefaultNode<T> {
|
||||||
type Output = T;
|
type Output = T;
|
||||||
fn eval(&self, _input: &()) -> T {
|
fn eval(&self, _input: ()) -> T {
|
||||||
T::default()
|
T::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,8 +42,8 @@ impl<T> DefaultNode<T> {
|
|||||||
pub struct DefaultRefNode<'n, T>(ValueNode<'n, T>);
|
pub struct DefaultRefNode<'n, T>(ValueNode<'n, T>);
|
||||||
impl<'n, T: 'n> Node<'n, ()> for DefaultRefNode<'n, T> {
|
impl<'n, T: 'n> Node<'n, ()> for DefaultRefNode<'n, T> {
|
||||||
type Output = &'n T;
|
type Output = &'n T;
|
||||||
fn eval(&'n self, _input: &'n ()) -> &'n T {
|
fn eval(&'n self, _input: ()) -> &'n T {
|
||||||
self.0.eval(&())
|
self.0.eval(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'n, T: Default> Default for DefaultRefNode<'n, T> {
|
impl<'n, T: Default> Default for DefaultRefNode<'n, T> {
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ pub trait DynamicInput<'n> {
|
|||||||
fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>);
|
fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AnyRef<'n, I: StaticType>: Node<'n, I> {
|
pub trait AnyRef<'n, I: 'n + StaticType>: Node<'n, &'n I> {
|
||||||
fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output;
|
fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T: Node<'n, I>, I: StaticType + 'n> AnyRef<'n, I> for T {
|
impl<'n, N: Node<'n, &'n I>, I: StaticType + 'n> AnyRef<'n, I> for N {
|
||||||
fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
||||||
self.eval(downcast_ref::<I>(input).unwrap_or_else(|| {
|
self.eval(downcast_ref::<I>(input).unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ mod mul {
|
|||||||
}
|
}
|
||||||
impl<'n> Node<'n, ()> for MulNodeAnyProxy<'n> {
|
impl<'n> Node<'n, ()> for MulNodeAnyProxy<'n> {
|
||||||
type Output = MulNodeInput<'n>;
|
type Output = MulNodeInput<'n>;
|
||||||
fn eval(&'n self, _input: &'n ()) -> <Self as graphene_std::Node<'n, ()>>::Output {
|
fn eval(&'n self, _input: ()) -> <Self as graphene_std::Node<'n, ()>>::Output {
|
||||||
let a = self.a.unwrap().eval(&());
|
let a = self.a.unwrap().eval(());
|
||||||
let a: &f32 = self
|
let a: &f32 = self
|
||||||
.a
|
.a
|
||||||
.map(|v| downcast_ref(v.eval(&())).unwrap())
|
.map(|v| downcast_ref(v.eval(())).unwrap())
|
||||||
.unwrap_or(&1.);
|
.unwrap_or(&1.);
|
||||||
/*let b: &f32 = self
|
/*let b: &f32 = self
|
||||||
.b
|
.b
|
||||||
@@ -43,9 +43,9 @@ mod mul {
|
|||||||
}
|
}
|
||||||
impl<'n> Node<'n, ()> for MulNodeTypedProxy<'n> {
|
impl<'n> Node<'n, ()> for MulNodeTypedProxy<'n> {
|
||||||
type Output = MulNodeInput<'n>;
|
type Output = MulNodeInput<'n>;
|
||||||
fn eval(&'n self, _input: &'n ()) -> <Self as graphene_std::Node<'n, ()>>::Output {
|
fn eval(&'n self, _input: ()) -> <Self as graphene_std::Node<'n, ()>>::Output {
|
||||||
let a = self.a.unwrap().eval(&());
|
let a = self.a.unwrap().eval(());
|
||||||
let b = self.b.unwrap().eval(&());
|
let b = self.b.unwrap().eval(());
|
||||||
MulNodeInput { a, b }
|
MulNodeInput { a, b }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ fn main() {
|
|||||||
//let node = unsafe { stack.get(0) };
|
//let node = unsafe { stack.get(0) };
|
||||||
//let boxed = Box::new(StorageNode::new(node));
|
//let boxed = Box::new(StorageNode::new(node));
|
||||||
//unsafe { stack.push(boxed) };
|
//unsafe { stack.push(boxed) };
|
||||||
let result = unsafe { &stack.get()[0] }.eval(&());
|
let result = unsafe { &stack.get()[0] }.eval(());
|
||||||
/*unsafe {
|
/*unsafe {
|
||||||
stack
|
stack
|
||||||
.push(Box::new(AnyRefNode::new(stack.get(0).as_ref()))
|
.push(Box::new(AnyRefNode::new(stack.get(0).as_ref()))
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub struct CacheNode<'n, CachedNode: Node<'n, Input>, Input> {
|
|||||||
}
|
}
|
||||||
impl<'n, CashedNode: Node<'n, Input>, Input> Node<'n, Input> for CacheNode<'n, CashedNode, Input> {
|
impl<'n, CashedNode: Node<'n, Input>, Input> Node<'n, Input> for CacheNode<'n, CashedNode, Input> {
|
||||||
type Output = &'n CashedNode::Output;
|
type Output = &'n CashedNode::Output;
|
||||||
fn eval(&'n self, input: &'n Input) -> Self::Output {
|
fn eval(&'n self, input: Input) -> Self::Output {
|
||||||
self.cache.get_or_init(|| self.node.eval(input))
|
self.cache.get_or_init(|| self.node.eval(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ impl<'n, N: Node<'n, I, Output = &'n O>, I, O: DynAny<'n>> Node<'n, I>
|
|||||||
for AnyRefNode<'n, N, I, &'n O>
|
for AnyRefNode<'n, N, I, &'n O>
|
||||||
{
|
{
|
||||||
type Output = &'n (dyn DynAny<'n>);
|
type Output = &'n (dyn DynAny<'n>);
|
||||||
fn eval(&'n self, input: &'n I) -> Self::Output {
|
fn eval(&'n self, input: I) -> Self::Output {
|
||||||
let value: &O = self.0.eval(input);
|
let value: &O = self.0.eval(input);
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ pub struct StorageNode<'n>(&'n dyn Node<'n, (), Output = &'n dyn DynAny<'n>>);
|
|||||||
|
|
||||||
impl<'n> Node<'n, ()> for StorageNode<'n> {
|
impl<'n> Node<'n, ()> for StorageNode<'n> {
|
||||||
type Output = &'n (dyn DynAny<'n>);
|
type Output = &'n (dyn DynAny<'n>);
|
||||||
fn eval(&'n self, input: &'n ()) -> Self::Output {
|
fn eval(&'n self, input: ()) -> Self::Output {
|
||||||
let value = self.0.eval(input);
|
let value = self.0.eval(input);
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ impl<'n> StorageNode<'n> {
|
|||||||
pub struct AnyValueNode<'n, T>(T, PhantomData<&'n ()>);
|
pub struct AnyValueNode<'n, T>(T, PhantomData<&'n ()>);
|
||||||
impl<'n, T: 'n + DynAny<'n>> Node<'n, ()> for AnyValueNode<'n, T> {
|
impl<'n, T: 'n + DynAny<'n>> Node<'n, ()> for AnyValueNode<'n, T> {
|
||||||
type Output = &'n dyn DynAny<'n>;
|
type Output = &'n dyn DynAny<'n>;
|
||||||
fn eval(&'n self, _input: &()) -> &'n dyn DynAny<'n> {
|
fn eval(&'n self, _input: ()) -> &'n dyn DynAny<'n> {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user