Skip to content

Separate hot runtime value propagation from UI/parameter observation #282

Description

@vade

Separate hot runtime value propagation from UI/parameter observation. Keep Parameters and Combine for authored/editor state, but let graph execution move port values through direct internal storage without publishing every per-frame update.

Key Changes

  • Add internal runtime storage on ports:

    • Keep existing public value / parameter sync behavior for UI/editor paths.
    • Add internal fast-path assignment for execution, e.g. setRuntimeValue(_:force:), that updates value state without Combine/UI notification.
  • Split send paths:

    • Existing send(..., force:) remains the observable/editor-safe path.
    • New runtime send path directly assigns connected inlet runtime values and updates valueDidChange/dirty state.
  • Keep parameters authoritative for authored inputs:

    • UI edits update Parameters.
    • Parameters seed/update inlet runtime values.
    • Nodes mark dirty normally.
  • Treat computed outlet values as runtime data:

    • Node execute writes outlet runtime values.
    • Connected inlet runtime values update directly.
    • UI does not receive per-port Combine events every execution iteration.
  • Add a live inspection strategy later:

    • Visible node views can sample current runtime values on demand, or
    • GraphRenderer can emit one throttled “runtime values changed” tick for visible/debug UI only.

Migration Approach

  • Start with a narrow internal API on NodePort.
  • Convert only execution hot spots first, especially outlet-to-inlet propagation from node execute.
  • Leave parameter editing, connection changes, publishing, serialization, and UI-visible port metadata unchanged.
  • Add assertions/tests to ensure observable send still works for editor paths.

Test Plan

  • Functional:

    • Parameter edits still update connected graph execution.
    • Published inputs/outputs still serialize and restore.
    • Node UI still reflects authored parameter values.
    • Live/debug value display either remains unchanged or is explicitly marked as sampled/throttled.
  • Performance:

    • Profile iterator String Queue before/after.
    • Confirm NodePort.send, _send, ParameterPort.value.didSet, and GenericParameter.value.didSet drop from per-iteration hot paths.
  • Regression:

    • Feedback cache still snapshots the correct outlet runtime values.
    • Type-agnostic nodes using snapshotValue() / sendBoxed() still work.
    • Connected parameter ports still receive user-authored values correctly.

Assumptions

  • Combine remains for UI/editor observation, not graph execution.
  • Runtime values may change every frame without forcing SwiftUI redraws.
  • Live port value UI should be sampled or throttled rather than synchronously published per value write.
  • Public API changes should be avoided until the internal model proves itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions