Skip to content

Commit 55ddb7b

Browse files
author
mergetest
committed
Merge PR #224: 12.1 performance pass, alpha-14 fixes, Important Debuffs on by default
# Conflicts: # DandersFrames/Features/Dispel.lua
2 parents 3ad44fc + ed307a5 commit 55ddb7b

30 files changed

Lines changed: 2133 additions & 447 deletions

CHANGELOG.md

Lines changed: 19 additions & 4 deletions
Large diffs are not rendered by default.

DandersFrames/AuraDesigner/Factory.lua

Lines changed: 236 additions & 75 deletions
Large diffs are not rendered by default.

DandersFrames/Core.lua

Lines changed: 141 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,26 @@ DF.DebugSubCommands = {}
227227
-- This lookup is what the dispatcher gate consults so the two halves now match.
228228
DF.DEBUG_SUB_DEV = {}
229229

230+
-- ☠ EVERY sub() NAME, dev or not. This is what stops "/df debug <word>" loading
231+
-- the settings addon for a command that lives entirely in this one.
232+
--
233+
-- The dispatcher's unknown-word fallback exists because a handful of debug tools
234+
-- (icons, colorhook, atlas, auraexp, memtest) register their slashes only when
235+
-- the companion loads, so an unrecognised word has to load it and retry. But
236+
-- "recognised" was read from DebugSlashBySub, which ONLY RegisterDebugSlash
237+
-- fills -- so all ~38 commands registered through sub() looked unknown and pulled
238+
-- in ~3 MB of settings UI before running a branch that never needed it. That is
239+
-- the whole saving of splitting the addon in two, spent on one diagnostic.
240+
--
241+
-- Worse for the probes that exist to MEASURE memory: loading the companion
242+
-- perturbs exactly what they report.
243+
--
244+
-- Safe against shadowing: no sub() name collides with a companion-registered
245+
-- slash, so this set can never swallow a word that genuinely needs the load. The
246+
-- sub() branches that DO need the companion (profiler, ...) call
247+
-- EnsureOptionsLoaded themselves, at the point of need.
248+
DF.DEBUG_SUB_KNOWN = {}
249+
230250
-- ============================================================
231251
-- CHAT OUTPUT HOUSE STYLE (DF:Out)
232252
-- ============================================================
@@ -526,6 +546,9 @@ function DF:RegisterDebugSub(cmd, desc, devOnly, args, hidden)
526546
-- command cannot be marked dev in the listing while staying runnable on
527547
-- release — the two can no longer drift apart.
528548
if devOnly then DF.DEBUG_SUB_DEV[cmd] = true end
549+
-- Registering IS the gate here too: a branch added later is covered on the
550+
-- day it is written, with no second list to keep in step.
551+
DF.DEBUG_SUB_KNOWN[cmd] = true
529552
end
530553

531554
-- ============================================================
@@ -1219,8 +1242,13 @@ function DF:LightweightUpdateHighlight(highlightType)
12191242
end
12201243

12211244
if highlight and highlight:IsShown() then
1245+
-- ☠ This function writes the four line textures DIRECTLY, bypassing
1246+
-- ApplyHighlightStyle, so its cached style is stale the moment we touch
1247+
-- them. Drop it or the next full update sees a matching signature and
1248+
-- skips, leaving these drag-time values in place permanently.
1249+
if DF.InvalidateHighlightStyle then DF:InvalidateHighlightStyle(highlight) end
12221250
highlight:SetAlpha(alpha)
1223-
1251+
12241252
-- Update border textures - check both naming conventions
12251253
local top = highlight.top or highlight.topLine
12261254
local bottom = highlight.bottom or highlight.bottomLine
@@ -1647,6 +1675,36 @@ function DF:GetClassColor(class)
16471675
return RAID_CLASS_COLORS[class] or DEFAULT_CLASS_COLOR
16481676
end
16491677

