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
This commit is contained in:
@@ -49,27 +49,6 @@ const ELSEWHERE: &[(&str, &str, &str)] = &[
|
||||
"QUEST_LOG_UPDATE",
|
||||
"benilla-app/src/ui_quest_log.rs",
|
||||
),
|
||||
// `trade_skill_touched`, set by all four verbs, drained by `take_trade_skill_touched`.
|
||||
(
|
||||
"CollapseTradeSkillSubClass",
|
||||
"TRADE_SKILL_UPDATE",
|
||||
"benilla-app/src/ui_tradeskill.rs",
|
||||
),
|
||||
(
|
||||
"ExpandTradeSkillSubClass",
|
||||
"TRADE_SKILL_UPDATE",
|
||||
"benilla-app/src/ui_tradeskill.rs",
|
||||
),
|
||||
(
|
||||
"SetTradeSkillInvSlotFilter",
|
||||
"TRADE_SKILL_UPDATE",
|
||||
"benilla-app/src/ui_tradeskill.rs",
|
||||
),
|
||||
(
|
||||
"SetTradeSkillSubClassFilter",
|
||||
"TRADE_SKILL_UPDATE",
|
||||
"benilla-app/src/ui_tradeskill.rs",
|
||||
),
|
||||
// `repeat_count` moved (`repeat_changed`).
|
||||
(
|
||||
"DoTradeSkill",
|
||||
|
||||
Reference in New Issue
Block a user