diff --git a/HealBot.lua b/HealBot.lua index f2cbc62..7c37104 100644 --- a/HealBot.lua +++ b/HealBot.lua @@ -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. diff --git a/HealBot_Controller_Events.lua b/HealBot_Controller_Events.lua index 24f8983..71dfc9d 100644 --- a/HealBot_Controller_Events.lua +++ b/HealBot_Controller_Events.lua @@ -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 diff --git a/HealBot_Controller_Range.lua b/HealBot_Controller_Range.lua index 4ccb085..823a053 100644 --- a/HealBot_Controller_Range.lua +++ b/HealBot_Controller_Range.lua @@ -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 diff --git a/HealBot_Controller_Spells.lua b/HealBot_Controller_Spells.lua index b35b0cc..e6dd71a 100644 --- a/HealBot_Controller_Spells.lua +++ b/HealBot_Controller_Spells.lua @@ -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 diff --git a/HealBot_Integrations.lua b/HealBot_Integrations.lua index e45554f..42ac6c2 100644 --- a/HealBot_Integrations.lua +++ b/HealBot_Integrations.lua @@ -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 diff --git a/README.md b/README.md index e81c524..8658b72 100644 --- a/README.md +++ b/README.md @@ -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.