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

@@ -4,8 +4,11 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, ToTokens};
use syn::parse::{Parse, ParseStream, Parser};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::{Comma, RArrow};
use syn::{AttrStyle, Attribute, Error, Expr, ExprTuple, FnArg, GenericParam, Ident, ItemFn, Lit, LitFloat, LitStr, Meta, Pat, PatIdent, PatType, Path, ReturnType, Type, WhereClause};
use syn::{
parse_quote, AttrStyle, Attribute, Error, Expr, ExprTuple, FnArg, GenericParam, Ident, ItemFn, Lit, LitFloat, LitStr, Meta, Pat, PatIdent, PatType, Path, ReturnType, Type, TypeParam, WhereClause,
};
use crate::codegen::generate_node_code;
@@ -548,10 +551,12 @@ fn extract_attribute<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attri
// Modify the new_node_fn function to use the code generation
pub fn new_node_fn(attr: TokenStream2, item: TokenStream2) -> TokenStream2 {
let parse_result = parse_node_fn(attr, item.clone());
let Ok(parsed_node) = parse_result else {
let Ok(mut parsed_node) = parse_result else {
let e = parse_result.unwrap_err();
return Error::new(e.span(), format!("Failed to parse node function: {e}")).to_compile_error();
};
parsed_node.replace_impl_trait_in_input();
if let Err(e) = crate::validation::validate_node_fn(&parsed_node) {
return Error::new(e.span(), format!("Validation Error:\n{e}")).to_compile_error();
}
@@ -564,6 +569,31 @@ pub fn new_node_fn(attr: TokenStream2, item: TokenStream2) -> TokenStream2 {
}
}
impl ParsedNodeFn {
fn replace_impl_trait_in_input(&mut self) {
if let Type::ImplTrait(impl_trait) = self.input.ty.clone() {
let ident = Ident::new("_Input", impl_trait.span());
let mut bounds = impl_trait.bounds;
bounds.push(parse_quote!('n));
self.fn_generics.push(GenericParam::Type(TypeParam {
attrs: Default::default(),
ident: ident.clone(),
colon_token: Some(Default::default()),
bounds,
eq_token: None,
default: None,
}));
self.input.ty = parse_quote!(#ident);
if self.input.implementations.is_empty() {
self.input.implementations.push(parse_quote!(gcore::Context));
}
}
if self.input.pat_ident.ident == "_" {
self.input.pat_ident.ident = Ident::new("__ctx", self.input.pat_ident.ident.span());
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -774,7 +804,7 @@ mod tests {
let attr = quote!(category("Vector: Shape"));
let input = quote!(
/// Test
fn circle(_: (), #[default(50.)] radius: f64) -> VectorData {
fn circle(_: impl Ctx, #[default(50.)] radius: f64) -> VectorData {
// Implementation details...
}
);
@@ -795,7 +825,7 @@ mod tests {
where_clause: None,
input: Input {
pat_ident: pat_ident("_"),
ty: parse_quote!(()),
ty: parse_quote!(impl Ctx),
implementations: Punctuated::new(),
},
output_type: parse_quote!(VectorData),