Comments in benilla-ui: one line of fact each, no history, no record numbers (#143)
Part of #41: the comments of `benilla-ui` (the Lua UI engine, its FrameXML loader and its widgets) are rewritten to the rule in `docs/METHOD.md`, which is what the code does and the reference fact behind it, in a line. 43,140 comment lines become 15,161. - **The mechanical strip.** The citations that were only a private record number go first, and each edit is shown to be a pure removal. - **Wrong facts corrected.** The rewrite corrects the comments that stated wrong facts. Among them: - `0x64a480` is the case-sensitive compare (a byte `repz cmpsb`), and `0x64a4c0` the case-insensitive one. - A frame's id sits at `+0xb0`, not `+0xb4`. `EnableKeyboard`/`IsKeyboardEnabled` are `0x776ec0`/`0x776f90`. - A region's unpinned edge has no fallback to its owner's rect: the owner supplies only the scale. - `$parent` expands to the nearest named ancestor, or "Top" when none is named (`0x76c5b0`), not simply to the parent. - A StatusBar fills from its internal normalised fraction, not from `GetValue()`. - The addresses of `StartDuel` and `StartDuelUnit` were swapped. - Many "untraced" notes now give the traced reference fact: the drag threshold, the per-grip sizing edges, the empty-`autoFocus` skip, and `SetTexCoordModifiesRect`'s default. - Stock FrameXML line citations are checked against the stock 1.12 files and corrected. `ref-` file names become the stock file names. - **Deviation labels.** "Deviation:" now marks only a choice with a reason. A surface that exists only for the retired Era addon target says so plainly: it is not 1.12. - **Verification.** Every file strips to identical code, and `cargo fmt --check` is clean. Nine second readers compared every file old against new, restored the facts the rewrite had dropped, and checked each new citation against the code, the stock files, vmangos and the reference. Behaviour differences the rewrite surfaced are filed as their own issues (#131–#142), and more are being validated. The comments here state what the code does. String literals are untouched; they are #92. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8505187668
commit
fd386e75ae
@@ -1,44 +1,13 @@
|
||||
//! **The widget-method surface gate** — the sibling of [`super::reference_surface`], for the API
|
||||
//! an addon reaches through a *widget* rather than through `_G` (decision 2142).
|
||||
//!
|
||||
//! `our_globals_stay_inside_the_1_12_surface` has guarded the global namespace since 1189, and the
|
||||
//! shape gate (1842/1843/2118) guards the arity and return kinds of the methods we *have*. Between
|
||||
//! them sat the question neither asks: **is the set of method NAMES on each widget class the set
|
||||
//! 1.12 registers?** A method the reference has and we do not is invisible to the shape gate,
|
||||
//! which skips what does not exist; a method we have and the reference does not is invisible to
|
||||
//! everything, and is the superset `api-coverage.sh`'s header calls "not free" — an addon that
|
||||
//! feature-detects (`if region.GetBlendMode then`) takes a path we cannot honour, and the failure
|
||||
//! surfaces far from the cause.
|
||||
//!
|
||||
//! A corpus census over 110 top-20 and 219 vanilla addons found both directions live at once
|
||||
//! (2142): `ShaguTweaks` probes `GetBlendMode`, which we were missing, and silently recolours
|
||||
//! textures the reference leaves alone; `pfUI` and `_Nameplates` call `GameTooltip:GetAnchorType`
|
||||
//! bare and raise. The demand is in the corpus, which is not in this repo — so this gate does not
|
||||
//! measure demand. It measures the SURFACE, and every entry in the two declared lists below is
|
||||
//! where the reading of the demand got written down.
|
||||
//!
|
||||
//! When re-reading that demand: those corpora hold addons that *run on* 1.12, not addons written
|
||||
//! only for it — most of the big ones are multi-client and pick a code path at load, and they come
|
||||
//! in several versions of themselves. `scripts/api-coverage.sh`'s header has the detail; decision
|
||||
//! 2146 is the case that made it matter.
|
||||
//!
|
||||
//! ## The reference side is a CHAIN, not 23 flat surfaces
|
||||
//!
|
||||
//! The reference's 23 widget registrar tables are mutually **disjoint** — a class's real surface is
|
||||
//! its own table plus the tables it misses into. Comparing a live `Frame` against `0x878ec0` alone
|
||||
//! reports 87 of its 88 methods as beyond-1.12, which is how you get a gate nobody believes.
|
||||
//! [`WIDGET_CHAINS`] is that inheritance, and its two non-obvious rows are byte-settled, not
|
||||
//! guessed: `0x87c9b8` is the base `Region` map (its 19 names are exactly [`super::super`]'s
|
||||
//! `REGION_MAP_METHODS`), and `0x847ce4` is `LootButton`, whose whole surface of its own is
|
||||
//! `SetSlot` (decision 1799, read off the registrar's own `mov edx,1`).
|
||||
//! The widget-method surface gate, the widget sibling of [`super::reference_surface`]. The
|
||||
//! reference's 23 widget registrar tables are disjoint, so a class's surface is its own table plus
|
||||
//! those it inherits ([`WIDGET_CHAINS`]): `0x87c9b8` is the base `Region` map (the 19
|
||||
//! `REGION_MAP_METHODS`), and `LootButton`'s own `0x847ce4` holds only `SetSlot`.
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use crate::script::{widget_method_census, UiScript};
|
||||
|
||||
/// `(class, its own registrar table, the tables it inherits)`.
|
||||
///
|
||||
/// `WorldFrame` is a `Frame` to Lua (1983/1984) and `TitleRegion` a bare `Region`, so neither has a
|
||||
/// table of its own among the 23. `TaxiRouteFrame` is absent for the same reason (1828).
|
||||
/// `(class, its own registrar table, the tables it inherits)`. `WorldFrame` is a `Frame` to Lua
|
||||
/// and `TitleRegion` a bare `Region`; like `TaxiRouteFrame`, neither has a table of its own.
|
||||
const WIDGET_CHAINS: &[(&str, &str, &[&str])] = &[
|
||||
("Frame", FRAME, &[REGION]),
|
||||
("WorldFrame", FRAME, &[REGION]),
|
||||
@@ -70,8 +39,7 @@ const WIDGET_CHAINS: &[(&str, &str, &[&str])] = &[
|
||||
("Minimap", "0x84c538", FRAME_CHAIN),
|
||||
("Texture", "0x87c128", &[REGION]),
|
||||
("FontString", "0x87c1d8", &[REGION]),
|
||||
// The font OBJECT (`CreateFont`) carries its own `GetName`/`GetObjectType`/`IsObjectType` and
|
||||
// inherits nothing.
|
||||
// The font object (`CreateFont`) inherits nothing.
|
||||
("Font", "0x87c7c8", &[]),
|
||||
("TitleRegion", REGION, &[]),
|
||||
];
|
||||
@@ -82,17 +50,11 @@ const MODEL: &str = "0x878948";
|
||||
const PLAYER_MODEL: &str = "0x84f1fc";
|
||||
const FRAME_CHAIN: &[&str] = &[FRAME, REGION];
|
||||
|
||||
/// Methods the reference registers that this client does not answer — **a list that may only
|
||||
/// shrink**, one row per name, naming every class it is missing on and why it has not been built.
|
||||
///
|
||||
/// The corpus demand behind each is 2142's census. A name with real, live callers does not belong
|
||||
/// here: it belongs implemented.
|
||||
/// Reference methods this client does not answer yet: one row per name, its classes and why. The
|
||||
/// list only shrinks; a name with live callers belongs implemented.
|
||||
const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
// ── The MovieFrame trio: zero addon demand, and the stock GLUE screen calls all three ──────
|
||||
// `_extracted_gluexml/MovieFrame.lua:23/30/35/47/71`. The glue screens stay ours permanently
|
||||
// (0068 §8), so the intro-movie screen is owed these however little the ecosystem wants them —
|
||||
// which makes this the one group here that is a real backlog item rather than a name nobody
|
||||
// has ever typed. benilla has no movie playback at all, so it is a feature, not a verb.
|
||||
// ── The MovieFrame trio ──
|
||||
// The stock glue `MovieFrame.lua` calls all three; benilla plays no movie yet.
|
||||
(
|
||||
"StartMovie",
|
||||
"MovieFrame",
|
||||
@@ -104,10 +66,8 @@ const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
"MovieFrame",
|
||||
"the same — `MovieFrame.lua:35` passes `GetMovieSubtitles()`",
|
||||
),
|
||||
// ── The Minimap's four content setters ────────────────────────────────────────────────────
|
||||
// benilla draws the minimap's blips, arrow and mask from the app side (`minimap/blips`), never
|
||||
// through Lua; the stock UI does not call these either. Wiring them means routing the art
|
||||
// choice back through the VM, which nothing has asked for.
|
||||
// ── The Minimap's four content setters ──
|
||||
// The app draws the minimap's blips and arrow itself, never through Lua.
|
||||
(
|
||||
"SetArrowModel",
|
||||
"Minimap",
|
||||
@@ -116,10 +76,8 @@ const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
("SetBlipTexture", "Minimap", "the same"),
|
||||
("SetIconTexture", "Minimap", "the same"),
|
||||
("SetPlayerModel", "Minimap", "the same"),
|
||||
// ── The Button font-object and text-colour family ─────────────────────────────────────────
|
||||
// Seven getters and one setter over a button's disabled/highlight/pushed font state. benilla
|
||||
// keeps that state (`button.rs`'s `Slot` triple) but publishes none of it back. **Zero call
|
||||
// sites in 329 addon folders and zero in the stock UI** — the whole family is completeness.
|
||||
// ── The Button font-object and text-colour family ──
|
||||
// `button.rs` keeps this font state but publishes none of it; nothing calls these.
|
||||
(
|
||||
"GetDisabledFontObject",
|
||||
"Button CheckButton LootButton",
|
||||
@@ -155,9 +113,7 @@ const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
"Button CheckButton LootButton",
|
||||
"the same family",
|
||||
),
|
||||
// ── Line spacing, on the five classes that carry text ─────────────────────────────────────
|
||||
// A real layout property benilla's text layout does not model — a setter here is not a store,
|
||||
// it is a change to how `ui_text` lays out wrapped lines. No caller anywhere measured.
|
||||
// ── Line spacing, on the five classes that carry text ──
|
||||
(
|
||||
"GetSpacing",
|
||||
"EditBox Font FontString MessageFrame ScrollingMessageFrame",
|
||||
@@ -168,9 +124,7 @@ const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
"EditBox Font FontString MessageFrame ScrollingMessageFrame",
|
||||
"the same — the setter is a layout change, not a stored value",
|
||||
),
|
||||
// ── EditBox mode read-backs ───────────────────────────────────────────────────────────────
|
||||
// The four modes are all SET here (`editbox`'s `SetAutoFocus`/`SetMultiLine`/`SetNumeric`/
|
||||
// `SetPassword`) and none is readable. Cheap, and nothing has ever asked.
|
||||
// ── EditBox mode read-backs ──
|
||||
(
|
||||
"IsAutoFocus",
|
||||
"EditBox",
|
||||
@@ -179,10 +133,7 @@ const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
("IsMultiLine", "EditBox", "the same"),
|
||||
("IsNumeric", "EditBox", "the same"),
|
||||
("IsPassword", "EditBox", "the same"),
|
||||
// ── ScrollingMessageFrame's line-position surface ─────────────────────────────────────────
|
||||
// The scroll POSITION verbs (`ScrollUp`/`ScrollDown`/`ScrollToTop`…) are all here; these four
|
||||
// report or set where that position sits, which our message buffer tracks internally and does
|
||||
// not publish. No caller anywhere measured.
|
||||
// ── ScrollingMessageFrame's line-position surface ──
|
||||
(
|
||||
"GetCurrentLine",
|
||||
"ScrollingMessageFrame",
|
||||
@@ -191,16 +142,14 @@ const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
("GetCurrentScroll", "ScrollingMessageFrame", "the same"),
|
||||
("GetNumLinesDisplayed", "ScrollingMessageFrame", "the same"),
|
||||
("SetScrollFromBottom", "ScrollingMessageFrame", "the same"),
|
||||
// ── The colour picker's HSV pair ──────────────────────────────────────────────────────────
|
||||
// `ColorSelect` publishes the RGB pair; the HSV twin would need the conversion the reference
|
||||
// does in C. The stock `ColorPickerFrame` uses RGB only, and so does every corpus caller.
|
||||
// ── The colour picker's HSV pair ──
|
||||
(
|
||||
"GetColorHSV",
|
||||
"ColorSelect",
|
||||
"the RGB pair is published; nothing measured asks for HSV",
|
||||
),
|
||||
("SetColorHSV", "ColorSelect", "the same"),
|
||||
// ── One texture read-back ─────────────────────────────────────────────────────────────────
|
||||
// ── One texture read-back ──
|
||||
(
|
||||
"IsDesaturated",
|
||||
"Texture",
|
||||
@@ -208,9 +157,7 @@ const NOT_YET_ANSWERED: &[(&str, &str, &str)] = &[
|
||||
),
|
||||
];
|
||||
|
||||
/// Methods this client answers that 1.12 does not register on that class — **each a deliberate,
|
||||
/// reasoned exception, never a quiet superset**. Same contract as
|
||||
/// [`super::reference_surface::allowed_beyond_1_12`]: a name here must say why it stays.
|
||||
/// Methods answered here that 1.12 does not register on that class, each with why it stays.
|
||||
const ALLOWED_BEYOND: &[(&str, &str, &str)] = &[];
|
||||
|
||||
/// The reference's widget rows, `table_va -> {name}`.
|
||||
@@ -236,7 +183,7 @@ fn reference_tables() -> BTreeMap<String, BTreeSet<String>> {
|
||||
out
|
||||
}
|
||||
|
||||
/// `class -> the effective reference surface` (own table + everything it inherits).
|
||||
/// `class -> the effective reference surface` (its own table and everything it inherits).
|
||||
fn reference_surface_by_class() -> BTreeMap<&'static str, BTreeSet<String>> {
|
||||
let tables = reference_tables();
|
||||
assert!(
|
||||
@@ -284,8 +231,7 @@ fn declared(list: &[(&str, &str, &str)]) -> BTreeMap<String, BTreeSet<String>> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Render a `class -> names` map as the declared-list rows it would need, so a failure hands you
|
||||
/// the entry to paste rather than a set difference to transcribe.
|
||||
/// Render a `class -> names` map as declared-list rows, ready to paste in.
|
||||
fn as_rows(diff: &BTreeMap<String, BTreeSet<String>>) -> String {
|
||||
let mut by_name: BTreeMap<&String, Vec<&String>> = BTreeMap::new();
|
||||
for (class, names) in diff {
|
||||
@@ -343,7 +289,7 @@ fn every_1_12_widget_method_is_answered() {
|
||||
as_rows(&missing)
|
||||
);
|
||||
|
||||
// A listed name that came back fails, so the list cannot outlive its fix.
|
||||
// A listed name that is answered now fails, so the list cannot outlive its fix.
|
||||
let mut healed: Vec<String> = Vec::new();
|
||||
for (name, classes, _) in NOT_YET_ANSWERED {
|
||||
for class in classes.split_whitespace() {
|
||||
@@ -374,8 +320,7 @@ fn our_widget_methods_stay_inside_the_1_12_surface() {
|
||||
let extra: BTreeSet<String> = have
|
||||
.iter()
|
||||
.filter(|n| !want.contains(*n))
|
||||
// Our host bridge and the VM's own internals declare themselves ours by prefix, the
|
||||
// same discipline `reference_surface` uses for globals.
|
||||
// Our host bridge and VM internals are marked by prefix, as `reference_surface` does.
|
||||
.filter(|n| !n.starts_with("Benilla") && !n.starts_with("__benilla_"))
|
||||
.filter(|n| !listed.get(*n).is_some_and(|c| c.contains(class)))
|
||||
.cloned()
|
||||
|
||||
Reference in New Issue
Block a user