1678+
-- ============================================================
1679+
-- UNIT ROLE RESOLUTION
1680+
-- ============================================================
1681+
-- ☠ NEVER CALL UnitGroupRolesAssigned DIRECTLY FOR A GATE. Use this.
1682+
--
1683+
-- UnitGroupRolesAssigned answers "what role did the GROUP assign", not "what
1684+
-- does this player do". It returns "NONE" solo, in the open world, in open-world
1685+
-- groups, and in delves until something forces an assignment -- so a Holy
1686+
-- Paladin standing in Silvermoon reads as NONE, and any caller that maps NONE
1687+
-- onto DAMAGER decides a healer is a DPS. That is what made the resource bar's
1688+
-- Healers toggle inert while solo (the bar answered to the DPS toggle instead),
1689+
-- and why a delve only resolved the role after a spec change.
1690+
--
1691+
-- The player is the one unit we can do better for: GetSpecializationRole is
1692+
-- authoritative and always available. Other units expose no public spec API, so
1693+
-- they stay NONE and the caller keeps whatever fallback it had.
1694+
--
1695+
-- Returns nil for a unit that does not exist, otherwise a role token that may
1696+
-- still be "NONE" -- resolution only, no policy. Callers decide what NONE means.
1697+
function DF:GetUnitRole(unit)
1698+
if not unit or not UnitExists(unit) then return nil end
1699+
local role = UnitGroupRolesAssigned and UnitGroupRolesAssigned(unit)
1700+
if (not role or role == "NONE") and UnitIsUnit and UnitIsUnit(unit, "player")
1701+
and GetSpecialization and GetSpecializationRole then
1702+
local spec = GetSpecialization()
1703+
if spec then role = GetSpecializationRole(spec) or role end
1704+
end
1705+
return role
1706+
end
1707+
16501708
-- Resolve the frame border colour: the static borderColor by default, or
16511709
-- (Stage 2.1+) the unit's class / role colour with its own alpha slider when
16521710
-- the canonical frameBorderColorSource picks one. Non-player / unknown-class
@@ -1701,17 +1759,10 @@ function DF:GetFrameBorderColor(frame, db)
17011759
if frame.dfIsTestFrame then
17021760
local testData = DF.GetTestUnitData and DF:GetTestUnitData(frame.index, frame.isRaidFrame)
17031761
role = testData and testData.role
1704-
elseif frame.unit and UnitExists(frame.unit) and UnitGroupRolesAssigned then
1705-
role = UnitGroupRolesAssigned(frame.unit)
1706-
-- UnitGroupRolesAssigned returns "NONE" outside instances where
1707-
-- roles aren't assigned (solo, world content). For the player,
1708-
-- fall back to spec role so role colour stays meaningful. Other
1709-
-- units expose no public spec API; they stay on picker fallback.
1710-
if (not role or role == "NONE") and UnitIsUnit and UnitIsUnit(frame.unit, "player")
1711-
and GetSpecialization and GetSpecializationRole then
1712-
local spec = GetSpecialization()
1713-
if spec then role = GetSpecializationRole(spec) end
1714-
end
1762+
else
1763+
-- Player falls back to the spec role when the group assigned none;
1764+
-- other units stay NONE and drop to the picker fallback below.
1765+
role = DF:GetUnitRole(frame.unit)
17151766
end
17161767
local c = rc and role and role ~= "NONE" and (rc[role] or rc[string.lower(role)])
17171768
if c then
@@ -2535,6 +2586,34 @@ function DF:DebugAuraFilters(unit)
25352586
o:Field("AuraUtil.ShouldDisplayBuff", hasSDB and "present" or "absent", hasSDB and "good" or "warn")
25362587
o:Field("AuraUtil.ForEachAura", hasFEA and "present" or "absent", hasFEA and "good" or "warn")
25372588

2589+
-- Which Edit Mode strategy is actually live. Deafening the container to
2590+
-- AURA_DATA_PROVIDER_SWITCH can only be PROVEN at runtime (it is a base widget
2591+
-- method on a forbidden-table object), so this reports the client's answer
2592+
-- rather than an assumption — see EDIT-MODE DEAFENING in Frames/AuraContainer.lua.
2593+
o:Section("Edit Mode isolation")
2594+
local ac = DF.AuraContainer
2595+
local deafOK = ac and ac._providerDeafOK
2596+
if not ac or deafOK == nil then
2597+
o:Field("strategy", "not probed yet (no container built)", "neutral")
2598+
elseif deafOK then
2599+
o:Field("strategy", "deafened container — rows keep live auras", "good")
2600+
else
2601+
o:Field("strategy", "rebirth fallback — rebuild on switch (OOC), hide in combat", "warn")
2602+
end
2603+
if ac and ac._providerDeafWhy then
2604+
o:Field("unregister probe", tostring(ac._providerDeafWhy), deafOK and "good" or "neutral")
2605+
end
2606+
-- Populated the first time Edit Mode is opened. QUEUED means the client deferred
2607+
-- our re-entrant switch to after the in-flight dispatch (safe, and the inline reset
2608+
-- gains nothing); NESTED means it dispatched re-entrantly (zero blip, but containers
2609+
-- the outer dispatch had not reached can strand on the sample source).
2610+
if ac and ac._inlineDispatch then
2611+
o:Field("inline reset dispatch", ac._inlineDispatch,
2612+
ac._inlineDispatch == "QUEUED" and "good" or "warn")
2613+
elseif ac then
2614+
o:Field("inline reset dispatch", "not observed yet (open Edit Mode once)", "neutral")
2615+
end
2616+
25382617
o:Section("ShouldDisplayBuff per aura")
25392618
if AuraUtil and AuraUtil.ForEachAura then
25402619
local rows = {}
@@ -3637,6 +3716,37 @@ DF._MainEventDispatcher = function(self, event, arg1)
36373716
DandersFramesCharDB.currentProfile = currentProfile
36383717
DandersFramesDB_v2.currentProfile = currentProfile
36393718

