perf: optimize spell and unit ID lookups with caching and fix range cache memory leaks

This commit is contained in:
Bluewhale1337
2026-10-02 12:17:29 +02:00
parent f4ba0d983d
commit 032c7571af
6 changed files with 64 additions and 43 deletions
+30 -17
View File
@@ -240,25 +240,38 @@ end
local HealBot_RaidUnitTokens = {}
for i=1, 40 do HealBot_RaidUnitTokens[i] = "raid"..i end
HealBot_NameToUnitID = {}
function HealBot_UpdateUnitIDCache()
HealBot_NameToUnitID = {}
local name = UnitName("player")
if name then HealBot_NameToUnitID[name] = "player" end
for i=1, 4 do
local unit = "party"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
unit = "partypet"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
end
local petName = UnitName("pet")
if petName then HealBot_NameToUnitID[petName] = "pet" end
for i=1, 40 do
local unit = "raid"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
unit = "raidpet"..i
name = UnitName(unit)
if name then HealBot_NameToUnitID[name] = unit end
end
end
-- HealBot_FindUnitID: Finds a unit token for a given player name.
function HealBot_FindUnitID(unitname)
local text;
if HealBot_Action_HealGroup then
for _,unit in ipairs(HealBot_Action_HealGroup) do
text = UnitName(unit);
if text and text==unitname then
return unit;
end
end
end
for i=1,40 do
local unit = HealBot_RaidUnitTokens[i];
text = UnitName(unit);
if text and text==unitname then
return unit;
end
end
return nil;
return HealBot_NameToUnitID[unitname]
end
-- HealBot_PlaySound: Plays an audio alert based on ID.
+2
View File
@@ -498,6 +498,7 @@ end
function HealBot_OnEvent_PartyMembersChanged(this)
HealBot_Model:PreserveStateByGUID()
HealBot_Integrations_PruneNampower()
if HealBot_UpdateUnitIDCache then HealBot_UpdateUnitIDCache() end
if HealBot_IsFighting then
HealBot_Action_PartyChanged()
end
@@ -557,6 +558,7 @@ end
function HealBot_OnEvent_SpellsChanged(this, arg1)
if arg1 then return; end
HealBot_AddDebug("HB: SpellsChanged");
if HealBot_CacheSpellIDs then HealBot_CacheSpellIDs() end
HealBot_SpellsInitFlag = 2;
end
+9 -5
View File
@@ -15,7 +15,11 @@ local _lastFrameTime = 0
function HealBot_Range_Check(unit, range)
local currentTime = GetTime()
if _lastFrameTime ~= currentTime then
for k in pairs(_rangeCache) do _rangeCache[k] = nil end
for r, cacheTable in pairs(_rangeCache) do
for u in pairs(cacheTable) do
cacheTable[u] = nil
end
end
_lastFrameTime = currentTime
end
@@ -24,9 +28,9 @@ function HealBot_Range_Check(unit, range)
range = 40;
end
local cacheKey = unit .. "_" .. range
if _rangeCache[cacheKey] ~= nil then
return _rangeCache[cacheKey]
_rangeCache[range] = _rangeCache[range] or {}
if _rangeCache[range][unit] ~= nil then
return _rangeCache[range][unit]
end
if ( unit == "player" ) then
@@ -72,6 +76,6 @@ function HealBot_Range_Check(unit, range)
end
end
_rangeCache[cacheKey] = return_val
_rangeCache[range][unit] = return_val
return return_val;
end
+18 -20
View File
@@ -34,28 +34,26 @@ function HealBot_GetSpellName(id)
return spellName .. " (" .. subSpellName .. ")";
end
HealBot_SpellNameToId = {}
function HealBot_CacheSpellIDs()
HealBot_SpellNameToId = {}
local id = 1
while true do
local spellName, subSpellName = GetSpellName(id, BOOKTYPE_SPELL)
if not spellName then break end
if subSpellName and subSpellName ~= "" then
HealBot_SpellNameToId[spellName .. " (" .. subSpellName .. ")"] = id
HealBot_SpellNameToId[spellName .. "(" .. subSpellName .. ")"] = id
end
HealBot_SpellNameToId[spellName] = id
id = id + 1
end
end
-- HealBot_GetSpellId: Internal utility: HealBot_GetSpellId
function HealBot_GetSpellId(spell)
local id, idd = 1, 0;
while true do
local spellName, subSpellName = GetSpellName(id, BOOKTYPE_SPELL);
if (spellName) then
if (spell == spellName .. " (" .. subSpellName .. ")") or (spell == spellName .. "(" .. subSpellName .. ")") then
return id;
end
if (spell == spellName) then
idd = id;
end
else
break
end
id = id + 1;
end
if idd > 0 then
return idd
else
return nil;
end
return HealBot_SpellNameToId[spell]
end
-- HealBot_CastSpellByName: Internal utility: HealBot_CastSpellByName
-1
View File
@@ -21,7 +21,6 @@ function HealBot_Integrations_Toggle()
HealBot_Integrations_UnitXP_Active = true;
HealBot_AddDebug("UnitXP Integration: ENABLED");
else
Look at the lines that need translation
HealBot_Integrations_UnitXP_Active = false;
HealBot_AddDebug("UnitXP Integration: DISABLED");
end
+5
View File
@@ -152,6 +152,11 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
* **Chat Announcements & Mouseover Casts:** Chat announcements are now correctly fired when using native Hovercasting (Mouseover). Additionally, added safety checks to prevent spamming chat announcements when accidentally clicking on a dead player (unless casting a resurrection spell).
* **New Priest Buff (Enlighten):** Added the custom "Enlighten" buff to Priest trackable buffs, complete with the `btnholyscriptures` icon on unit frames.
**1.3.4**
* **Performance: Spell Lookup Optimization:** Fixed a massive CPU drain and garbage generation issue where the entire spellbook was linearly scanned every frame per unit. Spell IDs are now cached via O(1) dictionary lookup on login and talent/spell changes.
* **Performance: Unit ID Lookup Optimization:** Eliminated heavy C-API calls to `UnitName()` during incoming heals by caching raid and party unit tokens in a fast O(1) hash table that updates on roster changes.
* **Performance: Range Cache GC Leak:** Fixed a continuous memory leak in the range checker caused by string concatenation (`unit .. "_" .. range`) running every frame. Range states are now stored in a nested numeric table cache.
* **Integrations Bug Fix:** Removed stray translation text from `HealBot_Integrations.lua` that caused Lua syntax errors on load.
**1.3.3**
* **Chat Panel Refactor:** Completely replaced the spell selection dropdowns in the Chat tab with manual text input boxes, allowing users to type exact spell names (with or without ranks) directly, matching the behavior of the key-bindings configuration. Fixed a string matching bug caused by Vanilla WoW's hidden trailing spaces when comparing spell names, ensuring that both rankless (e.g. `Flash Heal`) and ranked inputs trigger correctly.