Migrate memo nodes to node macro and make implementing other persistent nodes easier (#3552)

* Add #[data] and #[serialize] attributes to node macro

- Add #[data] attribute for struct fields that aren't node parameters
  - Data fields are initialized with Default::default()
  - Passed as references to the underlying function
  - Excluded from registry metadata (internal state)
  - Generic types in data fields allowed without #[implementations]

- Add #[serialize] attribute for custom Node::serialize() implementation
  - Receives references to all data fields
  - Generates serialize() method in Node trait impl

- Conditional derives based on data field presence
  - With data fields: Debug, Clone only
  - Without data fields: Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash

* Refactor Memo and Monitor Node to use node macro

* Move Complex type into type alias

* Fix format

* Update node-graph/nodes/gcore/src/memo.rs

Co-authored-by: Keavon Chambers <keavon@keavon.com>

* Update node-graph/nodes/gcore/src/memo.rs

Co-authored-by: Keavon Chambers <keavon@keavon.com>

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Dennis Kobert
2026-01-05 22:28:02 +01:00
committed by GitHub
parent 8f25eb6ca4
commit fafc687d84
5 changed files with 249 additions and 115 deletions

View File

@@ -102,6 +102,11 @@ fn validate_implementations_for_generics(parsed: &ParsedNodeFn) {
if !has_skip_impl && !parsed.fn_generics.is_empty() {
for field in &parsed.fields {
// Skip validation for data fields - they're internal state and can be generic
if field.is_data_field {
continue;
}
let pat_ident = &field.pat_ident;
match &field.ty {
ParsedFieldType::Regular(RegularParsedField { ty, implementations, .. }) => {