mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +08:00
Don't force nodes to store references to other nodes
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::Node;
|
||||
pub struct FnNode<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O: 'n>(
|
||||
pub struct FnNode<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O>(
|
||||
T,
|
||||
&'n N,
|
||||
PhantomData<O>,
|
||||
N,
|
||||
PhantomData<&'n O>,
|
||||
);
|
||||
impl<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n, T, N, O> {
|
||||
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n, T, N, O> {
|
||||
type Output = O;
|
||||
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
@@ -14,19 +14,20 @@ impl<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, T: Fn(<N as Node>::Output) -> O, N: Node<'n>, O> FnNode<'n, T, N, O> {
|
||||
pub fn new(f: T, input: &'n N) -> Self {
|
||||
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> FnNode<'n, T, N, O> {
|
||||
pub fn new(f: T, input: N) -> Self {
|
||||
FnNode(f, input, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FnNodeWithState<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O, State>(
|
||||
T,
|
||||
&'n N,
|
||||
State,
|
||||
PhantomData<O>,
|
||||
);
|
||||
impl<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O: 'n, State> Node<'n>
|
||||
pub struct FnNodeWithState<
|
||||
'n,
|
||||
T: Fn(<N as Node<'n>>::Output, &State) -> O,
|
||||
N: Node<'n>,
|
||||
O,
|
||||
State: 'n,
|
||||
>(T, N, State, PhantomData<&'n O>);
|
||||
impl<'n, T: Fn(<N as Node<'n>>::Output, &State) -> O, N: Node<'n>, O: 'n, State> Node<'n>
|
||||
for FnNodeWithState<'n, T, N, O, State>
|
||||
{
|
||||
type Output = O;
|
||||
@@ -37,7 +38,7 @@ impl<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O: 'n, State> Node<'n>
|
||||
}
|
||||
|
||||
impl<'n, T: Fn(N::Output, &State) -> O, N: Node<'n>, O, State> FnNodeWithState<'n, T, N, O, State> {
|
||||
pub fn new(f: T, input: &'n N, state: State) -> Self {
|
||||
pub fn new(f: T, input: N, state: State) -> Self {
|
||||
FnNodeWithState(f, input, state, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,50 @@
|
||||
#![no_std]
|
||||
#![cfg_attr(target_arch = "spirv", feature(register_attr), register_attr(spirv))]
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "async")]
|
||||
use alloc::boxed::Box;
|
||||
#[cfg(feature = "async")]
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub mod generic;
|
||||
pub mod ops;
|
||||
//pub mod structural;
|
||||
pub mod value;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub trait Node<'n> {
|
||||
type Output: 'n; // TODO: replace with generic associated type
|
||||
|
||||
fn eval(&'n self) -> Self::Output;
|
||||
}
|
||||
|
||||
impl<'n, N: Node<'n>> Node<'n> for &'n N {
|
||||
type Output = N::Output;
|
||||
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
Node::eval(*self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
#[async_trait]
|
||||
pub trait AsyncNode<'n> {
|
||||
type Output: 'n; // TODO: replace with generic associated type
|
||||
|
||||
async fn eval(&'n self) -> Self::Output;
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
#[async_trait]
|
||||
impl<'n, N: Node<'n> + Sync> AsyncNode<'n> for N {
|
||||
type Output = N::Output;
|
||||
|
||||
async fn eval(&'n self) -> Self::Output {
|
||||
Node::eval(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Cache {
|
||||
fn clear(&mut self);
|
||||
}
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
use core::ops::Add;
|
||||
use core::{marker::PhantomData, ops::Add};
|
||||
|
||||
use crate::Node;
|
||||
|
||||
#[repr(C)]
|
||||
struct AddNode<'n, T: Add, I1: Node<'n, Output = T>, I2: Node<'n, Output = T>>(
|
||||
pub &'n I1,
|
||||
pub &'n I2,
|
||||
struct AddNode<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>(
|
||||
pub I1,
|
||||
pub I2,
|
||||
PhantomData<&'n (L, R)>,
|
||||
);
|
||||
impl<'n, T: Add + 'n, I1: Node<'n, Output = T>, I2: Node<'n, Output = T>> Node<'n>
|
||||
for AddNode<'n, T, I1, I2>
|
||||
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> Node<'n>
|
||||
for AddNode<'n, L, R, I1, I2>
|
||||
{
|
||||
type Output = <T as Add>::Output;
|
||||
fn eval(&self) -> T::Output {
|
||||
type Output = <L as Add<R>>::Output;
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
self.0.eval() + self.1.eval()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CloneNode<'n, N: Node<'n, Output = &'n O>, O: Clone + 'n>(pub &'n N);
|
||||
pub struct CloneNode<'n, N: Node<'n, Output = &'n O>, O: Clone + 'n>(pub N, PhantomData<&'n ()>);
|
||||
impl<'n, N: Node<'n, Output = &'n O>, O: Clone> Node<'n> for CloneNode<'n, N, O> {
|
||||
type Output = O;
|
||||
fn eval(&self) -> Self::Output {
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
self.0.eval().clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FstNode<'n, N: Node<'n>>(pub &'n N);
|
||||
pub struct FstNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
|
||||
impl<'n, T: 'n, U, N: Node<'n, Output = (T, U)>> Node<'n> for FstNode<'n, N> {
|
||||
type Output = T;
|
||||
fn eval(&self) -> Self::Output {
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
let (a, _) = self.0.eval();
|
||||
a
|
||||
}
|
||||
@@ -37,10 +38,10 @@ impl<'n, T: 'n, U, N: Node<'n, Output = (T, U)>> Node<'n> for FstNode<'n, N> {
|
||||
|
||||
#[repr(C)]
|
||||
/// Destructures a Tuple of two values and returns the first one
|
||||
pub struct SndNode<'n, N: Node<'n>>(pub &'n N);
|
||||
pub struct SndNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
|
||||
impl<'n, T, U: 'n, N: Node<'n, Output = (T, U)>> Node<'n> for SndNode<'n, N> {
|
||||
type Output = U;
|
||||
fn eval(&self) -> Self::Output {
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
let (_, b) = self.0.eval();
|
||||
b
|
||||
}
|
||||
@@ -48,34 +49,26 @@ impl<'n, T, U: 'n, N: Node<'n, Output = (T, U)>> Node<'n> for SndNode<'n, N> {
|
||||
|
||||
#[repr(C)]
|
||||
/// Destructures a Tuple of two values and returns the first one
|
||||
pub struct SndRefNode<'n, N: Node<'n>>(pub &'n N);
|
||||
impl<'n, T: 'n, U: 'n, N: Node<'n, Output = &'n (T, U)>> Node<'n> for SndRefNode<'n, N> {
|
||||
type Output = &'n U;
|
||||
fn eval(&self) -> Self::Output {
|
||||
let (_, ref b) = self.0.eval();
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
/// Destructures a Tuple of two values and returns the first one
|
||||
pub struct DupNode<'n, N: Node<'n>>(&'n N);
|
||||
pub struct DupNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
|
||||
impl<'n, N: Node<'n>> Node<'n> for DupNode<'n, N> {
|
||||
type Output = (N::Output, N::Output);
|
||||
fn eval(&self) -> Self::Output {
|
||||
fn eval(&'n self) -> Self::Output {
|
||||
(self.0.eval(), self.0.eval()) //TODO: use Copy/Clone implementation
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo() {
|
||||
let value = crate::value::ValueNode::new(2u32);
|
||||
let dup = DupNode(&value);
|
||||
let value2 = crate::value::ValueNode::new(4u32);
|
||||
let dup = DupNode(value, PhantomData);
|
||||
fn swap<'n>(input: (&'n u32, &'n u32)) -> (&'n u32, &'n u32) {
|
||||
(input.1, input.0)
|
||||
}
|
||||
//let fnn = crate::generic::FnNode::new(swap, &dup); TODO fix types
|
||||
let snd = SndNode(&dup);
|
||||
let add = AddNode(&snd, &value);
|
||||
let fnn = crate::generic::FnNode::new(swap, &dup);
|
||||
let _ = fnn.eval();
|
||||
let snd = SndNode(&fnn, PhantomData);
|
||||
let _ = snd.eval();
|
||||
let add = AddNode(&snd, value2, PhantomData);
|
||||
let _ = add.eval();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ use core::marker::PhantomData;
|
||||
|
||||
use crate::Node;
|
||||
|
||||
pub struct ComposeNode<'n, Input, Inter, FIRST, SECOND> {
|
||||
first: &'n FIRST,
|
||||
second: &'n SECOND,
|
||||
pub struct ComposeNode<'n, Inter, First, Second> {
|
||||
first: &'n First,
|
||||
second: &'n Second,
|
||||
_phantom: PhantomData<&'n Input>,
|
||||
_phantom2: PhantomData<Inter>,
|
||||
}
|
||||
@@ -26,7 +26,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND>
|
||||
where
|
||||
FIRST: Node<'n, Input>,
|
||||
@@ -41,20 +40,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
impl<'n, Input, Inter, FIRST, SECOND> ComposeNode<'n, Input, Inter, FIRST, SECOND>
|
||||
where
|
||||
FIRST: Node<'n, Input>,
|
||||
{
|
||||
pub fn new(first: &'n FIRST, second: &'n SECOND) -> Self {
|
||||
ComposeNode::<'n, Input, Inter, FIRST, SECOND> {
|
||||
first,
|
||||
second,
|
||||
_phantom: PhantomData,
|
||||
_phantom2: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct ComposeNodeOwned<'n, Input, Inter, FIRST, SECOND> {
|
||||
first: FIRST,
|
||||
|
||||
Reference in New Issue
Block a user