3719+
-- Settings-window geometry moves from db.party to account-wide
3720+
-- windowState (see DF:GetWindowState for why). Seed once from whichever
3721+
-- profile is active at this login -- that is the window the user last
3722+
-- sized and scaled, so it is the only correct source.
3723+
if not DandersFramesDB_v2.windowState then
3724+
local ws = {}
3725+
local src = DandersFramesDB_v2.profiles[currentProfile]
3726+
src = src and src.party
3727+
if type(src) == "table" then
3728+
ws.scale, ws.width, ws.height = src.guiScale, src.guiWidth, src.guiHeight
3729+
ws.point, ws.relPoint, ws.x, ws.y = src.guiPoint, src.guiRelPoint, src.guiX, src.guiY
3730+
end
3731+
DandersFramesDB_v2.windowState = ws
3732+
end
3733+
-- Clean up the legacy per-profile keys (no longer read anywhere). Same
3734+
-- shape as the languageOverride strip above: unconditional, so profiles
3735+
-- that were not the seed source are cleared too. Both modes -- only
3736+
-- db.party was ever read, but RaidDefaults is copied from PartyDefaults
3737+
-- so every profile carries a dead db.raid set as well.
3738+
for _, profile in pairs(DandersFramesDB_v2.profiles) do
3739+
if type(profile) == "table" then
3740+
for _, modeKey in ipairs({ "party", "raid" }) do
3741+
local m = profile[modeKey]
3742+
if type(m) == "table" then
3743+
m.guiScale, m.guiWidth, m.guiHeight = nil, nil, nil
3744+
m.guiPoint, m.guiRelPoint, m.guiX, m.guiY = nil, nil, nil, nil
3745+
end
3746+
end
3747+
end
3748+
end
3749+
36403750
DF.db = DandersFramesDB_v2.profiles[currentProfile]
36413751

36423752
-- Ensure both modes exist in current profile
@@ -4973,15 +5083,23 @@ DF._MainEventDispatcher = function(self, event, arg1)
49735083
local dbgWord, dbgRest = rawMsg:match("^%s*[Dd][Ee][Bb][Uu][Gg]%s+(%S+)%s*(.-)%s*$")
49745084
-- "on"/"off" are the logging toggle, not commands named on/off.
49755085
if dbgWord and dbgWord:lower() ~= "on" and dbgWord:lower() ~= "off" then
4976-
local dbgKey = DF.DebugSlashBySub[dbgWord:lower()]
5086+
local dbgLower = dbgWord:lower()
5087+
local dbgKey = DF.DebugSlashBySub[dbgLower]
49775088
-- Several debug tools live in the companion and register their
49785089
-- slashes only when it loads. If the word is unknown and the
49795090
-- companion is not in yet, load it and retry once -- otherwise
49805091
-- the first use of /df debug memtest fell through to the final
49815092
-- else and opened the settings window instead of the tool.
4982-
if not dbgKey and not DF._optionsAddonLoaded
5093+
--
5094+
-- ☠ DEBUG_SUB_KNOWN FIRST. A sub()-registered command is a branch
5095+
-- in THIS addon; it is recognised, it just is not in the slash
5096+
-- registry. Without this test every one of them read as unknown
5097+
-- and loaded the companion for nothing -- see the note at the
5098+
-- DEBUG_SUB_KNOWN declaration.
5099+
if not dbgKey and not DF.DEBUG_SUB_KNOWN[dbgLower]
5100+
and not DF._optionsAddonLoaded
49835101
and DF.EnsureOptionsLoaded and DF:EnsureOptionsLoaded() then
4984-
dbgKey = DF.DebugSlashBySub[dbgWord:lower()]
5102+
dbgKey = DF.DebugSlashBySub[dbgLower]
49855103
end
49865104
if dbgKey and SlashCmdList[dbgKey] then
49875105
SlashCmdList[dbgKey](dbgRest or "")
@@ -5176,15 +5294,14 @@ DF._MainEventDispatcher = function(self, event, arg1)
51765294
DF:ResetFullProfile()
51775295
elseif msg == "resetgui" then
51785296
-- Reset GUI scale, size, and position to defaults
5179-
if DF.db and DF.db.party then
5180-
DF.db.party.guiScale = 1.0
5181-
DF.db.party.guiWidth = 760
5182-
DF.db.party.guiHeight = 520
5183-
DF.db.party.guiPoint = nil
5184-
DF.db.party.guiRelPoint = nil
5185-
DF.db.party.guiX = nil
5186-
DF.db.party.guiY = nil
5187-
end
5297+
local ws = DF:GetWindowState()
5298+
ws.scale = 1.0
5299+
ws.width = 760
5300+
ws.height = 520
5301+
ws.point = nil
5302+
ws.relPoint = nil
5303+
ws.x = nil
5304+
ws.y = nil
51885305
if DF.GUIFrame then
51895306
DF.GUIFrame:ClearAllPoints()
51905307
DF.GUIFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)

0 commit comments

Comments
 (0)