mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-03 13:02:20 +00:00
Impl DynNode
This commit is contained in:
parent
f73836b838
commit
71f12db1e6
16 changed files with 433 additions and 84 deletions
|
@ -10,7 +10,7 @@ license = "MIT OR Apache-2.0"
|
|||
|
||||
[features]
|
||||
std = ["dyn-any"]
|
||||
default = ["gpu", "async"]
|
||||
default = ["async"]
|
||||
gpu = ["spirv-std"]
|
||||
async = ["async-trait"]
|
||||
nightly = []
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#[cfg(feature = "async")]
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
use alloc::boxed::Box;
|
||||
#[cfg(feature = "async")]
|
||||
|
@ -18,12 +19,35 @@ pub trait Node<T> {
|
|||
type Output;
|
||||
|
||||
fn eval(self, input: T) -> Self::Output;
|
||||
fn input(&self) -> &str {
|
||||
core::any::type_name::<T>()
|
||||
}
|
||||
fn output(&self) -> &str {
|
||||
core::any::type_name::<Self::Output>()
|
||||
}
|
||||
}
|
||||
|
||||
trait Input<I> {
|
||||
unsafe fn input(&self, input: I);
|
||||
}
|
||||
|
||||
pub trait RefNode<T> {
|
||||
type Output;
|
||||
|
||||
fn eval_ref(&self, input: T) -> Self::Output;
|
||||
}
|
||||
|
||||
impl<'n, N: 'n, I> RefNode<I> for &'n N
|
||||
where
|
||||
&'n N: Node<I>,
|
||||
Self: 'n,
|
||||
{
|
||||
type Output = <&'n N as Node<I>>::Output;
|
||||
fn eval_ref(&self, input: I) -> Self::Output {
|
||||
self.eval(input)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
#[async_trait]
|
||||
pub trait AsyncNode<T> {
|
||||
|
@ -46,13 +70,23 @@ pub trait Cache {
|
|||
fn clear(&mut self);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gpu"))]
|
||||
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>> {
|
||||
type Output = O;
|
||||
|
||||
fn eval(&'n self, input: &'n I) -> Self::Output {
|
||||
#[cfg(feature = "async")]
|
||||
impl<N, I> Node<I> for Box<N>
|
||||
where
|
||||
N: Node<I>,
|
||||
{
|
||||
type Output = <N as Node<I>>::Output;
|
||||
fn eval(self, input: I) -> Self::Output {
|
||||
(*self).eval(input)
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "async")]
|
||||
impl<'n, N, I> Node<I> for &'n Box<N>
|
||||
where
|
||||
&'n N: Node<I>,
|
||||
{
|
||||
type Output = <&'n N as Node<I>>::Output;
|
||||
fn eval(self, input: I) -> Self::Output {
|
||||
self.as_ref().eval(input)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,24 @@ impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<(L, R)> for AddNode {
|
|||
input.0 + input.1
|
||||
}
|
||||
}
|
||||
impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<(L, R)> for &'n AddNode {
|
||||
type Output = <L as Add<R>>::Output;
|
||||
fn eval(self, input: (L, R)) -> Self::Output {
|
||||
input.0 + input.1
|
||||
}
|
||||
}
|
||||
impl<'n, L: Add<R, Output = O> + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for AddNode {
|
||||
type Output = <L as Add<R>>::Output;
|
||||
fn eval(self, input: &'n (L, R)) -> Self::Output {
|
||||
input.0 + input.1
|
||||
}
|
||||
}
|
||||
impl<'n, L: Add<R, Output = O> + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for &'n AddNode {
|
||||
type Output = <L as Add<R>>::Output;
|
||||
fn eval(self, input: &'n (L, R)) -> Self::Output {
|
||||
input.0 + input.1
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct CloneNode;
|
||||
|
@ -82,7 +100,7 @@ pub struct DupNode;
|
|||
impl<'n, T: Clone + 'n> Node<T> for DupNode {
|
||||
type Output = (T, T);
|
||||
fn eval(self, input: T) -> Self::Output {
|
||||
(input.clone(), input) //TODO: use Copy/Clone implementation
|
||||
(input.clone(), input)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,6 +113,12 @@ impl<'n, T: 'n> Node<T> for IdNode {
|
|||
input
|
||||
}
|
||||
}
|
||||
impl<'n, T: 'n> Node<T> for &'n IdNode {
|
||||
type Output = T;
|
||||
fn eval(self, input: T) -> Self::Output {
|
||||
input
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapResultNode<MN, I, E>(pub MN, pub PhantomData<(I, E)>);
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct MutWrapper<N>(pub N);
|
||||
/*pub struct MutWrapper<N>(pub N);
|
||||
|
||||
impl<'n, T: Clone, N> Node<&'n mut T> for &'n MutWrapper<N>
|
||||
where
|
||||
|
@ -44,7 +44,7 @@ where
|
|||
fn eval(self, value: &'n mut T) {
|
||||
*value = (&self.0).eval(value.clone());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
@ -54,8 +54,8 @@ mod test {
|
|||
fn map_node() {
|
||||
let array = &mut [Color::from_rgbaf32(1.0, 0.0, 0.0, 1.0).unwrap()];
|
||||
(&GrayscaleNode).eval(Color::from_rgbf32_unchecked(1., 0., 0.));
|
||||
let map = ForEachNode(MutWrapper(GrayscaleNode));
|
||||
/*let map = ForEachNode(MutWrapper(GrayscaleNode));
|
||||
(&map).eval(array.iter_mut());
|
||||
assert_eq!(array[0], Color::from_rgbaf32(0.33333334, 0.33333334, 0.33333334, 1.0).unwrap());
|
||||
assert_eq!(array[0], Color::from_rgbaf32(0.33333334, 0.33333334, 0.33333334, 1.0).unwrap());*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use core::marker::PhantomData;
|
||||
|
||||
use crate::Node;
|
||||
use crate::{Node, RefNode};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ComposeNode<First, Second, Input> {
|
||||
first: First,
|
||||
second: Second,
|
||||
|
@ -25,25 +26,40 @@ where
|
|||
}
|
||||
impl<'n, Input, Inter, First, Second> Node<Input> for &'n ComposeNode<First, Second, Input>
|
||||
where
|
||||
First: Node<Input, Output = Inter> + Copy,
|
||||
Second: Node<Inter> + Copy,
|
||||
First: RefNode<Input, Output = Inter> + Copy,
|
||||
Second: RefNode<Inter> + Copy,
|
||||
{
|
||||
type Output = Second::Output;
|
||||
type Output = <Second as RefNode<Inter>>::Output;
|
||||
|
||||
fn eval(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)
|
||||
let arg: Inter = (self.first).eval_ref(input);
|
||||
(self.second).eval_ref(arg)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, Input, First: 'n, Second: 'n> ComposeNode<First, Second, Input>
|
||||
impl<Input, Inter, First, Second> RefNode<Input> for ComposeNode<First, Second, Input>
|
||||
where
|
||||
First: Node<Input>,
|
||||
Second: Node<First::Output>,
|
||||
First: RefNode<Input, Output = Inter> + Copy,
|
||||
Second: RefNode<Inter> + Copy,
|
||||
{
|
||||
type Output = <Second as RefNode<Inter>>::Output;
|
||||
|
||||
fn eval_ref(&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_ref(input);
|
||||
(self.second).eval_ref(arg)
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "std")]
|
||||
impl<Input: 'static, First: 'static, Second: 'static> dyn_any::StaticType for ComposeNode<First, Second, Input> {
|
||||
type Static = ComposeNode<First, Second, Input>;
|
||||
}
|
||||
|
||||
impl<'n, Input, First: 'n, Second: 'n> ComposeNode<First, Second, Input> {
|
||||
pub const fn new(first: First, second: Second) -> Self {
|
||||
ComposeNode::<First, Second, Input> { first, second, _phantom: PhantomData }
|
||||
}
|
||||
|
@ -79,6 +95,24 @@ pub trait AfterRef<Inter>: Sized {
|
|||
}
|
||||
impl<'n, Second: 'n, I> AfterRef<I> for Second where &'n Second: Node<I> {}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub trait AfterBox<Inter> {
|
||||
fn after<'n, First: 'n, Input>(self, first: First) -> ComposeNode<First, Self, Input>
|
||||
where
|
||||
First: Node<Input, Output = Inter> + Copy,
|
||||
alloc::boxed::Box<Self>: Node<Inter>,
|
||||
Self: Sized,
|
||||
{
|
||||
ComposeNode::<First, Self, Input> {
|
||||
first,
|
||||
second: self,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "async")]
|
||||
impl<'n, Second: 'n, I> AfterBox<I> for alloc::boxed::Box<Second> where &'n alloc::boxed::Box<Second>: Node<I> {}
|
||||
|
||||
pub struct ConsNode<Root>(pub Root);
|
||||
|
||||
impl<Root, Input> Node<Input> for ConsNode<Root>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue