From ef08c27e9c4820c65b3a6ed41d9709e97ab4308a Mon Sep 17 00:00:00 2001 From: Dennis Date: Wed, 10 Aug 2022 13:05:57 +0200 Subject: [PATCH] Reintroduce input for the node trait # Conflicts: # node-graph/gcore/src/raster.rs --- node-graph/gcore/src/lib.rs | 28 +++++++++++------------- node-graph/gcore/src/raster.rs | 32 +++++++++++++++++++++++----- node-graph/gcore/src/raster/color.rs | 2 +- node-graph/gcore/src/value.rs | 27 ++++++++++++++--------- node-graph/gstd/src/lib.rs | 6 ++++-- node-graph/gstd/src/raster.rs | 18 ++++++++++++++++ 6 files changed, 79 insertions(+), 34 deletions(-) create mode 100644 node-graph/gstd/src/raster.rs diff --git a/node-graph/gcore/src/lib.rs b/node-graph/gcore/src/lib.rs index a63bc47c..cbd80793 100644 --- a/node-graph/gcore/src/lib.rs +++ b/node-graph/gcore/src/lib.rs @@ -8,23 +8,23 @@ use alloc::boxed::Box; #[cfg(feature = "async")] use async_trait::async_trait; -pub mod generic; -pub mod ops; +//pub mod generic; +//pub mod ops; //pub mod structural; pub mod raster; pub mod value; -pub trait Node<'n> { +pub trait Node<'n, T> { type Output; // TODO: replace with generic associated type - fn eval(&'n self) -> Self::Output; + fn eval(&'n self, input: T) -> Self::Output; } -impl<'n, N: Node<'n>> Node<'n> for &'n N { +impl<'n, N: Node<'n, T>, T> Node<'n, T> for &'n N { type Output = N::Output; - fn eval(&'n self) -> Self::Output { - Node::eval(*self) + fn eval(&'n self, input: T) -> Self::Output { + Node::eval(*self, input) } } @@ -34,29 +34,25 @@ pub trait NodeInput { fn new(input: Self::Nodes) -> Self; } -trait FQN { - fn fqn(&self) -> &'static str; -} - trait Input { unsafe fn input(&self, input: I); } #[cfg(feature = "async")] #[async_trait] -pub trait AsyncNode<'n> { +pub trait AsyncNode<'n, T> { type Output; // TODO: replace with generic associated type - async fn eval_async(&'n self) -> Self::Output; + async fn eval_async(&'n self, input: T) -> Self::Output; } #[cfg(feature = "async")] #[async_trait] -impl<'n, N: Node<'n> + Sync> AsyncNode<'n> for N { +impl<'n, N: Node<'n, T> + Sync, T: Send + 'n> AsyncNode<'n, T> for N { type Output = N::Output; - async fn eval_async(&'n self) -> Self::Output { - Node::eval(self) + async fn eval_async(&'n self, input: T) -> Self::Output { + Node::eval(self, input) } } diff --git a/node-graph/gcore/src/raster.rs b/node-graph/gcore/src/raster.rs index 26547105..63112882 100644 --- a/node-graph/gcore/src/raster.rs +++ b/node-graph/gcore/src/raster.rs @@ -1,18 +1,40 @@ use core::marker::PhantomData; -use crate::Node; +use crate::{value::ValueNode, Node}; use self::color::Color; pub mod color; -pub struct GrayscaleNode<'n, N: Node<'n, Output = Color>>(pub N, PhantomData<&'n ()>); +pub struct GrayscaleNode; -impl<'n, N: Node<'n, Output = Color>> Node<'n> for GrayscaleNode<'n, N> { +impl<'n> Node<'n, Color> for GrayscaleNode { type Output = Color; - fn eval(&'n self) -> Color { - let color = self.0.eval(); + fn eval(&'n self, color: Color) -> Color { let avg = (color.r() + color.g() + color.b()) / 3.0; Color::from_rgbaf32(avg, avg, avg, color.a()).expect("Grayscale node created an invalid color") } } + +pub struct ForEachNode<'n, I: Iterator, MN: Node<'n, S>, S>(pub MN, PhantomData<&'n (I, S)>); + +impl<'n, I: Iterator, MN: Node<'n, S, Output = ()>, S> Node<'n, I> for ForEachNode<'n, I, MN, S> { + type Output = (); + fn eval(&'n self, input: I) -> Self::Output { + input.for_each(|x| self.0.eval(x)) + } +} + +pub struct MutWrapper<'n, N: Node<'n, T, Output = T>, T: Clone>(pub N, PhantomData<&'n T>); + +impl<'n, T: Clone, N: Node<'n, T, Output = T>> Node<'n, &'n mut T> for MutWrapper<'n, N, T> { + type Output = (); + fn eval(&'n self, value: &'n mut T) { + *value = self.0.eval(value.clone()); + } +} + +fn foo() { + let map = ForEachNode(MutWrapper(GrayscaleNode, PhantomData), PhantomData); + map.eval(&mut [Color::from_rgbaf32(1.0, 0.0, 0.0, 1.0).unwrap()].iter_mut()); +} diff --git a/node-graph/gcore/src/raster/color.rs b/node-graph/gcore/src/raster/color.rs index 0b4fe2fd..1221a30e 100644 --- a/node-graph/gcore/src/raster/color.rs +++ b/node-graph/gcore/src/raster/color.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; /// The other components (RGB) are stored as `f32` that range from `0.0` up to `f32::MAX`, /// the values encode the brightness of each channel proportional to the light intensity in cd/m² (nits) in HDR, and `0.0` (black) to `1.0` (white) in SDR color. #[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Default)] //, Serialize, Deserialize)] pub struct Color { red: f32, green: f32, diff --git a/node-graph/gcore/src/value.rs b/node-graph/gcore/src/value.rs index 376a9ea3..f0a60939 100644 --- a/node-graph/gcore/src/value.rs +++ b/node-graph/gcore/src/value.rs @@ -5,32 +5,39 @@ use core::sync::atomic::AtomicBool; use crate::Node; pub struct IntNode; -impl<'n, const N: u32> Node<'n> for IntNode { +impl<'n, const N: u32> Node<'n, ()> for IntNode { type Output = u32; - fn eval(&self) -> u32 { + fn eval(&self, _: ()) -> u32 { N } } #[derive(Default)] pub struct ValueNode(pub T); -impl<'n, T: 'n> Node<'n> for ValueNode { +impl<'n, T: 'n> Node<'n, ()> for ValueNode { type Output = &'n T; - fn eval(&'n self) -> Self::Output { + fn eval(&'n self, _: ()) -> Self::Output { &self.0 } } + impl ValueNode { pub const fn new(value: T) -> ValueNode { ValueNode(value) } } +impl From for ValueNode { + fn from(value: T) -> Self { + ValueNode::new(value) + } +} + #[derive(Default)] pub struct DefaultNode(PhantomData); -impl<'n, T: Default + 'n> Node<'n> for DefaultNode { +impl<'n, T: Default + 'n> Node<'n, ()> for DefaultNode { type Output = T; - fn eval(&self) -> T { + fn eval(&self, _: ()) -> T { T::default() } } @@ -38,15 +45,15 @@ impl<'n, T: Default + 'n> Node<'n> for DefaultNode { #[repr(C)] /// Return the unit value pub struct UnitNode; -impl<'n> Node<'n> for UnitNode { +impl<'n> Node<'n, ()> for UnitNode { type Output = (); - fn eval(&'n self) -> Self::Output {} + fn eval(&'n self, _: ()) -> Self::Output {} } pub struct InputNode(MaybeUninit, AtomicBool); -impl<'n, T: 'n> Node<'n> for InputNode { +impl<'n, T: 'n> Node<'n, ()> for InputNode { type Output = &'n T; - fn eval(&'n self) -> Self::Output { + fn eval(&'n self, _: ()) -> Self::Output { if self.1.load(core::sync::atomic::Ordering::SeqCst) { unsafe { self.0.assume_init_ref() } } else { diff --git a/node-graph/gstd/src/lib.rs b/node-graph/gstd/src/lib.rs index ae80bfa1..eaf06871 100644 --- a/node-graph/gstd/src/lib.rs +++ b/node-graph/gstd/src/lib.rs @@ -1,8 +1,10 @@ pub mod value; pub use graphene_core::{generic, ops /*, structural*/}; -#[cfg(feature = "memoization")] -pub mod memo; +//#[cfg(feature = "memoization")] +//pub mod memo; + +//pub mod raster; pub use graphene_core::*; diff --git a/node-graph/gstd/src/raster.rs b/node-graph/gstd/src/raster.rs new file mode 100644 index 00000000..782bce56 --- /dev/null +++ b/node-graph/gstd/src/raster.rs @@ -0,0 +1,18 @@ +use core::marker::PhantomData; +use graphene_core::{value::RefNode, value::ValueNode, Node}; + +pub struct MapNode<'n, IN: Node<'n, Output = I>, I: Iterator, MAP: Fn(&dyn RefNode) -> MN, MN: Node<'n, Output = O> + 'n, S, O: 'n>(pub IN, pub MAP, PhantomData<&'n (I, S)>); + +impl<'n, IN: Node<'n, Output = I>, I: Iterator, MAP: Fn(&dyn RefNode) -> MN, MN: Node<'n, Output = O>, S, O: 'static + Clone> Node<'n> for MapNode<'n, IN, I, MAP, MN, S, O> { + type Output = Vec; + fn eval(&'n self) -> Self::Output { + self.0 + .eval() + .map(|x| { + let map_node = self.1(x as &dyn RefNode); + let result = map_node.eval(); + result.clone() + }) + .collect() + } +}