From 3148e80cc07b46a35505f864318f322707998148 Mon Sep 17 00:00:00 2001 From: Vati Date: Mon, 2 Mar 2026 13:17:16 +0400 Subject: [PATCH] perf: improvement --- Core/Database.lua | 4 +-- Core/Tooltip.lua | 72 +++++++++++++++++++++++++++++--------------- Guda.toc | 2 +- UI/BagFrame.lua | 14 +++++++-- UI/ItemButton.lua | 26 ++++++---------- UI/SettingsPopup.lua | 4 +-- 6 files changed, 73 insertions(+), 49 deletions(-) diff --git a/Core/Database.lua b/Core/Database.lua index 9ca0cfd..0d3bdf5 100644 --- a/Core/Database.lua +++ b/Core/Database.lua @@ -37,7 +37,7 @@ function DB:Initialize() bankColumns = 10, sortMethod = "quality", -- quality, name, type iconSize = 37, - iconSpacing = 3, + iconSpacing = 4, iconFontSize = 12, showQualityBorderEquipment = true, showQualityBorderOther = true, @@ -101,7 +101,7 @@ function DB:Initialize() Guda_CharDB.settings.iconSize = 37 end if not Guda_CharDB.settings.iconSpacing then - Guda_CharDB.settings.iconSpacing = 3 + Guda_CharDB.settings.iconSpacing = 4 end if not Guda_CharDB.settings.iconFontSize then Guda_CharDB.settings.iconFontSize = 12 diff --git a/Core/Tooltip.lua b/Core/Tooltip.lua index bd790ab..61ee8cb 100644 --- a/Core/Tooltip.lua +++ b/Core/Tooltip.lua @@ -4,6 +4,11 @@ local addon = Guda local Tooltip = {} addon.Modules.Tooltip = Tooltip +-- Reusable tables to avoid per-mouseover garbage (cleared before each use) +local _characterCounts = {} +local _breakdownParts = {} +local _charParts = {} + --============================================================================= -- Item Counting Helper Functions (extracted for clarity and reuse) --============================================================================= @@ -262,9 +267,13 @@ function Tooltip:AddInventoryInfo(tooltip, link) local totalBank = 0 local totalMail = 0 local totalEquipped = 0 - local characterCounts = {} local hasAnyItems = false + -- Reuse module-level tables (clear before use to avoid per-call allocation) + local characterCounts = _characterCounts + for k in pairs(characterCounts) do characterCounts[k] = nil end + local ccIndex = 0 + local currentPlayerName = addon.Modules.DB:GetPlayerFullName() local currentRealm = GetRealmName() @@ -281,19 +290,27 @@ function Tooltip:AddInventoryInfo(tooltip, link) totalBank = totalBank + bankCount totalMail = totalMail + mailCount totalEquipped = totalEquipped + equippedCount - table.insert(characterCounts, { - name = charData.name or charName, - classToken = charData.classToken, - bagCount = bagCount, - bankCount = bankCount, - mailCount = mailCount, - equippedCount = equippedCount, - isCurrent = isCurrentChar - }) + ccIndex = ccIndex + 1 + -- Reuse existing sub-table or create one that persists + if not characterCounts[ccIndex] then + characterCounts[ccIndex] = {} + end + local entry = characterCounts[ccIndex] + entry.name = charData.name or charName + entry.classToken = charData.classToken + entry.bagCount = bagCount + entry.bankCount = bankCount + entry.mailCount = mailCount + entry.equippedCount = equippedCount + entry.isCurrent = isCurrentChar end end -- If charData is not a table (string, number, etc.), just skip it end + -- Clean up any stale entries beyond current count + for i = ccIndex + 1, table.getn(characterCounts) do + characterCounts[i] = nil + end local totalCount = totalBags + totalBank + totalMail + totalEquipped @@ -305,16 +322,18 @@ function Tooltip:AddInventoryInfo(tooltip, link) -- Inventory label in exact bag frame title color tooltip:AddLine("|cFFFFD200Inventory|r") - -- Total line with cyan label and white count + -- Total line with cyan label and white count (reuse module-level table) local totalText = "|cFF00FFFFTotal|r: |cFFFFFFFF" .. totalCount .. "|r" - local breakdownParts = {} - if totalBags > 0 then table.insert(breakdownParts, "|cFF00FFFFBags|r: |cFFFFFFFF" .. totalBags .. "|r") end - if totalBank > 0 then table.insert(breakdownParts, "|cFF00FFFFBank|r: |cFFFFFFFF" .. totalBank .. "|r") end - if totalMail > 0 then table.insert(breakdownParts, "|cFF00FFFFMail|r: |cFFFFFFFF" .. totalMail .. "|r") end - if totalEquipped > 0 then table.insert(breakdownParts, "|cFF00FFFFEquipped|r: |cFFFFFFFF" .. totalEquipped .. "|r") end - + local breakdownParts = _breakdownParts + local bpIndex = 0 + if totalBags > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFBags|r: |cFFFFFFFF" .. totalBags .. "|r" end + if totalBank > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFBank|r: |cFFFFFFFF" .. totalBank .. "|r" end + if totalMail > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFMail|r: |cFFFFFFFF" .. totalMail .. "|r" end + if totalEquipped > 0 then bpIndex = bpIndex + 1; breakdownParts[bpIndex] = "|cFF00FFFFEquipped|r: |cFFFFFFFF" .. totalEquipped .. "|r" end + for i = bpIndex + 1, table.getn(breakdownParts) do breakdownParts[i] = nil end + local breakdownText = "" - if table.getn(breakdownParts) > 0 then + if bpIndex > 0 then breakdownText = "(" .. table.concat(breakdownParts, " | ") .. ")" end tooltip:AddDoubleLine(totalText, breakdownText, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0) @@ -326,25 +345,28 @@ function Tooltip:AddInventoryInfo(tooltip, link) return a.name < b.name end) + -- Reuse module-level parts table for per-character breakdown + local parts = _charParts for _, charInfo in ipairs(characterCounts) do local r, g, b = GetClassColor(charInfo.classToken) - local countText = "" + local pIndex = 0 - local parts = {} if charInfo.bagCount > 0 then - table.insert(parts, "|cFF00FFFFBags|r: |cFFFFFFFF" .. charInfo.bagCount .. "|r") + pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFBags|r: |cFFFFFFFF" .. charInfo.bagCount .. "|r" end if charInfo.bankCount > 0 then - table.insert(parts, "|cFF00FFFFBank|r: |cFFFFFFFF" .. charInfo.bankCount .. "|r") + pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFBank|r: |cFFFFFFFF" .. charInfo.bankCount .. "|r" end if charInfo.mailCount > 0 then - table.insert(parts, "|cFF00FFFFMail|r: |cFFFFFFFF" .. charInfo.mailCount .. "|r") + pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFMail|r: |cFFFFFFFF" .. charInfo.mailCount .. "|r" end if charInfo.equippedCount > 0 then - table.insert(parts, "|cFF00FFFFEquipped|r: |cFFFFFFFF" .. charInfo.equippedCount .. "|r") + pIndex = pIndex + 1; parts[pIndex] = "|cFF00FFFFEquipped|r: |cFFFFFFFF" .. charInfo.equippedCount .. "|r" end + for i = pIndex + 1, table.getn(parts) do parts[i] = nil end - if getn(parts) > 0 then + local countText = "" + if pIndex > 0 then countText = table.concat(parts, " | ") end diff --git a/Guda.toc b/Guda.toc index 378afa6..1b13210 100644 --- a/Guda.toc +++ b/Guda.toc @@ -2,7 +2,7 @@ ## Title: Guda ## Notes: All-in-one bag and bank addon for World of Warcraft 1.12.1 (Turtle WoW) ## Author: Vati -## Version: 2.0.1 +## Version: 2.0.2 ## SavedVariables: Guda_DB ## SavedVariablesPerCharacter: Guda_CharDB diff --git a/UI/BagFrame.lua b/UI/BagFrame.lua index 8ca508a..8422d4c 100644 --- a/UI/BagFrame.lua +++ b/UI/BagFrame.lua @@ -3366,14 +3366,22 @@ function BagFrame:Initialize() end, "BagFrame") -- Update when items get locked/unlocked (debounced for trading, mailing, etc.) + local lockUpdatePending = false addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function() if currentViewChar then return end if not Guda_BagFrame:IsShown() then return end - -- In Category View, just update lock states visually without full redraw + -- In Category View, debounce lock state updates (fires rapidly during drags) local viewType = addon.Modules.DB:GetSetting("bagViewType") or "single" if viewType == "category" then - -- Only update lock visual states, don't trigger full redraw - BagFrame:UpdateLockStates() + if not lockUpdatePending then + lockUpdatePending = true + Guda_ScheduleTimer(0.05, function() + lockUpdatePending = false + if Guda_BagFrame:IsShown() and not currentViewChar then + BagFrame:UpdateLockStates() + end + end) + end return end -- Use slightly longer delay for lock changes in single view (they fire rapidly during drags) diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index 5a5a7b7..0987875 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -1897,23 +1897,17 @@ end function Guda_ItemButton_OnLeave(self) -- Delay hide of drop indicator to allow mouse to move to indicator frame if activeCategoryDropIndicator == self and categoryDropIndicator and categoryDropIndicator:IsShown() then - -- Use OnUpdate delay to check if mouse moved to the indicator - local elapsed = 0 - local checkFrame = CreateFrame("Frame") - checkFrame:SetScript("OnUpdate", function() - elapsed = elapsed + arg1 - if elapsed >= 0.05 then - this:SetScript("OnUpdate", nil) - -- If mouse is over the indicator, don't hide - if categoryDropIndicator and categoryDropIndicator:IsMouseOver() then - return - end - -- If mouse is over the parent button, don't hide - if activeCategoryDropIndicator and MouseIsOver(activeCategoryDropIndicator) then - return - end - HideCategoryDropIndicator() + -- Use pooled timer to check if mouse moved to the indicator (avoids frame leak) + Guda_ScheduleTimer(0.05, function() + -- If mouse is over the indicator, don't hide + if categoryDropIndicator and categoryDropIndicator:IsMouseOver() then + return end + -- If mouse is over the parent button, don't hide + if activeCategoryDropIndicator and MouseIsOver(activeCategoryDropIndicator) then + return + end + HideCategoryDropIndicator() end) else HideCategoryDropIndicator() diff --git a/UI/SettingsPopup.lua b/UI/SettingsPopup.lua index 99578f4..cc61c66 100644 --- a/UI/SettingsPopup.lua +++ b/UI/SettingsPopup.lua @@ -136,7 +136,7 @@ function Guda_SettingsPopup_OnShow(self) local bankColumns = Guda.Modules.DB:GetSetting("bankColumns") or 10 local iconSize = Guda.Modules.DB:GetSetting("iconSize") or 37 local iconFontSize = Guda.Modules.DB:GetSetting("iconFontSize") or 12 - local iconSpacing = Guda.Modules.DB:GetSetting("iconSpacing") or 3 + local iconSpacing = Guda.Modules.DB:GetSetting("iconSpacing") or 4 local lockBags = Guda.Modules.DB:GetSetting("lockBags") if lockBags == nil then lockBags = false @@ -600,7 +600,7 @@ function Guda_SettingsPopup_IconSpacingSlider_OnLoad(self) self:SetMinMaxValues(0, 20) self:SetValueStep(1) - local currentValue = Guda.Modules.DB:GetSetting("iconSpacing") or 3 + local currentValue = Guda.Modules.DB:GetSetting("iconSpacing") or 4 self:SetValue(currentValue) end