refactor: optimize event processing, move global UI buttons, and reorganize options layout

This commit is contained in:
Bluewhale1337
2026-07-21 11:21:35 +02:00
parent db07c467a3
commit 026d4093aa
8 changed files with 155 additions and 124 deletions
+15 -24
View File
@@ -30,9 +30,7 @@ function HealBot_OnLoad(this)
end) end)
HealBot_Model:RegisterObserver("EQUIPMENT_CHANGED", function(unitID) HealBot_Model:RegisterObserver("EQUIPMENT_CHANGED", function(unitID)
if unitID == "player" then if unitID == "player" then
HealBot_BonusScanner:ScanEquipment() HealBot_EquipChangeTimer = 1
HealBot_CalcEquipBonus = true;
HealBot_RecalcSpells();
end end
end) end)
end end
@@ -76,10 +74,20 @@ function HealBot_OnUpdate(this, arg1)
end end
-- Process Dirty Queue for MVC View -- Process Dirty Queue for MVC View
if next(HealBot_View_DirtyUnits) ~= nil then local unitID, _ = next(HealBot_View_DirtyUnits)
for unitID in pairs(HealBot_View_DirtyUnits) do while unitID do
HealBot_Action_RefreshButtons(unitID) HealBot_Action_RefreshButtons(unitID)
HealBot_View_DirtyUnits[unitID] = nil HealBot_View_DirtyUnits[unitID] = nil
unitID, _ = next(HealBot_View_DirtyUnits)
end
if HealBot_EquipChangeTimer > 0 then
HealBot_EquipChangeTimer = HealBot_EquipChangeTimer - arg1
if HealBot_EquipChangeTimer <= 0 then
HealBot_EquipChangeTimer = 0
HealBot_BonusScanner:ScanEquipment()
HealBot_CalcEquipBonus = true;
HealBot_RecalcSpells();
end end
end end
@@ -93,15 +101,7 @@ function HealBot_OnUpdate(this, arg1)
HealsIn_Timer = 0; HealsIn_Timer = 0;
end end
if HealBot_EquipChangeTimer > 0 then
HealBot_EquipChangeTimer = HealBot_EquipChangeTimer - arg1
if HealBot_EquipChangeTimer <= 0 then
HealBot_EquipChangeTimer = 0
HealBot_BonusScanner:ScanEquipment()
HealBot_CalcEquipBonus = true;
HealBot_RecalcSpells();
end
end
if HealBot_SpellsInitFlag > 1 then if HealBot_SpellsInitFlag > 1 then
HealBot_SpellsInitFlag = HealBot_SpellsInitFlag + 1; HealBot_SpellsInitFlag = HealBot_SpellsInitFlag + 1;
@@ -138,32 +138,24 @@ local HealBot_EventHandlers = {
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_RAGE"] = function(this, arg1) ["UNIT_RAGE"] = function(this, arg1)
if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_ENERGY"] = function(this, arg1) ["UNIT_ENERGY"] = function(this, arg1)
if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_DISPLAYPOWER"] = function(this, arg1) ["UNIT_DISPLAYPOWER"] = function(this, arg1)
if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_AURA"] = function(this, arg1) ["UNIT_AURA"] = function(this, arg1)
HealBot_Model:MarkAuraChanged(arg1) HealBot_Model:MarkAuraChanged(arg1)
@@ -321,7 +313,6 @@ end
function HealBot_OnEvent_UnitHealth(this, unit) function HealBot_OnEvent_UnitHealth(this, unit)
if (not HealBot_Heals[unit]) then return end if (not HealBot_Heals[unit]) then return end
HealBot_CheckCasting(unit); HealBot_CheckCasting(unit);
HealBot_RecalcHeals(unit);
if unit == HealBot_Action_TooltipUnit then if unit == HealBot_Action_TooltipUnit then
HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit); HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
end end
@@ -379,7 +370,7 @@ end
function HealBot_OnEvent_PlayerTargetChanged(this) function HealBot_OnEvent_PlayerTargetChanged(this)
if HealBot_Action_UnitButtons and HealBot_Action_UnitButtons["target"] then if HealBot_Action_UnitButtons and HealBot_Action_UnitButtons["target"] then
HealBot_Action_RefreshButtons("target"); HealBot_View_DirtyUnits["target"] = true
HealBot_OnEvent_UnitAura(nil, "target"); HealBot_OnEvent_UnitAura(nil, "target");
end end
end end
+1 -3
View File
@@ -593,9 +593,7 @@ function HealBot_InitSpells()
end end
id = id + 1; id = id + 1;
end end
if class == "PRIEST" or class == "DRUID" or class == "PALADIN" or class == "SHAMAN" then
HealBot_AddChat("Initiated HealBot_CurrentSpells with " .. cnt .. " Spells");
end
return cnt; return cnt;
end end
+1 -1
View File
@@ -234,7 +234,7 @@ function HealBot_Options_OnLoad(this)
table.insert(UISpecialFrames,this:GetName()); table.insert(UISpecialFrames,this:GetName());
-- Tabs -- Tabs
PanelTemplates_SetNumTabs(this,7); PanelTemplates_SetNumTabs(this,8);
this.selectedTab = 1; this.selectedTab = 1;
PanelTemplates_UpdateTabs(this); PanelTemplates_UpdateTabs(this);
HealBot_Options_ShowPanel(this.selectedTab); HealBot_Options_ShowPanel(this.selectedTab);
+2 -33
View File
@@ -94,7 +94,7 @@
<Frame name="HealBot_Options" toplevel="true" frameStrata="DIALOG" <Frame name="HealBot_Options" toplevel="true" frameStrata="DIALOG"
movable="true" parent="UIParent" enableMouse="true" hidden="true"> movable="true" parent="UIParent" enableMouse="true" hidden="true">
<Size> <Size>
<AbsDimension x="420" y="455"/> <AbsDimension x="480" y="455"/>
</Size> </Size>
<Anchors> <Anchors>
<Anchor point="CENTER"> <Anchor point="CENTER">
@@ -215,38 +215,7 @@
</Anchor> </Anchor>
</Anchors> </Anchors>
</Button> </Button>
<Button name="HealBot_Options_Defaults" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_DEFAULTS">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="-50" y="15"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>HealBot_Options_Defaults_OnClick(this)</OnClick>
</Scripts>
</Button>
<Button name="HealBot_Options_CloseButton" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_CLOSE">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="50" y="15"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
HideUIPanel(this:GetParent());
</OnClick>
</Scripts>
</Button>
</Frames> </Frames>
<Scripts> <Scripts>
<OnLoad>HealBot_Options_OnLoad(this);</OnLoad> <OnLoad>HealBot_Options_OnLoad(this);</OnLoad>
+32 -2
View File
@@ -265,8 +265,38 @@
</Scripts> </Scripts>
</CheckButton> </CheckButton>
<Button name="HealBot_Options_Defaults" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_DEFAULTS">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="-50" y="15"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>HealBot_Options_Defaults_OnClick(this)</OnClick>
</Scripts>
</Button>
<Button name="HealBot_Options_CloseButton" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_CLOSE">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="50" y="15"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
HideUIPanel(this:GetParent():GetParent());
</OnClick>
</Scripts>
</Button>
</Frames> </Frames>
</Frame> </Frame>
+54 -52
View File
@@ -266,9 +266,9 @@
<AbsDimension x="123" y="17" /> <AbsDimension x="123" y="17" />
</Size> </Size>
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarBRSpaceS" relativePoint="TOPLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarBCSpaceS" relativePoint="TOPRIGHT">
<Offset> <Offset>
<AbsDimension x="0" y="-35" /> <AbsDimension x="10" y="0" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
@@ -277,62 +277,14 @@
<OnValueChanged>HealBot_Options_FramePaddingS_OnValueChanged(this)</OnValueChanged> <OnValueChanged>HealBot_Options_FramePaddingS_OnValueChanged(this)</OnValueChanged>
</Scripts> </Scripts>
</Slider> </Slider>
<Slider name="HealBot_Options_BorderThicknessS" inherits="HealBot_Options_SliderTemplate">
<Size>
<AbsDimension x="123" y="17" />
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_FramePaddingS" relativePoint="TOPRIGHT">
<Offset>
<AbsDimension x="10" y="0" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>HealBot_Options_val_OnLoad(this,"Solid Border",1,10)</OnLoad>
<OnValueChanged>HealBot_Options_BorderThicknessS_OnValueChanged(this)</OnValueChanged>
</Scripts>
</Slider>
<Slider name="HealBot_Options_BarMaxRowsS" inherits="HealBot_Options_SliderTemplate">
<Size>
<AbsDimension x="123" y="17" />
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_FramePaddingS" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="0" y="-35" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>HealBot_Options_val_OnLoad(this,"Max Rows",0,40)</OnLoad>
<OnValueChanged>HealBot_Options_BarMaxRowsS_OnValueChanged(this)</OnValueChanged>
</Scripts>
</Slider>
<CheckButton name="HealBot_Options_GridOrientation" inherits="OptionsCheckButtonTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarMaxRowsS" relativePoint="TOPRIGHT">
<Offset>
<AbsDimension x="10" y="5" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Horizontal Grid");
</OnLoad>
<OnClick>
HealBot_Options_GridOrientation_OnClick(this);
</OnClick>
</Scripts>
</CheckButton>
<Slider name="HealBot_Options_BarAlpha" inherits="HealBot_Options_SliderTemplate"> <Slider name="HealBot_Options_BarAlpha" inherits="HealBot_Options_SliderTemplate">
<Size> <Size>
<AbsDimension x="123" y="17" /> <AbsDimension x="123" y="17" />
</Size> </Size>
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarMaxRowsS" relativePoint="TOPLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarBRSpaceS" relativePoint="TOPLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-35" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
@@ -409,6 +361,56 @@
</Scripts> </Scripts>
</Slider> </Slider>
<Slider name="HealBot_Options_BorderThicknessS" inherits="HealBot_Options_SliderTemplate">
<Size>
<AbsDimension x="123" y="17" />
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarAlphaInHeal" relativePoint="TOPRIGHT">
<Offset>
<AbsDimension x="10" y="0" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>HealBot_Options_val_OnLoad(this,"Solid Border",1,10)</OnLoad>
<OnValueChanged>HealBot_Options_BorderThicknessS_OnValueChanged(this)</OnValueChanged>
</Scripts>
</Slider>
<Slider name="HealBot_Options_BarMaxRowsS" inherits="HealBot_Options_SliderTemplate">
<Size>
<AbsDimension x="123" y="17" />
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_AbortBarSize" relativePoint="TOPRIGHT">
<Offset>
<AbsDimension x="10" y="0" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>HealBot_Options_val_OnLoad(this,"Max Rows",0,40)</OnLoad>
<OnValueChanged>HealBot_Options_BarMaxRowsS_OnValueChanged(this)</OnValueChanged>
</Scripts>
</Slider>
<CheckButton name="HealBot_Options_GridOrientation" inherits="OptionsCheckButtonTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarMaxRowsS" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="-5" y="-10" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Horizontal Grid");
</OnLoad>
<OnClick>
HealBot_Options_GridOrientation_OnClick(this);
</OnClick>
</Scripts>
</CheckButton>
<Button name="HealBot_EnTextColorpickb"> <Button name="HealBot_EnTextColorpickb">
<Size> <Size>
<AbsDimension x="87" y="20"/> <AbsDimension x="87" y="20"/>
+46 -7
View File
@@ -335,6 +335,41 @@ function HealBot_Action_PositionButton(button, OsetX, OsetY, bwidth, bheight, ch
return OsetY; return OsetY;
end end
function HealBot_Action_PositionButtonHorizontal(button, OsetX, OsetY, bwidth, bheight, checked, header)
local bcspace = HealBot_Config.bcspace[HealBot_Config.Current_Skin] or 3;
if header then
headerno = headerno + 1;
local headerobj = getglobal("HealBot_Action_Header" .. headerno);
headerobj:SetText(header)
headerobj:Show();
headerobj:ClearAllPoints();
headerobj:SetHeight(bheight);
headerobj:SetWidth(bwidth);
headerobj:SetPoint("TOPLEFT", "HealBot_Action", "TOPLEFT", OsetX, -OsetY);
headerobj:Disable();
OsetX = OsetX + bwidth + bcspace;
else
local unit = button.unit;
button:SetText(" ");
if (HealBot_MayHeal(unit)) then
button:Show();
button:ClearAllPoints();
button:SetHeight(bheight);
if checked then
button:SetWidth(bwidth - 14);
button:SetPoint("TOPLEFT", "HealBot_Action", "TOPLEFT", OsetX + 14, -OsetY);
else
button:SetWidth(bwidth);
button:SetPoint("TOPLEFT", "HealBot_Action", "TOPLEFT", OsetX, -OsetY);
end
OsetX = OsetX + bwidth + bcspace;
else
button:Hide();
end
end
return OsetX;
end
function HealBot_Action_SetHeightWidth(width, height, bwidth) function HealBot_Action_SetHeightWidth(width, height, bwidth)
if HealBot_ActionHeight then if HealBot_ActionHeight then
HealBot_Action:SetHeight(HealBot_ActionHeight); HealBot_Action:SetHeight(HealBot_ActionHeight);
@@ -781,6 +816,8 @@ function HealBot_Action_PartyChanged()
local h = 1; local h = 1;
local i = 0; local i = 0;
local z = 1; local z = 1;
local brspace = HealBot_Config.brspace[HealBot_Config.Current_Skin] or 3;
local bcspace = HealBot_Config.bcspace[HealBot_Config.Current_Skin] or 3;
local limit = math.ceil((numBars) / cols) local limit = math.ceil((numBars) / cols)
if orientation == 1 and maxRows > 0 then if orientation == 1 and maxRows > 0 then
@@ -805,12 +842,12 @@ function HealBot_Action_PartyChanged()
OffsetX = OffsetX + bwidth + bcspace; OffsetX = OffsetX + bwidth + bcspace;
end end
else else
OffsetY = HealBot_Action_PositionButton(nil, OffsetX, OffsetY, bwidth, bheight, checked, header); OffsetX = HealBot_Action_PositionButtonHorizontal(nil, OffsetX, OffsetY, bwidth, bheight, checked, header);
if h == limit and z < numBars then if h == limit and z < numBars then
h = 0; h = 0;
if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end
OffsetX = bpadding; OffsetX = bpadding;
OffsetY = OffsetY + bheight + bcspace; OffsetY = OffsetY + bheight + brspace;
end end
end end
h = h + 1; h = h + 1;
@@ -828,13 +865,12 @@ function HealBot_Action_PartyChanged()
OffsetX = OffsetX + bwidth + bcspace; OffsetX = OffsetX + bwidth + bcspace;
end end
else else
button:SetPoint("TOPLEFT", "HealBot_Action", "TOPLEFT", OffsetX, -OffsetY); OffsetX = HealBot_Action_PositionButtonHorizontal(button, OffsetX, OffsetY, bwidth, bheight, checked, nil);
OffsetX = OffsetX + bwidth + bcspace;
if h == limit and z < numBars then if h == limit and z < numBars then
h = 0; h = 0;
if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end
OffsetX = bpadding; OffsetX = bpadding;
OffsetY = OffsetY + bheight + bcspace; OffsetY = OffsetY + bheight + brspace;
end end
end end
@@ -858,8 +894,11 @@ function HealBot_Action_PartyChanged()
else else
if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end
-- In horizontal mode, OffsetY represents the active row. We need to measure total height. -- In horizontal mode, OffsetY represents the active row. We need to measure total height.
MaxOffsetY = OffsetY + bheight + bcspace MaxOffsetY = OffsetY + bheight + brspace
OffsetX = MaxOffsetX -- For setting the final width OffsetX = MaxOffsetX
if numBars > 0 then
OffsetX = OffsetX - bwidth - bcspace
end
end end
if HealBot_Config.HideOptions == 1 then if HealBot_Config.HideOptions == 1 then
+2
View File
@@ -44,6 +44,8 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
**v1.5.1** **v1.5.1**
* **Event Loop Decoupling:** Ripped out redundant synchronous UI redraws that were bypassed by the new MVC architecture. High-frequency events (mana regen, health ticks) now fully rely on the `HealBot_OnUpdate` dirty queue, severely reducing CPU bottlenecks.
* **Combat UI Optimizations:** Removed unnecessary full spell recalculations when dropping combat, preventing client stutter after every mob kill.
* **Memory Optimization:** Fixed severe Lua garbage collection spikes during UI reloads by preventing full party layout rebuilds on `PLAYER_TARGET_CHANGED`, and cached dynamic string concatenations directly to unit frames to eliminate memory leakage on high frequency UI refreshes. * **Memory Optimization:** Fixed severe Lua garbage collection spikes during UI reloads by preventing full party layout rebuilds on `PLAYER_TARGET_CHANGED`, and cached dynamic string concatenations directly to unit frames to eliminate memory leakage on high frequency UI refreshes.
* **Mana Validation Fix:** Removed artificial spell mana gating, fixing an issue where low-mana spells disappeared from tooltips and couldn't be cast. WoW's native mana validation now correctly processes 0-cost buffs (e.g. Clearcasting, Inner Focus) while turning low-mana tooltip spells red. * **Mana Validation Fix:** Removed artificial spell mana gating, fixing an issue where low-mana spells disappeared from tooltips and couldn't be cast. WoW's native mana validation now correctly processes 0-cost buffs (e.g. Clearcasting, Inner Focus) while turning low-mana tooltip spells red.
* **Self-Buff Tracking:** Fixed a bug where "Self Only" buff tracking incorrectly excluded the player when represented by party or raid frames instead of the standard "player" unit ID. * **Self-Buff Tracking:** Fixed a bug where "Self Only" buff tracking incorrectly excluded the player when represented by party or raid frames instead of the standard "player" unit ID.