VSync joins the video options, the chat dock goes quiet

- VSync is a player setting on the Graphics page now — 1.12's own gxVSync, persisted like every other CVar — instead of a dev-HUD checkbox
- the perf HUD collapses to one surface that says everything once, at a deliberate, governed width; the badge stops crying wolf
- the idle chat dock stops repainting itself every frame — the fade applier gets the gate the reference carries twice over, and hovering still reveals the hidden tabs
- the tick can name who spent it: per-handler self/total attribution at the one seam where every handler fires

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-17 17:04:53 +07:00
co-authored by Claude Fable 5
parent 5ce93810b0
commit 39f5953a7e
17 changed files with 1525 additions and 278 deletions
@@ -0,0 +1,209 @@
//! Per-handler cost attribution (decision 1395) — the instrument that answers *which* handler.
//!
//! These assert on **names, call counts, and the self/total relation**, never on a duration
//! (0735): "this handler cost 2 ms" is not a fact a test can own. The one relational assertion
//! (`self < total` under nesting) carries its own exact control — the same shape with nothing
//! nested inside it must report `self == total` to the last nanosecond, which is what proves the
//! difference came from the subtraction rather than from the clock.
use super::common::script;
use crate::script::{HandlerRow, ScriptValue, UiScript};
/// The row for `frame:script`, or `None`.
fn row(rows: &[HandlerRow], frame: &str, script: &str) -> Option<HandlerRow> {
rows.iter()
.find(|r| r.frame == frame && r.script == script)
.cloned()
}
/// Recording, with no periodic report — the tests read the window directly.
fn armed() -> UiScript {
let s = script();
s.profile_handlers(true, 0.0);
s
}
#[test]
fn every_fired_handler_is_attributed_to_its_own_frame_and_script() {
let mut s = armed();
s.run(
r#"
local a = CreateFrame("Frame", "Alpha")
a:SetScript("OnUpdate", function() end)
local b = CreateFrame("Frame", "Beta")
b:SetScript("OnUpdate", function() end)
b:RegisterEvent("UNIT_HEALTH")
b:SetScript("OnEvent", function() end)
local quiet = CreateFrame("Frame", "Quiet")
"#,
)
.unwrap();
s.tick(0.016);
s.tick(0.016);
s.fire_event("UNIT_HEALTH", vec![ScriptValue::Str("player".into())]);
assert!(s.errors().is_empty(), "{:?}", s.errors());
let rows = s.handler_profile();
assert_eq!(
s.handler_profile_frames(),
2,
"two ticks is two frames of denominator"
);
assert_eq!(
row(&rows, "Alpha", "OnUpdate").map(|r| r.calls),
Some(2),
"one OnUpdate call per tick: {rows:#?}"
);
assert_eq!(row(&rows, "Beta", "OnUpdate").map(|r| r.calls), Some(2));
assert_eq!(
row(&rows, "Beta", "OnEvent").map(|r| r.calls),
Some(1),
"the event fan-out is attributed too, and separately from the tick"
);
assert!(
rows.iter().all(|r| r.frame != "Quiet"),
"a frame with no handler must not appear at all: {rows:#?}"
);
}
#[test]
fn a_handler_with_nothing_nested_inside_it_is_all_self_time() {
// The control for the nesting test below: with no nested fire, the subtraction is by zero and
// the two numbers must be *identical*, not merely close.
let mut s = armed();
s.run(
r#"
local f = CreateFrame("Frame", "Flat")
f:SetScript("OnUpdate", function()
local n = 0
for i = 1, 20000 do n = n + i end
end)
"#,
)
.unwrap();
s.tick(0.016);
let flat =
row(&s.handler_profile(), "Flat", "OnUpdate").expect("the flat handler is attributed");
assert_eq!(
flat.self_us, flat.total_us,
"nothing nested ⇒ self is total, exactly"
);
}
#[test]
fn a_handler_that_fires_another_is_not_charged_for_its_child() {
let mut s = armed();
s.run(
r#"
inner = CreateFrame("Frame", "Inner")
inner:Hide()
inner:SetScript("OnShow", function()
local n = 0
for i = 1, 200000 do n = n + i end
end)
local outer = CreateFrame("Frame", "Outer")
outer:SetScript("OnUpdate", function()
inner:Hide()
inner:Show() -- fires Inner's OnShow from inside Outer's OnUpdate
end)
"#,
)
.unwrap();
s.tick(0.016);
assert!(s.errors().is_empty(), "{:?}", s.errors());
let rows = s.handler_profile();
let outer = row(&rows, "Outer", "OnUpdate").expect("the outer handler is attributed");
let inner = row(&rows, "Inner", "OnShow").expect("the nested handler gets its own row");
assert_eq!(inner.calls, 1);
assert!(
outer.self_us < outer.total_us,
"the child's cost must come off the parent's self time: {outer:#?}"
);
// And the nested row must be the one holding it — the whole point is naming Inner, not Outer.
assert!(
inner.self_us > 0.0,
"the child's own cost lands on the child: {inner:#?}"
);
// A second tick must behave like the first: a leaked stack level would start charging Outer's
// child time to a phantom parent and the relation above would quietly stop holding.
s.tick(0.016);
let rows = s.handler_profile();
let outer = row(&rows, "Outer", "OnUpdate").expect("outer");
assert_eq!(outer.calls, 2);
assert_eq!(row(&rows, "Inner", "OnShow").map(|r| r.calls), Some(2));
assert!(outer.self_us < outer.total_us, "{outer:#?}");
}
#[test]
fn an_anonymous_frames_handler_is_labelled_by_where_it_was_written() {
// `CreateFrame("Frame")` + OnUpdate with no name is the addon timer idiom, so this is the
// common case, not the exotic one — and `#4127` would be an unusable row.
let mut s = armed();
s.run(
r#"
local f = CreateFrame("Frame")
f:SetScript("OnUpdate", function() end)
"#,
)
.unwrap();
s.tick(0.016);
let rows = s.handler_profile();
let [only] = &rows[..] else {
panic!("exactly one handler fired: {rows:#?}");
};
assert!(
!only.frame.starts_with('#') && only.frame.contains(':'),
"an unnamed frame is labelled by its handler's chunk and line, not by its id: {only:#?}"
);
}
#[test]
fn an_unarmed_vm_records_nothing() {
// The off-state is the shipped state, so it gets a guard of its own: a VM that was never armed
// must report an empty profile even while another VM in this process is recording (the gate is
// process-wide, the state is per-VM — see `handler_prof::ARMED`).
let _recording = armed();
let mut s = script();
s.run(
r#"
local f = CreateFrame("Frame", "Silent")
f:SetScript("OnUpdate", function() end)
"#,
)
.unwrap();
s.tick(0.016);
assert!(
s.handler_profile().is_empty(),
"an unarmed VM records nothing: {:#?}",
s.handler_profile()
);
assert_eq!(s.handler_profile_frames(), 0);
}
#[test]
fn disarming_clears_the_window() {
let mut s = armed();
s.run(
r#"
local f = CreateFrame("Frame", "Cleared")
f:SetScript("OnUpdate", function() end)
"#,
)
.unwrap();
s.tick(0.016);
assert!(!s.handler_profile().is_empty());
s.profile_handlers(false, 0.0);
assert!(s.handler_profile().is_empty(), "disarming drops the window");
s.tick(0.016);
assert!(
s.handler_profile().is_empty(),
"and a disarmed VM keeps recording nothing"
);
}