Replace Footprint/() call arguments with dynamically-bound Contexts (#2232)

* Implement experimental Context struct and traits

* Add Ctx super trait

* Checkpoint

* Return Any instead of DynAny

* Fix send implementation for inputs with lifetimes

* Port more nodes

* Uncomment nodes

* Port more nodes

* Port vector nodes

* Partial progress (the stuff I'm more sure about)

* Partial progress (the stuff that's not compiling and I'm not sure about)

* Fix more errors

* First pass of fixing errors introduced by rebase

* Port wasm application io

* Fix brush node types

* Add type annotation

* Fix warnings and wasm compilation

* Change types for Document Node definitions

* Improve debugging for footprint not found errors

* Forward context in append artboard node

* Fix thumbnails

* Fix loading most demo artwork

* Wrap output type of all nodes in future

* Encode futures as part of the type

* Fix document node definitions for future types

* Remove Clippy warnings

* Fix more things

* Fix opening demo art with manual composition upgrading

* Set correct type for manual composition

* Fix brush

* Fix tests

* Update docs for deps

* Fix up some node signature issues

* Code review

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
Co-authored-by: hypercube <0hypercube@gmail.com>
This commit is contained in:
Dennis Kobert
2025-03-01 23:54:52 +01:00
committed by Keavon Chambers
parent 0c1e96b9c6
commit 4ff2bdb04f
43 changed files with 1338 additions and 1545 deletions

View File

@@ -1,57 +1,40 @@
use crate::transform::Footprint;
use crate::vector::VectorDataTable;
use crate::Context;
use crate::Ctx;
use glam::{DAffine2, DVec2};
#[node_macro::node(category("Debug"))]
async fn log_to_console<T: core::fmt::Debug, F: Send + 'n>(
#[implementations((), (), (), (), (), (), (), (), Footprint)] footprint: F,
#[implementations(
() -> String, () -> bool, () -> f64, () -> u32, () -> u64, () -> DVec2, () -> VectorDataTable, () -> DAffine2,
Footprint -> String, Footprint -> bool, Footprint -> f64, Footprint -> u32, Footprint -> u64, Footprint -> DVec2, Footprint -> VectorDataTable, Footprint -> DAffine2,
)]
value: impl Node<F, Output = T>,
) -> T {
fn log_to_console<T: core::fmt::Debug>(_: impl Ctx, #[implementations(String, bool, f64, u32, u64, DVec2, VectorDataTable, DAffine2)] value: T) -> T {
#[cfg(not(target_arch = "spirv"))]
// KEEP THIS `debug!()` - It acts as the output for the debug node itself
let value = value.eval(footprint).await;
debug!("{:#?}", value);
value
}
#[node_macro::node(category("Debug"))]
async fn to_string<T: core::fmt::Debug + 'n, F: Send + 'n>(
#[implementations((), (), (), (), (), (), Footprint)] footprint: F,
#[implementations(
() -> String, () -> bool, () -> f64, () -> u32, () -> u64, () -> DVec2,
Footprint -> String, Footprint -> bool, Footprint -> f64, Footprint -> u32, Footprint -> u64, Footprint -> DVec2,
)]
value: impl Node<F, Output = T>,
) -> String {
let value = value.eval(footprint).await;
#[node_macro::node(category("Debug"), skip_impl)]
fn to_string<T: core::fmt::Debug>(_: impl Ctx, #[implementations(String, bool, f64, u32, u64, DVec2, VectorDataTable, DAffine2)] value: T) -> String {
format!("{:?}", value)
}
#[node_macro::node(category("Debug"))]
async fn switch<T, F: Send + 'n>(
#[implementations((), (), (), (), (), (), (), (), Footprint)] footprint: F,
async fn switch<T, C: Send + 'n + Clone>(
#[implementations(Context)] ctx: C,
condition: bool,
#[expose]
#[implementations(
() -> String, () -> bool, () -> f64, () -> u32, () -> u64, () -> DVec2, () -> VectorDataTable, () -> DAffine2,
Footprint -> String, Footprint -> bool, Footprint -> f64, Footprint -> u32, Footprint -> u64, Footprint -> DVec2, Footprint -> VectorDataTable, Footprint -> DAffine2
Context -> String, Context -> bool, Context -> f64, Context -> u32, Context -> u64, Context -> DVec2, Context -> VectorDataTable, Context -> DAffine2,
)]
if_true: impl Node<F, Output = T>,
if_true: impl Node<C, Output = T>,
#[expose]
#[implementations(
() -> String, () -> bool, () -> f64, () -> u32, () -> u64, () -> DVec2, () -> VectorDataTable, () -> DAffine2,
Footprint -> String, Footprint -> bool, Footprint -> f64, Footprint -> u32, Footprint -> u64, Footprint -> DVec2, Footprint -> VectorDataTable, Footprint -> DAffine2
Context -> String, Context -> bool, Context -> f64, Context -> u32, Context -> u64, Context -> DVec2, Context -> VectorDataTable, Context -> DAffine2,
)]
if_false: impl Node<F, Output = T>,
if_false: impl Node<C, Output = T>,
) -> T {
if condition {
if_true.eval(footprint).await
// We can't remove these calls because we only want to evaluate the branch that we actually need
if_true.eval(ctx).await
} else {
if_false.eval(footprint).await
if_false.eval(ctx).await
}
}