The target-of-target rows only write their globals, as 1.12's options do (#2150)
1.12's options declare Show Target of Target as a bare uvar (UIOptionsFrame.lua:65) and the mode is read on save (UIOptionsFrame.lua:365); neither calls TargetofTarget_Update. The frame follows from TargetFrame_OnUpdate and TargetofTarget_OnUpdate on the next frame (TargetFrame.lua:492-501). Our rows called it as their applyFunc, with the row as `this`; the function refreshes `this`'s debuffs (RefreshBuffs(this, 0, "targettarget"), TargetFrame.lua:538), so with a target's target up the switch raised "BuffFrame.lua:281: attempt to index local 'debuffBorder' (a nil value)" (seen on a Linux client). Verified: the_target_of_target_switch_leaves_the_frame_to_its_own_updates (with a target's target up: no error, the frame shows after one tick on and hides after one tick off) fails with the applyFunc put back, with exactly that error, and passes without it; the options and tot_frame tests pass on a deDE install; cargo test -p benilla-app --lib 5145, clippy -D warnings, fmt. Built on macOS only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 4d6f9ecc8a0d99e6d3ecf7fa4a8da229ebad92c2)
This commit is contained in:
@@ -2412,7 +2412,12 @@
|
||||
</OnLoad></Scripts>
|
||||
</Frame>
|
||||
<!-- Saved globals in 1.12; the mode greys with its switch
|
||||
(UIOptionsFrame.lua:697-701). -->
|
||||
(UIOptionsFrame.lua:697-701). Neither row applies anything:
|
||||
1.12's options only write the uvars (UIOptionsFrame.lua:65),
|
||||
and the target frames' OnUpdates show or hide the frame on
|
||||
the next frame (TargetFrame.lua:492-501). Called from a row,
|
||||
TargetofTarget_Update would refresh the row's debuffs
|
||||
(RefreshBuffs(this, ...), TargetFrame.lua:538). -->
|
||||
<Frame name="$parentRowTargetOfTarget" inherits="BenillaOptionsCheckboxRowTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentRowStatusText" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
|
||||
@@ -2421,7 +2426,6 @@
|
||||
<Scripts><OnLoad>
|
||||
BenillaOptionsGlobalRow_OnLoad(this, "SHOW_TARGET_OF_TARGET",
|
||||
"Show Target of Target", "OPTION_TOOLTIP_SHOW_TARGET_OF_TARGET")
|
||||
this.applyFunc = "TargetofTarget_Update"
|
||||
</OnLoad></Scripts>
|
||||
</Frame>
|
||||
<!-- The label is ours, since 1.12 never sets this
|
||||
@@ -2441,7 +2445,6 @@
|
||||
{ text = "Party or Raid", value = "4", tip = "OPTION_TOOLTIP_TARGETOFTARGET4" },
|
||||
{ text = "Always", value = "5", tip = "OPTION_TOOLTIP_TARGETOFTARGET5" },
|
||||
})
|
||||
this.applyFunc = "TargetofTarget_Update"
|
||||
</OnLoad></Scripts>
|
||||
</Frame>
|
||||
<!-- PLAYER_FLAGS bits, API rows
|
||||
|
||||
@@ -3751,8 +3751,9 @@ fn the_interface_page_writes_the_three_stock_globals() {
|
||||
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
|
||||
}
|
||||
|
||||
/// The picker is dead while the switch is off (`UIOptionsFrame.lua:697-701`), both rows run
|
||||
/// `TargetofTarget_Update` on a write, and the five entries are the reference's, in its order.
|
||||
/// The picker is dead while the switch is off (`UIOptionsFrame.lua:697-701`), both rows only write
|
||||
/// their globals, as 1.12's options do (`UIOptionsFrame.lua:65`), and the five entries are the
|
||||
/// reference's, in its order.
|
||||
#[test]
|
||||
fn the_target_of_target_rows_gate_each_other_and_write_their_globals() {
|
||||
benilla_formats::wow_data_or_skip!();
|
||||
@@ -3807,13 +3808,11 @@ fn the_target_of_target_rows_gate_each_other_and_write_their_globals() {
|
||||
);
|
||||
assert!(
|
||||
s.eval::<bool>(
|
||||
"return BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTarget.applyFunc \
|
||||
== \"TargetofTarget_Update\" \
|
||||
and BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTargetMode.applyFunc \
|
||||
== \"TargetofTarget_Update\""
|
||||
"return BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTarget.applyFunc == nil \
|
||||
and BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTargetMode.applyFunc == nil"
|
||||
)
|
||||
.unwrap(),
|
||||
"both rows re-decide the frame when they are written"
|
||||
"the frames' own OnUpdates re-decide the frame, as in 1.12"
|
||||
);
|
||||
|
||||
s.run("BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTargetModeDropdownButton:Click()")
|
||||
@@ -3848,6 +3847,53 @@ fn the_target_of_target_rows_gate_each_other_and_write_their_globals() {
|
||||
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
|
||||
}
|
||||
|
||||
/// With a target's target up, the switch raises nothing and the frame follows on the next frame,
|
||||
/// from `TargetFrame_OnUpdate` and `TargetofTarget_OnUpdate` (`TargetFrame.lua:492-501`). Run from
|
||||
/// the row, `TargetofTarget_Update` refreshed the row's own debuffs (`RefreshBuffs(this, …)`,
|
||||
/// `TargetFrame.lua:538`) and raised `BuffFrame.lua:281: attempt to index local 'debuffBorder'`.
|
||||
#[test]
|
||||
fn the_target_of_target_switch_leaves_the_frame_to_its_own_updates() {
|
||||
use benilla_ui::script::UnitState;
|
||||
benilla_formats::wow_data_or_skip!();
|
||||
let mut s = interface_harness();
|
||||
let unit = |name: &str, guid: u64| UnitState {
|
||||
exists: true,
|
||||
is_connected: true,
|
||||
name: Some(name.into()),
|
||||
guid,
|
||||
health: 80,
|
||||
max_health: 100,
|
||||
level: 60,
|
||||
..UnitState::default()
|
||||
};
|
||||
s.set_unit("player", Some(unit("Tri", 0x100)));
|
||||
s.set_unit("target", Some(unit("Kobold Miner", 0x200)));
|
||||
s.set_unit("targettarget", Some(unit("Tri", 0x100)));
|
||||
s.fire_event("PLAYER_TARGET_CHANGED", vec![]);
|
||||
s.run("ShowUIPanel(BenillaOptionsFrame)").unwrap();
|
||||
s.run("BenillaOptionsFrameCategoryListRowInterface:Click()")
|
||||
.unwrap();
|
||||
let shown = |s: &mut UiScript| {
|
||||
s.eval::<bool>("return TargetofTargetFrame:IsShown() and true or false")
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
s.run("BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTargetCheck:Click()")
|
||||
.unwrap();
|
||||
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
|
||||
s.tick(0.016);
|
||||
assert!(
|
||||
shown(&mut s),
|
||||
"on: the target frame's OnUpdate brings it up"
|
||||
);
|
||||
|
||||
s.run("BenillaOptionsFrameContainerBodyInterfaceRowTargetOfTargetCheck:Click()")
|
||||
.unwrap();
|
||||
s.tick(0.016);
|
||||
assert!(!shown(&mut s), "off: its own OnUpdate takes it down");
|
||||
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
|
||||
}
|
||||
|
||||
/// Show Cloak and Show Helm are bits of the character's `PLAYER_FLAGS`, read and written through
|
||||
/// 1.12's `func`/`setFunc` pair (`UIOptionsFrame.lua:18-19`). The getter follows the click before
|
||||
/// the server answers: the wire verb is a blind flip, so a second click must see the new state.
|
||||
|
||||
Reference in New Issue
Block a user