Files
Graphite/node-graph/gcore/src/structural.rs
Dennis Kobert 620540d7cd Incremental compilation and stable node IDs (#977)
* Generate stable node ids

* checkpoint

* Implement borrow tree

* Add eval function on borrow tree

* Refactor Node trait to fix lifetime issues

* Compiler infinite loop

* Impl compose pair

* Transition to double lifetime on trait

* Change node trait to use a generic arg for the input

* Start adapting node_macro

* Migrate more nodes to new macro

* Fix raster tests

* Port vector nodes

* Make Node trait object safe

* Fix FlatMapResultNode

* Translate most of gstd

* Fix DowncastBothNode

* Refactor node trait once again to allow for HRTB for type erased nodes

* Start working on type erased nodes

* Try getting DowncastBothNode to work

* Introduce Upcasting node + work on BorrowTree

* Make enough 'static to get the code to compile

* Transition DynamicExecutor to use borrow tree

* Make Compose Node use HRTB's

* Fix MapResultNode

* Disable blur test

* Add workaround for Composing type erased nodes

* Convert more nodes in the node_registry

* Convert more of the node_registry

* Add update tree fn and hook up to frontend

* Fix blur node

* Implement CacheNode

* Make frontend use graph compiler

* Fix document_node_types type declaration for most nodes

* Remove unused imports

* Move comment down

* Reuse nodes via borrow tree

* Deprecate trait based value in favor of TaggedValue

* Remove unsafe code in buffer creation

* Fix blur node

* Fix stable node id generation

* Fix types for Image adjustment document nodes

* Fix Imaginate Node

* Remove unused imports

* Remove log

* Fix off by one error

* Remove macro generated imaginate node entry

* Create parameterized add node

* Fix test case

* Remove link from layer_panel.rs

* Fix formatting
2023-02-07 20:06:24 +01:00

93 lines
2.5 KiB
Rust

use core::marker::PhantomData;
use crate::Node;
pub struct ComposeNode<First: for<'i> Node<'i, I>, Second: for<'i> Node<'i, <First as Node<'i, I>>::Output>, I> {
first: First,
second: Second,
phantom: PhantomData<I>,
}
impl<'i, Input: 'i, First, Second> Node<'i, Input> for ComposeNode<First, Second, Input>
where
First: for<'a> Node<'a, Input> + 'i,
Second: for<'a> Node<'a, <First as Node<'a, Input>>::Output> + 'i,
{
type Output = <Second as Node<'i, <First as Node<'i, Input>>::Output>>::Output;
fn eval<'s: 'i>(&'s self, input: Input) -> Self::Output {
let arg = self.first.eval(input);
self.second.eval(arg)
}
}
impl<First, Second, Input> ComposeNode<First, Second, Input>
where
First: for<'a> Node<'a, Input>,
Second: for<'a> Node<'a, <First as Node<'a, Input>>::Output>,
{
pub const fn new(first: First, second: Second) -> Self {
ComposeNode::<First, Second, Input> { first, second, phantom: PhantomData }
}
}
// impl Clone for ComposeNode<First, Second, Input>
impl<First, Second, Input> Clone for ComposeNode<First, Second, Input>
where
First: for<'a> Node<'a, Input> + Clone,
Second: for<'a> Node<'a, <First as Node<'a, Input>>::Output> + Clone,
{
fn clone(&self) -> Self {
ComposeNode::<First, Second, Input> {
first: self.first.clone(),
second: self.second.clone(),
phantom: PhantomData,
}
}
}
pub trait Then<'i, Input: 'i>: Sized {
fn then<Second>(self, second: Second) -> ComposeNode<Self, Second, Input>
where
Self: for<'a> Node<'a, Input>,
Second: for<'a> Node<'a, <Self as Node<'a, Input>>::Output>,
{
ComposeNode::new(self, second)
}
}
impl<'i, First: for<'a> Node<'a, Input>, Input: 'i> Then<'i, Input> for First {}
pub struct ConsNode<I: From<()>, Root>(pub Root, PhantomData<I>);
impl<'i, Root, Input: 'i, I: 'i + From<()>> Node<'i, Input> for ConsNode<I, Root>
where
Root: Node<'i, I>,
{
type Output = (Input, Root::Output);
fn eval<'s: 'i>(&'s self, input: Input) -> Self::Output {
let arg = self.0.eval(I::from(()));
(input, arg)
}
}
impl<'i, Root: Node<'i, I>, I: 'i + From<()>> ConsNode<I, Root> {
pub fn new(root: Root) -> Self {
ConsNode(root, PhantomData)
}
}
#[cfg(test)]
mod test {
use crate::{ops::IdNode, value::ValueNode};
use super::*;
#[test]
fn compose() {
let value = ValueNode::new(4u32);
let compose = value.then(IdNode::new());
assert_eq!(compose.eval(()), &4u32);
let type_erased = &compose as &dyn for<'i> Node<'i, (), Output = &'i u32>;
assert_eq!(type_erased.eval(()), &4u32);
}
}