Node graph dynamic execution (#824)

Restructure document node implementation

* Implement topological sort

* Enforce the usage of type annotations

* Add complete test case
This commit is contained in:
TrueDoctor
2022-10-26 00:45:42 +02:00
committed by Keavon Chambers
parent d142a9092c
commit 4ec600957c
12 changed files with 662 additions and 384 deletions

View File

@@ -30,17 +30,21 @@ impl<'n, L: Add<R, Output = O> + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for
}
}
// Unfortunatly we can't impl the AddNode as we get
// `upstream crates may add a new impl of trait `core::ops::Add` for type `alloc::boxed::Box<(dyn dyn_any::DynAny<'_> + 'static)>` in future versions`
pub struct DynamicAddNode;
#[cfg(feature = "std")]
pub mod dynamic {
use super::*;
// Alias for a dynamic type
pub type Dynamic<'a> = alloc::boxed::Box<dyn dyn_any::DynAny<'a> + 'a>;
// Unfortunatly we can't impl the AddNode as we get
// `upstream crates may add a new impl of trait `core::ops::Add` for type `alloc::boxed::Box<(dyn dyn_any::DynAny<'_> + 'static)>` in future versions`
pub struct DynamicAddNode;
/// Resolves the dynamic types for a dynamic node.
///
/// Macro uses format `BaseNode => (arg1: u32) (arg1: i32)`
macro_rules! resolve_dynamic_types {
// Alias for a dynamic type
pub type Dynamic<'a> = alloc::boxed::Box<dyn dyn_any::DynAny<'a> + 'a>;
/// Resolves the dynamic types for a dynamic node.
///
/// Macro uses format `BaseNode => (arg1: u32) (arg1: i32)`
macro_rules! resolve_dynamic_types {
($node:ident => $(($($arg:ident : $t:ty),*))*) => {
$(
// Check for each possible set of arguments if their types match the arguments given
@@ -55,24 +59,25 @@ macro_rules! resolve_dynamic_types {
};
}
impl<'n> Node<(Dynamic<'n>, Dynamic<'n>)> for DynamicAddNode {
type Output = Dynamic<'n>;
fn eval(self, (left, right): (Dynamic, Dynamic)) -> Self::Output {
resolve_dynamic_types! { AddNode =>
(left: usize, right: usize)
(left: u8, right: u8)
(left: u16, right: u16)
(left: u32, right: u32)
(left: u64, right: u64)
(left: u128, right: u128)
(left: isize, right: isize)
(left: i8, right: i8)
(left: i16, right: i16)
(left: i32, right: i32)
(left: i64, right: i64)
(left: i128, right: i128)
(left: f32, right: f32)
(left: f64, right: f64) }
impl<'n> Node<(Dynamic<'n>, Dynamic<'n>)> for DynamicAddNode {
type Output = Dynamic<'n>;
fn eval(self, (left, right): (Dynamic, Dynamic)) -> Self::Output {
resolve_dynamic_types! { AddNode =>
(left: usize, right: usize)
(left: u8, right: u8)
(left: u16, right: u16)
(left: u32, right: u32)
(left: u64, right: u64)
(left: u128, right: u128)
(left: isize, right: isize)
(left: i8, right: i8)
(left: i16, right: i16)
(left: i32, right: i32)
(left: i64, right: i64)
(left: i128, right: i128)
(left: f32, right: f32)
(left: f64, right: f64) }
}
}
}

View File

@@ -1,3 +1,4 @@
#[cfg(feature = "std")]
use dyn_any::{DynAny, StaticType};
use serde::{Deserialize, Serialize};
@@ -6,7 +7,8 @@ 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, DynAny)]
#[cfg_attr(feature = "std", derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize, DynAny))]
#[cfg_attr(not(feature = "std"), derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize))]
pub struct Color {
red: f32,
green: f32,