Help / example patch generation (phase 0: tool + plumbing)#126
Open
jcelerier wants to merge 6 commits into
Open
Help / example patch generation (phase 0: tool + plumbing)#126jcelerier wants to merge 6 commits into
jcelerier wants to merge 6 commits into
Conversation
Introduces the infrastructure for shipping a help/example patch with every object, per backend. Two sources: an explicit per-object override file (copied verbatim) or an auto-generated patch produced from the object's introspection dump. - examples/Demos/GeneratePatches.cpp: a new JSON-driven tool (generate_patches <backend> <dump.json> <output>) that parses the dump schema into a normalized model once and dispatches to per-backend emitters (pd, max/.maxhelp, godot/.tscn, td, python). Phase 0 emitters are minimal but valid (instantiate the object + carry title/description); later phases flesh out the rich layout. - cmake/avendish.tools.cmake: build the generate_patches target (same deps as json_to_maxref). - cmake/avendish.help.cmake: reusable avnd_generate_help() — override-if-present else auto-generate, stores the result path as a target property, best-effort, with an AVND_DISABLE_AUTOHELP escape hatch. Mirrors the maxref wiring. - cmake/avendish.pd.cmake: avnd_make_pd gains a HELP_PATCH override arg and emits pd/<c_name>-help.pd. - cmake/avendish.cmake: include avendish.help after avendish.dump. - HELP_PATCH_GENERATION_PLAN.md: full plan (architecture, per-backend design, override mechanism, packaging, phasing, validated TD .tox text-synthesis path). Verified: tool builds on MSVC and emits valid output for all five backends from a real dump; avnd_generate_help exercised in both override and auto-gen modes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
Flesh out the pd emitter from the phase-0 stub into a rich, ELSE-style help
patch generated from the dump JSON:
- Header: title bar (object name) + an avendish library badge.
- Description text from the object metadata.
- Live interactive demo:
* one driver widget per control, wired to the object's left inlet via a
[<selector> $1( message — float→hsl (with range) or floatatom, int→floatatom,
bool→tgl, enum(with choices)→hradio, string→symbolatom; bang/impulse and
complex/multi-component controls fall back to an editable message box;
* the message selector replicates the binding's name normalization
([^a-zA-Z0-9.~] -> '_'), so messages actually route to the control;
* osc~ sources into the signal inlets for audio inputs;
* clip~ -> dac~ for audio outputs, number/print sinks for value/message
outputs, wired in dump (= outlet) order.
- Labelled inlets / outlets sections (cnv dividers) with per-port type/range and
description text.
Object indices are tracked in creation order and connections emitted afterward,
matching the Pd netlist format. Verified against real dumps (a value-port object
and an audio effect with a ranged slider): correct widget→message→inlet and
audio osc~→object→clip~→dac~ wiring, and all connect indices in range.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
- GeneratePatches.cpp: full Max emitter producing an interactive .maxhelp JSON patcher: title/description comments; one widget per control (flonum/number/ toggle/button) wired through a [selector $1( message into the object's left inlet (Max registers an "anything" A_GIMME method, same name normalization as Pd); cycle~ sources for audio in; *~ -> ezdac~ and print sinks for outputs. Complements the existing .maxref.xml reference. Also create the output's parent directory before writing (fixes generation into max/help/, pd/, etc.). - avendish.max.cmake: avnd_make_max gains a HELP_PATCH override arg and emits max/help/<c_name>.maxhelp via avnd_generate_help (property AVND_MAX_HELP). - avendish.packaging.cmake: the Max addon packager copies the .maxhelp into the package's help/ folder (best-effort, same rationale as the maxref copy). Verified: 112 *_max_help targets created; building one produces a valid .maxhelp (comment header, flonum->[Gain $1]->inlet 0, cycle~->object->*~->ezdac~). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
…lish Godot (.tscn, fully text-emittable): - emit a scene instantiating the registered class (avnd_<c_name><suffix>, passed from CMake via the new EXTRA_ARG hint since the suffix depends on processor type) with exported properties set to their init values. - avnd_make_godot gains an EXAMPLE_GODOT override; godot/examples/<...>.tscn, copied into the package's examples/ folder. TouchDesigner (.tox is binary + an avendish operator is a compiled Custom OP, so a network can only reference it once installed): - ship a Python network-builder script (td/examples/<c_name>.example.py) that documents the parameters and scaffolds the network; a hand-authored .tox can be shipped via the EXAMPLE_TD override. (The validated toeexpand/toecollapse text-synthesis path remains documented for a future iteration.) Python: a runnable usage example (import, construct, set controls) next to the module, with an EXAMPLE_PY override. Polish / infra: - Pd: wrap long control lists into columns (a 190-port object went from 620x6286 to 2084x3946) and move per-control descriptions to the inlets section. - avnd_generate_help: EXTRA_ARG passthrough; guard against a not-yet-created source target (direct avnd_make_* calls). - generate_patches: create the output's parent directory; optional hint arg. Per-control descriptions need no code change: emit_port already dumps each port's metadata (incl. description), and every emitter surfaces it — authors only need to declare them. Verified: 189 godot / 194 td / 94 python example targets configure; building one of each produces a valid .tscn (type=avnd_avnd_addition, properties set), a TD builder script, and a Python example. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
Pd auto-wraps long #X text comments, but the emitter advanced the Y cursor by a fixed amount per line, so a comment that wrapped to two lines (e.g. the "left inlet: any [name value( ..." explanation) collided with the next comment. Give each comment an explicit character width (Pd's `, f <n>` flag) so wrapping is deterministic, and have text() return the vertical space it occupies (ceil(len/width) * line-height). Section emission now advances Y by that returned height, so multi-line comments reserve the room they need. Verified in Pd 0.56.5: the inlets/outlets sections no longer overlap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Infrastructure for shipping a help / example patch with every object, per backend. Two sources, in priority order:
dump/<c_name>.json).This first PR lands the plumbing and the generator tool (phase 0). The rich per-backend emitters land in follow-up phases — see
HELP_PATCH_GENERATION_PLAN.mdfor the full design.Contents
examples/Demos/GeneratePatches.cpp— new JSON-driven tool (generate_patches <backend> <dump.json> <output>). Parses the dump schema into a normalized model once, then dispatches to per-backend emitters (pd,max/.maxhelp,godot/.tscn,td,python). Phase-0 emitters are minimal but valid (instantiate the object + carry title/description).cmake/avendish.help.cmake— reusableavnd_generate_help(): override-if-present else auto-generate, stores the result path as a target property, best-effort,AVND_DISABLE_AUTOHELPescape hatch. Mirrors the existing maxref wiring.cmake/avendish.tools.cmake— builds thegenerate_patchestarget.cmake/avendish.pd.cmake—avnd_make_pdgains aHELP_PATCHoverride arg and emitspd/<c_name>-help.pd.cmake/avendish.cmake— includesavendish.help.HELP_PATCH_GENERATION_PLAN.md— architecture, per-backend design, override mechanism, packaging integration, phasing, and the validated TouchDesigner.toxtext-synthesis path (via the bundledtoeexpand/toecollapse).Verification
generate_patchesbuilds on MSVC and emits valid output for all five backends from a realAllPortsTypesdump (.maxhelpis valid JSON,.tscnvalid scene text).avnd_generate_helpexercised in both override (verbatim copy) and auto-gen modes.Next
Phase 1: the full Pure Data emitter (header + badge, live interactive demo with a widget wired per control, inlets/outlets/arguments sections, enum/string/color/xy completion).
🤖 Generated with Claude Code