From ce594af5fae1124d0a51ffe2f98fb30698b46f76 Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 10:36:54 +0200 Subject: [PATCH 1/3] fix: memory leak in UnitAura and bump version to 1.4.2 --- HealBot_Controller_Aura.lua | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/HealBot_Controller_Aura.lua b/HealBot_Controller_Aura.lua index b527d95..9ae5d5e 100644 --- a/HealBot_Controller_Aura.lua +++ b/HealBot_Controller_Aura.lua @@ -115,23 +115,27 @@ function HealBot_CheckBuffs(unit) end end +local HealBot_TrackedHoTs = { + ["Interface\\Icons\\Spell_Holy_Renew"] = true, + ["Interface\\Icons\\Spell_Nature_Rejuvenation"] = true, + ["Interface\\Icons\\Spell_Nature_ResistNature"] = true, + ["Interface\\Icons\\Spell_Holy_PowerWordShield"] = true, + ["Interface\\Icons\\Spell_Holy_SealOfProtection"] = true, + ["Interface\\Icons\\Spell_Holy_Excorcism"] = true, + ["Interface\\Icons\\btnholyscriptures"] = true, +} + function HealBot_OnEvent_UnitAura(this, unit) local DebuffType; if HealBot_Heals[unit] and unit ~= "target" then - HealBot_UnitIcons[unit] = {} + if not HealBot_UnitIcons[unit] then + HealBot_UnitIcons[unit] = {} + end + for j = 1, 5 do + HealBot_UnitIcons[unit][j] = nil + end local iconCount = 0 - - local HealBot_TrackedHoTs = { - ["Interface\\Icons\\Spell_Holy_Renew"] = true, - ["Interface\\Icons\\Spell_Nature_Rejuvenation"] = true, - ["Interface\\Icons\\Spell_Nature_ResistNature"] = true, - ["Interface\\Icons\\Spell_Holy_PowerWordShield"] = true, - ["Interface\\Icons\\Spell_Holy_SealOfProtection"] = true, - ["Interface\\Icons\\Spell_Holy_Excorcism"] = true, - ["Interface\\Icons\\btnholyscriptures"] = true, - } - local i = 1; while true do local debuff, tmp, debuff_type = UnitDebuff(unit, i, 1) From 1334fc09bf1e6cd36b08c5ebfa1c654f67d570b6 Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 12:27:51 +0200 Subject: [PATCH 2/3] perf: replace table.foreach with pairs loops to avoid GC spikes during combat --- HealBot_Action.lua | 8 ++++---- HealBot_View_Layout.lua | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/HealBot_Action.lua b/HealBot_Action.lua index 052a0c6..4d32195 100644 --- a/HealBot_Action.lua +++ b/HealBot_Action.lua @@ -22,9 +22,9 @@ function HealBot_ShouldHeal(unit) end function HealBot_Action_ShouldHealSome() - return table.foreach(HealBot_Action_HealButtons, function (index,button) + for index, button in pairs(HealBot_Action_HealButtons) do if (HealBot_ShouldHeal(button.unit)) then return button.unit; end - end); + end end function HealBot_MustHeal(unit) @@ -32,9 +32,9 @@ function HealBot_MustHeal(unit) end function HealBot_Action_MustHealSome() - return table.foreach(HealBot_Action_HealButtons, function (index,button) + for index, button in pairs(HealBot_Action_HealButtons) do if (HealBot_MustHeal(button.unit)) then return button.unit; end - end); + end end function HealBot_GetRezSpellForClass() diff --git a/HealBot_View_Layout.lua b/HealBot_View_Layout.lua index 9884ca8..40ef3c9 100644 --- a/HealBot_View_Layout.lua +++ b/HealBot_View_Layout.lua @@ -255,9 +255,9 @@ function HealBot_Action_EnableButton(button) end function HealBot_Action_EnableButtons() - table.foreach(HealBot_Action_HealButtons, function (index, button) - HealBot_Action_EnableButton(button); - end); + for index, button in pairs(HealBot_Action_HealButtons) do + HealBot_Action_EnableButton(button) + end end function HealBot_Action_RefreshButton(button) @@ -285,13 +285,13 @@ end function HealBot_Action_RefreshButtons(unit) if unit and HealBot_Action_UnitButtons[unit] then - table.foreach(HealBot_Action_UnitButtons[unit], function (index, button) - HealBot_Action_RefreshButton(button); - end); + for index, button in pairs(HealBot_Action_UnitButtons[unit]) do + HealBot_Action_RefreshButton(button) + end else - table.foreach(HealBot_Action_HealButtons, function (index, button) - HealBot_Action_RefreshButton(button); - end); + for index, button in pairs(HealBot_Action_HealButtons) do + HealBot_Action_RefreshButton(button) + end end end @@ -748,7 +748,7 @@ function HealBot_Action_PartyChanged() local i = 0; local z = 1; - table.foreach(HealBot_Action_HealButtons, function (index, button) + for index, button in pairs(HealBot_Action_HealButtons) do i = i + 1; local checked = false; local header; @@ -787,7 +787,7 @@ function HealBot_Action_PartyChanged() bar:SetScale(barScale); bar2:SetHeight(bheight); HealBot_Action_SetTexture(bar2, btexture); - end); + end if MaxOffsetY < OffsetY then MaxOffsetY = OffsetY; end From c8e62fe80ea64bfaf7bd7b7522c7736d9e3af07a Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 12:36:38 +0200 Subject: [PATCH 3/3] docs: restore v1.4.2 changelog entry --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4b4049a..5a26b81 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\ ### Change Log + +**v1.4.2** +* **Memory Optimization:** Fixed a significant memory leak where tracking tables were being repeatedly allocated every tick during aura scanning, and replaced `table.foreach` with pairs loops to avoid GC spikes during combat. + **v1.4.1** * **Talent-based Healing Calculations:** Implemented dynamic spell healing calculations for Druid, Priest, and Paladin classes based on talents. * **Modifier Key Polling:** Replaced MODIFIER_STATE_CHANGED event with polling in HealBot_OnUpdate to track modifier keys reliably.