refactor: implement table pooling and out-of-combat cleanup to reduce memory allocation overhead and garbage collection pressure

This commit is contained in:
Bluewhale1337
2026-09-06 23:22:43 +02:00
parent 1ef79cfcd1
commit 7d910eadd2
3 changed files with 48 additions and 12 deletions
+12 -2
View File
@@ -3,6 +3,8 @@
HealBot_View_DirtyUnits = {}
HealBot_View_DirtyPower = {}
local unitsToRefresh = {}
local powerToRefresh = {}
local HealBot_Timer1, HealsIn_Timer = 0, 0;
HealBot_LastModState = ""
@@ -152,7 +154,7 @@ function HealBot_OnUpdate(this, arg1)
end
-- Process Dirty Queue for MVC View
local unitsToRefresh = {}
for k in pairs(unitsToRefresh) do unitsToRefresh[k] = nil end
for unitID in pairs(HealBot_View_DirtyUnits) do
unitsToRefresh[unitID] = true
HealBot_View_DirtyUnits[unitID] = nil
@@ -162,7 +164,7 @@ function HealBot_OnUpdate(this, arg1)
HealBot_Action_Refresh(unitID)
end
local powerToRefresh = {}
for k in pairs(powerToRefresh) do powerToRefresh[k] = nil end
for unitID in pairs(HealBot_View_DirtyPower) do
powerToRefresh[unitID] = true
HealBot_View_DirtyPower[unitID] = nil
@@ -490,6 +492,14 @@ end
function HealBot_OnEvent_PlayerRegenEnabled(this)
HealBot_IsFighting = false;
HealBot_Delay_RecalcParty = 1;
if HealBot_IncomingHealers then
for sender, data in pairs(HealBot_IncomingHealers) do
if not HealBot_FindUnitID(sender) then
HealBot_IncomingHealers[sender] = nil
end
end
end
end
-- HealBot_OnEvent_PlayerTargetChanged: Internal utility: HealBot_OnEvent_PlayerTargetChanged
+32 -8
View File
@@ -1,6 +1,13 @@
-- HealBot_Model.lua
-- Centralized Data Store and Observer System for HealBotBlue
local pool_oldGUIDs = {}
local pool_newUnitForGUID = {}
local pool_stateSwaps = {}
local pool_iconSwaps = {}
local pool_missingBuffSwaps = {}
local pool_debuffSwaps = {}
-- Safe local wrappers to prevent native UIDropDownMenu concatenation crashes
-- when setting selected values on closed dropdowns during initialization.
function HealBot_UIDropDownMenu_SetSelectedID(frame, id, useValue)
@@ -180,14 +187,16 @@ end
function HealBot_Model:PreserveStateByGUID()
if not (HealBot_Integrations_SuperWoW_Active or HealBot_Integrations_ClassicAPI_Active) or not HealBot_GetUnitGUID then return end
local oldGUIDs = {}
for k in pairs(pool_oldGUIDs) do pool_oldGUIDs[k] = nil end
local oldGUIDs = pool_oldGUIDs
for unit, guid in pairs(self.unitGUIDs) do
if string.find(unit, "^party") or string.find(unit, "^raid") or unit == "player" or unit == "pet" then
oldGUIDs[unit] = guid
end
end
local newUnitForGUID = {}
for k in pairs(pool_newUnitForGUID) do pool_newUnitForGUID[k] = nil end
local newUnitForGUID = pool_newUnitForGUID
-- Scan the new roster
for _, unit in ipairs(self.partyMembers) do
local guid = HealBot_GetUnitGUID(unit)
@@ -206,10 +215,14 @@ function HealBot_Model:PreserveStateByGUID()
end
end
local stateSwaps = {}
local iconSwaps = {}
local missingBuffSwaps = {}
local debuffSwaps = {}
for k in pairs(pool_stateSwaps) do pool_stateSwaps[k] = nil end
local stateSwaps = pool_stateSwaps
for k in pairs(pool_iconSwaps) do pool_iconSwaps[k] = nil end
local iconSwaps = pool_iconSwaps
for k in pairs(pool_missingBuffSwaps) do pool_missingBuffSwaps[k] = nil end
local missingBuffSwaps = pool_missingBuffSwaps
for k in pairs(pool_debuffSwaps) do pool_debuffSwaps[k] = nil end
local debuffSwaps = pool_debuffSwaps
for oldUnit, guid in pairs(oldGUIDs) do
local newUnit = newUnitForGUID[guid]
@@ -231,11 +244,22 @@ function HealBot_Model:PreserveStateByGUID()
for targetUnit, stateData in pairs(stateSwaps) do
-- Deep copy to prevent memory aliasing
self.units[targetUnit] = {}
if not self.units[targetUnit] then
self.units[targetUnit] = { icons = {} }
end
local targetIcons = self.units[targetUnit].icons
if not targetIcons then targetIcons = {} end
for k in pairs(targetIcons) do targetIcons[k] = nil end
for k in pairs(self.units[targetUnit]) do self.units[targetUnit][k] = nil end
for k, v in pairs(stateData) do
if k ~= "icons" then
self.units[targetUnit][k] = v
end
self.units[targetUnit].icons = {}
end
self.units[targetUnit].icons = targetIcons
if HealBot_UnitIcons and iconSwaps[targetUnit] then
if not HealBot_UnitIcons[targetUnit] then HealBot_UnitIcons[targetUnit] = {} end
+2
View File
@@ -50,6 +50,8 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
### Change Log
**v1.7.1**
* **Performance Fix - Table Pooling** - Fixed massive Vanilla Lua 5.0 garbage collection memory leaks caused by unbounded table allocations in high-frequency update loops (e.g., `OnUpdate` and `PreserveStateByGUID`). Moved tables to file-local scope and implemented inline clearing.
* **Performance Fix - OOC Cleanup** - Added an out-of-combat garbage collection hook (`PLAYER_REGEN_ENABLED`) to purge disconnected senders from the `HealBot_IncomingHealers` global table, preventing memory bloat during prolonged play sessions.
* **Bug Fix - Incoming Heals Comms** - Fixed a regex string parsing bug that caused incoming heals from other HealBot instances to drop if a unit's name contained non-alphabetic characters (e.g. dashes or spaces in pet names).
* **Feature - Standard HealComm Sync** - Implemented lightweight parsing of the standard `HealComm` addon channel. HealBot now perfectly syncs incoming heals with modern raid frames like Luna, Grid, and pfUI, while retaining backwards compatibility with older versions of HealBot.
* **UI Update - Raid Marks** - Anchored raid target icons to top of unit frames instead of center.