From cafc0f3f9207ee116b9836a22a9cd31b32b998c3 Mon Sep 17 00:00:00 2001 From: Salikh Gurgenidze Date: Sat, 24 Jan 2026 05:28:37 +0400 Subject: [PATCH] fix: performance issue --- UI/BankFrame.lua | 80 ++++++++++++++++++++++++++++++++++++++++++++--- UI/ItemButton.lua | 6 +++- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/UI/BankFrame.lua b/UI/BankFrame.lua index 1fbf2f3..e43f4b0 100644 --- a/UI/BankFrame.lua +++ b/UI/BankFrame.lua @@ -184,6 +184,62 @@ function BankFrame:UpdateSingleSlot(bagID, slotID) return true end +-- Update changed slots in a bank bag by comparing with cached data +-- Returns number of slots updated, or -1 if full redraw is needed +function BankFrame:UpdateChangedSlots(bagID) + if not Guda_BankFrame:IsShown() then return -1 end + if currentViewChar then return -1 end + + local bankBagParent = bankBagParents[bagID] + if not bankBagParent or not bankBagParent.itemButtons then return -1 end + + local numSlots = addon.Modules.Utils:GetBagSlotCount(bagID) + if not numSlots or numSlots == 0 then return -1 end + + local updatedCount = 0 + for slotID = 1, numSlots do + -- Find button for this slot + local targetButton = nil + for button in pairs(bankBagParent.itemButtons) do + if button.bagID == bagID and button.slotID == slotID then + targetButton = button + break + end + end + + if not targetButton then + -- Button not found, need full redraw + return -1 + end + + -- Compare current item with button's cached data + local currentLink = GetContainerItemLink(bagID, slotID) + local cachedLink = targetButton.itemData and targetButton.itemData.link or nil + + -- Check if slot changed (different item or count) + local needsUpdate = false + if currentLink ~= cachedLink then + needsUpdate = true + elseif currentLink then + local _, currentCount = GetContainerItemInfo(bagID, slotID) + local cachedCount = targetButton.itemData and targetButton.itemData.count or 0 + if currentCount ~= cachedCount then + needsUpdate = true + end + end + + if needsUpdate then + if self:UpdateSingleSlot(bagID, slotID) then + updatedCount = updatedCount + 1 + else + return -1 -- Update failed, need full redraw + end + end + end + + return updatedCount +end + -- Deferred update state for frame budgeting local bankPendingUpdate = false local bankUpdateDebounceFrame = nil @@ -245,6 +301,7 @@ function BankFrame:Update() -- If no items displayed yet, continue with full update end + -- Mark all existing buttons as not in use (we'll mark active ones during display) -- Mark all existing buttons as not in use (we'll mark active ones during display) for _, bankBagParent in pairs(bankBagParents) do if bankBagParent and bankBagParent.itemButtons then @@ -1705,11 +1762,24 @@ function BankFrame:Initialize() elseif event == "BAG_UPDATE" and arg1 then -- Check if this is a bank bag (5-10) if arg1 >= 5 and arg1 <= 10 then - -- Invalidate the specific bank bag - addon.Modules.BankScanner:InvalidateBag(arg1) - -- Clear ItemDetection cache to ensure fresh detection after item swap - if addon.Modules.ItemDetection then - addon.Modules.ItemDetection:ClearCache() + -- Try incremental update if not sorting + if not isSorting then + addon.Modules.BankScanner:InvalidateBag(arg1) + if addon.Modules.ItemDetection then + addon.Modules.ItemDetection:ClearCache() + end + -- Try to update only changed slots + local result = BankFrame:UpdateChangedSlots(arg1) + if result >= 0 then + return -- Success, no full redraw needed + end + -- Fall through to full redraw + else + -- Sorting in progress - invalidate for full redraw + addon.Modules.BankScanner:InvalidateBag(arg1) + if addon.Modules.ItemDetection then + addon.Modules.ItemDetection:ClearCache() + end end else -- Not a bank bag, ignore for bank frame diff --git a/UI/ItemButton.lua b/UI/ItemButton.lua index fe5337c..cfba5db 100644 --- a/UI/ItemButton.lua +++ b/UI/ItemButton.lua @@ -251,10 +251,14 @@ end -- Create or get a button from the pool function Guda_GetItemButton(parent) - -- Try to reuse existing button + -- Try to reuse existing button from same parent for _, button in pairs(buttonPool) do -- Skip bag slot buttons if not button.isBagSlot and not button:IsShown() and button:GetParent() == parent then + -- Re-register with parent (itemButtons hash may have been cleared) + if Guda_RegisterItemButton then + Guda_RegisterItemButton(parent, button) + end return button end end