Files
benilla-octo/crates
gromandClaude Opus 5 754d577eaf ui: a trade-skill list mutator signals inside its own call
`ExpandTradeSkillSubClass`, `CollapseTradeSkillSubClass`,
`SetTradeSkillSubClassFilter` and `SetTradeSkillInvSlotFilter` fire
`TRADE_SKILL_UPDATE` from inside the call now, as the one helper all four
tail-call in the reference does (`0x4fd710`, `0x4fd730`, `0x4fd750`;
`reference/1.12-verb-events.tsv`). It used to be a `trade_skill_touched` flag
drained by `ui_tradeskill::drain_trade_skill` and answered the following frame.

Inline is load-bearing. These four verbs are called *from* a
`TRADE_SKILL_UPDATE` handler: a profession library reads the recipe list by
unfolding every header, walking it and folding back what was folded. The signal
is therefore re-entrant by construction, and every addon that does it carries
its own guard — LibCraftingProfessions has `trade_skill_scan_in_progress`, ATSW
an `atsw_scans < 2` counter. Those guards are written against an inline signal
and only an inline signal lands inside the window they cover.

Deferred to the next frame it landed after the guard had cleared: the library
rescanned, the rescan called the verb, the verb re-armed the flag, and the two
kept each other alive at one fire a frame for as long as the window was open.
grom's 2026-10-21 session shows it directly — `[ui-events]` reporting
`TRADE_SKILL_UPDATE · 1.01 fires/f · ~900 call(s)` across 37 consecutive
windows, three unbroken minutes, at 0.58-0.84 ms a frame in handlers over four
addons rebuilding their lists for nothing. It is the 118-second and 61-second
stretches at 55-70 fps in a session whose in-play median was 86.

Two tests: each mutator's fire is read with its own `run` still on the stack, so
a deferred signal fails; and a library-shaped in-progress guard turns one real
update into exactly one scan, with nothing owed to a later tick.

The bench's `[events]` block also fires the five non-quest events the live
session named. They cost ~0.2-0.5 ms there against 12-72 ms live, because this
harness has no NPC in front of it, no trainer list and no open map — recorded as
a gap, not an answer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
2026-10-21 14:47:57 -06:00
..