Clean up document message wrappers around proto nodes so they're now used directly (#4101)

* Rename the 'Identity' node to 'Passthrough' internally

* Rename the 'Memoize'  node to 'Cache' internally

* Let skip_impl proto nodes auto-generate as document node definitions

* Remove the wrapper 'Passthrough' node from document_node_definitions.rs

* Remove the wrapper 'Cache' node from document_node_definitions.rs

* Remove the wrapper 'Monitor' node from document_node_definitions.rs

* Remove the wrapper 'Noise Pattern' node from document_node_definitions.rs

* Remove the wrapper 'Brush' node from document_node_definitions.rs

* Remove the wrapper 'Transform' node from document_node_definitions.rs

* Code review improvements

* Rename Cache node back to Memoize

* More code review
This commit is contained in:
Keavon Chambers
2026-05-03 19:26:36 -07:00
committed by GitHub
parent b27b4c6be7
commit 21e5e06b0b
29 changed files with 408 additions and 662 deletions

View File

@@ -74,11 +74,11 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
.collect();
// Combined struct type parameters: data field generic idents (T, U, ...) + node generics (Node0, Node1, ...)
// For struct type instantiation: MemoNode<T, Node0>
// For struct type instantiation: MemoizeNode<T, Node0>
let struct_type_params: Vec<Ident> = data_field_generic_idents.iter().cloned().chain(node_generics.iter().cloned()).collect();
// Combined struct generic parameters with bounds for struct definition
// struct MemoNode<T: Clone, Node0>
// struct MemoizeNode<T: Clone, Node0>
let struct_generic_params: Vec<TokenStream2> = data_field_generics.iter().map(|gp| quote!(#gp)).chain(node_generics.iter().map(|id| quote!(#id))).collect();
let input_ident = &input.pat_ident;
@@ -622,8 +622,22 @@ fn generate_phantom_data<'a>(fn_generics: impl Iterator<Item = &'a crate::Generi
}
fn generate_register_node_impl(parsed: &ParsedNodeFn, field_names: &[&Ident], struct_name: &Ident, identifier: &Ident) -> Result<TokenStream2, Error> {
// On native, `register_node` and `register_metadata` run automatically via `#[ctor]`.
// On Wasm, `ctor` isn't available, so this `extern "C"` fn is invoked from JS to register the same way.
// `skip_impl` nodes don't generate a `register_node`, so the shim calls only `register_metadata` for them.
let registry_name = format_ident!("__node_registry_{}_{}", NODE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst), struct_name);
let register_node_call = if parsed.attributes.skip_impl { quote!() } else { quote!(register_node();) };
let wasm_shim = quote! {
#[cfg(target_family = "wasm")]
#[unsafe(no_mangle)]
extern "C" fn #registry_name() {
#register_node_call
register_metadata();
}
};
if parsed.attributes.skip_impl {
return Ok(quote!());
return Ok(wasm_shim);
}
let mut constructors = Vec::new();
@@ -708,8 +722,6 @@ fn generate_register_node_impl(parsed: &ParsedNodeFn, field_names: &[&Ident], st
)
));
}
let registry_name = format_ident!("__node_registry_{}_{}", NODE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst), struct_name);
let native = quote! {
#[cfg_attr(not(target_family = "wasm"), ctor)]
fn register_node() {
@@ -728,13 +740,7 @@ fn generate_register_node_impl(parsed: &ParsedNodeFn, field_names: &[&Ident], st
Ok(quote! {
#native
#[cfg(target_family = "wasm")]
#[unsafe(no_mangle)]
extern "C" fn #registry_name() {
register_node();
register_metadata();
}
#wasm_shim
})
}

View File

@@ -52,7 +52,7 @@ pub(crate) struct NodeFnAttributes {
pub(crate) shader_node: Option<ShaderNodeType>,
/// Custom serialization function path (e.g., "my_module::custom_serialize")
pub(crate) serialize: Option<Path>,
/// Whether the preprocessor should add a Memo node after this node in the generated subnetwork
/// Whether the preprocessor should add a Memoize node after this node in the generated subnetwork
pub(crate) memoize: bool,
}
@@ -379,7 +379,7 @@ impl Parse for NodeFnAttributes {
.map_err(|_| Error::new_spanned(meta, "Expected a valid path for 'serialize', e.g., serialize(my_module::custom_serialize)"))?;
serialize = Some(parsed_path);
}
// Instructs the preprocessor to insert a Memo node after this node in the generated subnetwork,
// Instructs the preprocessor to insert a Memoize node after this node in the generated subnetwork,
// caching its output across evaluations with identical inputs.
//
// Example usage: