Reintroduce input for the node trait

# Conflicts:
#	node-graph/gcore/src/raster.rs
This commit is contained in:
Dennis 2022-08-10 13:05:57 +02:00 committed by Keavon Chambers
parent b46bcc16ba
commit ef08c27e9c
6 changed files with 79 additions and 34 deletions

View file

@ -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<I> {
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)
}
}

View file

@ -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<Item = S>, MN: Node<'n, S>, S>(pub MN, PhantomData<&'n (I, S)>);
impl<'n, I: Iterator<Item = S>, 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());
}

View file

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

View file

@ -5,32 +5,39 @@ use core::sync::atomic::AtomicBool;
use crate::Node;
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;
fn eval(&self) -> u32 {
fn eval(&self, _: ()) -> u32 {
N
}
}
#[derive(Default)]
pub struct ValueNode<T>(pub T);
impl<'n, T: 'n> Node<'n> for ValueNode<T> {
impl<'n, T: 'n> Node<'n, ()> for ValueNode<T> {
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
fn eval(&'n self, _: ()) -> Self::Output {
&self.0
}
}
impl<T> ValueNode<T> {
pub const fn new(value: T) -> ValueNode<T> {
ValueNode(value)
}
}
impl<T> From<T> for ValueNode<T> {
fn from(value: T) -> Self {
ValueNode::new(value)
}
}
#[derive(Default)]
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;
fn eval(&self) -> T {
fn eval(&self, _: ()) -> T {
T::default()
}
}
@ -38,15 +45,15 @@ impl<'n, T: Default + 'n> Node<'n> for DefaultNode<T> {
#[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<T>(MaybeUninit<T>, AtomicBool);
impl<'n, T: 'n> Node<'n> for InputNode<T> {
impl<'n, T: 'n> Node<'n, ()> for InputNode<T> {
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 {

View file

@ -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::*;

View file

@ -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<Item = &'n S>, MAP: Fn(&dyn RefNode<Output = S>) -> 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<Item = &'n S>, MAP: Fn(&dyn RefNode<Output = S>) -> MN, MN: Node<'n, Output = O>, S, O: 'static + Clone> Node<'n> for MapNode<'n, IN, I, MAP, MN, S, O> {
type Output = Vec<O>;
fn eval(&'n self) -> Self::Output {
self.0
.eval()
.map(|x| {
let map_node = self.1(x as &dyn RefNode<Output = S>);
let result = map_node.eval();
result.clone()
})
.collect()
}
}