mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-23 16:16:56 +00:00
unitframes: compare indicator auras without case folding
The indicator scan lowercased the aura's name and icon on every aura of every unit, and SetupBuffIndicators lowercased the other side to match. Both sides come out of the same DBC records byte for byte, so the comparison already held without any of it: the aura's name and icon are Spell.dbc's localized name and SpellIcon.dbc's path (aura/Data.cpp fills one struct and emits it as either the AuraData table or the positional UnitAura tuple), and the indicator record reads those same two fields through C_Spell.GetSpellName / GetSpellTexture. So this was two string allocations per aura per scan to reach a result it already had -- and on Lua 5.0 that is an allocate-and-hash each time, since the VM interns even when the string exists. RefreshUnit runs this for every unit frame, which in a raid is 40 frames against up to 32 auras each. Checked every rank of all 65 indicator spells in Spell.dbc: name and icon are byte-identical across a spell's whole ladder, no case or spelling drift, so nothing depended on the fold. It also drops a crash path. aura/Data.cpp yields nil for the icon when a spell's SpellIconID is 0, and icon:lower() would have errored on that; name was guarded on the line above but icon never was. A raw compare is just false. The equality is now load-bearing, so AddIndicator's comment says to feed it spell ids and never a hand-written name or icon path -- a literal "interface\icons\foo" in that table would silently match nothing.
This commit is contained in:
+8
-4
@@ -48,6 +48,12 @@ end, true)
|
||||
-- Every rank of a spell carries the same name and icon, so one id per buff
|
||||
-- covers the whole rank ladder. Ids missing from this client resolve to nil and
|
||||
-- drop out of the list. 'predict' names the libpredict key of a HoT.
|
||||
--
|
||||
-- Both fields are stored raw, and RefreshUnit compares them raw. The aura's
|
||||
-- name and icon and these come out of the same DBC records byte for byte --
|
||||
-- Spell.dbc's localized name, SpellIcon.dbc's path -- so case folding either
|
||||
-- side would only burn a string per aura per scan. Feed this ids, never
|
||||
-- hand-written names or icon paths, or that equality quietly stops holding.
|
||||
local indicator_cache = {}
|
||||
local function AddIndicator(indicators, spellId, predict)
|
||||
local record = indicator_cache[spellId]
|
||||
@@ -55,7 +61,7 @@ local function AddIndicator(indicators, spellId, predict)
|
||||
local name = C_Spell.GetSpellName(spellId)
|
||||
local icon = name and C_Spell.GetSpellTexture(spellId)
|
||||
-- cache misses as false, so an absent spell is only looked up once
|
||||
record = icon and { name = name:lower(), icon = icon:lower(), predict = predict } or false
|
||||
record = icon and { name = name, icon = icon, predict = predict } or false
|
||||
indicator_cache[spellId] = record
|
||||
end
|
||||
|
||||
@@ -1969,12 +1975,10 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
for i=1,n do
|
||||
local name, icon, count, _, _, expirationTime = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if not name then break end
|
||||
local texLower = icon:lower()
|
||||
local nameLower = name:lower()
|
||||
local timeleft = expirationTime > 0 and (expirationTime - GetTime()) or nil
|
||||
|
||||
for _, filter in pairs(unit.indicators) do
|
||||
if filter.icon == texLower and filter.name == nameLower then
|
||||
if filter.icon == icon and filter.name == name then
|
||||
if filter.predict then
|
||||
local start, duration, prediction = libpredict:GetHotDuration(unitstr, filter.predict)
|
||||
pfUI.uf:AddIcon(unit, pos, icon, timeleft or prediction, count, tonumber(start), tonumber(duration))
|
||||
|
||||
Reference in New Issue
Block a user