mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 15:28:04 +08:00
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
This commit is contained in:
committed by
Keavon Chambers
parent
12d6818d73
commit
004e87ca3e
@@ -1,29 +1,23 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::MaybeUninit;
|
||||
use core::sync::atomic::AtomicBool;
|
||||
|
||||
use crate::Node;
|
||||
|
||||
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct IntNode<const N: u32>;
|
||||
impl<const N: u32> Node<()> for IntNode<N> {
|
||||
|
||||
impl<'i, const N: u32> Node<'i, ()> for IntNode<N> {
|
||||
type Output = u32;
|
||||
fn eval(self, _: ()) -> u32 {
|
||||
fn eval<'s: 'i>(&'s self, _input: ()) -> Self::Output {
|
||||
N
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ValueNode<T>(pub T);
|
||||
impl<'n, T: 'n> Node<()> for ValueNode<T> {
|
||||
type Output = T;
|
||||
fn eval(self, _: ()) -> Self::Output {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
impl<'n, T: 'n> Node<()> for &'n ValueNode<T> {
|
||||
type Output = &'n T;
|
||||
fn eval(self, _: ()) -> Self::Output {
|
||||
|
||||
impl<'i, T: 'i> Node<'i, ()> for ValueNode<T> {
|
||||
type Output = &'i T;
|
||||
fn eval<'s: 'i>(&'s self, _input: ()) -> Self::Output {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
@@ -46,58 +40,85 @@ impl<T: Clone> Clone for ValueNode<T> {
|
||||
}
|
||||
impl<T: Clone + Copy> Copy for ValueNode<T> {}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClonedNode<T: Clone>(pub T);
|
||||
|
||||
impl<'i, T: Clone + 'i> Node<'i, ()> for ClonedNode<T> {
|
||||
type Output = T;
|
||||
fn eval<'s: 'i>(&'s self, _input: ()) -> Self::Output {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> ClonedNode<T> {
|
||||
pub const fn new(value: T) -> ClonedNode<T> {
|
||||
ClonedNode(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> From<T> for ClonedNode<T> {
|
||||
fn from(value: T) -> Self {
|
||||
ClonedNode::new(value)
|
||||
}
|
||||
}
|
||||
impl<T: Clone + Copy> Copy for ClonedNode<T> {}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DefaultNode<T>(PhantomData<T>);
|
||||
impl<T: Default> Node<()> for DefaultNode<T> {
|
||||
|
||||
impl<'i, T: Default + 'i> Node<'i, ()> for DefaultNode<T> {
|
||||
type Output = T;
|
||||
fn eval(self, _: ()) -> T {
|
||||
fn eval<'s: 'i>(&self, _input: ()) -> Self::Output {
|
||||
T::default()
|
||||
}
|
||||
}
|
||||
impl<'n, T: Default + 'n> Node<()> for &'n DefaultNode<T> {
|
||||
type Output = T;
|
||||
fn eval(self, _: ()) -> T {
|
||||
T::default()
|
||||
|
||||
impl<T> DefaultNode<T> {
|
||||
pub fn new() -> Self {
|
||||
Self(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
/// Return the unit value
|
||||
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct UnitNode;
|
||||
impl Node<()> for UnitNode {
|
||||
pub struct ForgetNode;
|
||||
|
||||
impl<'i, T: 'i> Node<'i, T> for ForgetNode {
|
||||
type Output = ();
|
||||
fn eval(self, _: ()) -> Self::Output {}
|
||||
}
|
||||
impl<'n> Node<()> for &'n UnitNode {
|
||||
type Output = ();
|
||||
fn eval(self, _: ()) -> Self::Output {}
|
||||
fn eval<'s: 'i>(&self, _input: T) -> Self::Output {}
|
||||
}
|
||||
|
||||
pub struct InputNode<T>(MaybeUninit<T>, AtomicBool);
|
||||
impl<'n, T: 'n> Node<()> for InputNode<T> {
|
||||
type Output = T;
|
||||
fn eval(self, _: ()) -> Self::Output {
|
||||
if self.1.load(core::sync::atomic::Ordering::SeqCst) {
|
||||
unsafe { self.0.assume_init() }
|
||||
} else {
|
||||
panic!("tried to access an input before setting it")
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'n, T: 'n> Node<()> for &'n InputNode<T> {
|
||||
type Output = &'n T;
|
||||
fn eval(self, _: ()) -> Self::Output {
|
||||
if self.1.load(core::sync::atomic::Ordering::SeqCst) {
|
||||
unsafe { self.0.assume_init_ref() }
|
||||
} else {
|
||||
panic!("tried to access an input before setting it")
|
||||
}
|
||||
impl ForgetNode {
|
||||
pub const fn new() -> Self {
|
||||
ForgetNode
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> InputNode<T> {
|
||||
pub const fn new() -> InputNode<T> {
|
||||
InputNode(MaybeUninit::uninit(), AtomicBool::new(false))
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_int_node() {
|
||||
let node = IntNode::<5>;
|
||||
assert_eq!(node.eval(()), 5);
|
||||
}
|
||||
#[test]
|
||||
fn test_value_node() {
|
||||
let node = ValueNode::new(5);
|
||||
assert_eq!(node.eval(()), &5);
|
||||
let type_erased = &node as &dyn for<'a> Node<'a, (), Output = &'a i32>;
|
||||
assert_eq!(type_erased.eval(()), &5);
|
||||
}
|
||||
#[test]
|
||||
fn test_default_node() {
|
||||
let node = DefaultNode::<u32>::new();
|
||||
assert_eq!(node.eval(()), 0);
|
||||
}
|
||||
#[test]
|
||||
fn test_unit_node() {
|
||||
let node = ForgetNode::new();
|
||||
assert_eq!(node.eval(()), ());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user