mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-12 00:20:01 +00:00
auras: scan through GetAuraSlots instead of by-index loops
Every aura scan loop (unit frame buffs/debuffs, dispel indicators, buff and custom indicators, player buff frame, buffwatch bars, tooltip buff row) now enumerates a unit's auras once with C_UnitAuras.GetAuraSlots and reads each aura by slot id via the positional C_UnitAuras.UnitAuraBySlot. The by-index getters re-walk the aura array from slot 0 on every call, so a per-button loop over them was quadratic in the aura count; one enumeration plus a by-slot read per aura is linear. pfUI.api.ScanAuraSlots(unit, filter, buf, max) wraps GetAuraSlots' fill-a- table form (table as the 5th argument) so no vararg Lua frame is involved: Lua 5.0 allocates an `arg` table for every vararg call, which showed up as nameplate OnUpdate/OnEvent memory growth in the first cut of this change. Single by-index reads in tooltip and click handlers are unchanged (one call each, and SetUnitAura takes the same index). Requires the ClassicAPI build that adds GetAuraSlots' fill form; on an older DLL the 5th argument is ignored and ScanAuraSlots would read the first slot id as the count.
This commit is contained in:
@@ -116,6 +116,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
-- Reusable per-plate debuff display buffer (avoid GC churn from per-call table creation)
|
||||
local debuffDisplayBuf = {} -- [i] = { effect, texture, stacks, dtype, duration, timeleft }
|
||||
for i = 1, 16 do debuffDisplayBuf[i] = {} end
|
||||
local auraSlots = {} -- reusable GetAuraSlots buffer for the per-plate aura scan
|
||||
local threatMemory = {} -- guid -> true if mob had player targeted
|
||||
-- local debuffSeen = {} -- reusable table for debuff tracking (avoid GC churn)
|
||||
|
||||
@@ -1312,11 +1313,12 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
if unitstr then
|
||||
local filter = cfg.owndebuffs and "HARMFUL|PLAYER" or "HARMFUL"
|
||||
local now = GetTime()
|
||||
-- positional UnitAura writes straight into the reusable buffer, so the
|
||||
-- per-plate scan allocates nothing (no per-aura table, no result array)
|
||||
local i = 1
|
||||
while debuffCount < 16 do
|
||||
local aname, icon, count, dispelType, duration, expirationTime = C_UnitAuras.UnitAura(unitstr, i, filter)
|
||||
-- one GetAuraSlots enumeration, then positional by-slot reads straight
|
||||
-- into the reusable buffer: the per-plate scan allocates nothing (no
|
||||
-- per-aura table, no result array) and walks the aura array once
|
||||
local n = ScanAuraSlots(unitstr, filter, auraSlots, 16)
|
||||
for i = 1, n do
|
||||
local aname, icon, count, dispelType, duration, expirationTime = C_UnitAuras.UnitAuraBySlot(unitstr, auraSlots[i])
|
||||
if not aname then break end
|
||||
debuffCount = debuffCount + 1
|
||||
local b = debuffDisplayBuf[debuffCount]
|
||||
@@ -1326,7 +1328,6 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
b.dtype = dispelType
|
||||
b.duration = duration
|
||||
b.timeleft = (expirationTime and expirationTime > 0) and (expirationTime - now) or nil
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
for i = 1, 16 do
|
||||
|
||||
Reference in New Issue
Block a user