performance: sort debouncing
This commit is contained in:
@@ -1625,6 +1625,7 @@ function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sort
|
|||||||
if noProgressPasses >= 5 then
|
if noProgressPasses >= 5 then
|
||||||
addon:DebugSort("%s sort stopped due to no progress after %d passes (items remaining: %d/%d)",
|
addon:DebugSort("%s sort stopped due to no progress after %d passes (items remaining: %d/%d)",
|
||||||
sortType, passCount, currentAnalysis.itemsOutOfPlace, currentAnalysis.totalItems)
|
sortType, passCount, currentAnalysis.itemsOutOfPlace, currentAnalysis.totalItems)
|
||||||
|
|
||||||
-- Final update
|
-- Final update
|
||||||
local frame = CreateFrame("Frame")
|
local frame = CreateFrame("Frame")
|
||||||
local startTime = GetTime()
|
local startTime = GetTime()
|
||||||
|
|||||||
+75
-33
@@ -136,6 +136,12 @@ function Guda_BagFrame_OnHide(self)
|
|||||||
addon.Modules.Utils:ClearWorkQueue()
|
addon.Modules.Utils:ClearWorkQueue()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Cancel any pending throttled updates
|
||||||
|
local throttleFrame = getglobal("Guda_BagUpdateThrottle")
|
||||||
|
if throttleFrame then
|
||||||
|
throttleFrame:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
-- Clean up all buttons when frame is hidden (safe since we're not displaying)
|
-- Clean up all buttons when frame is hidden (safe since we're not displaying)
|
||||||
for _, bagParent in pairs(bagParents) do
|
for _, bagParent in pairs(bagParents) do
|
||||||
if bagParent then
|
if bagParent then
|
||||||
@@ -2503,32 +2509,81 @@ function BagFrame:Initialize()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Debounce state for BagFrame updates (prevents lag from rapid events)
|
--=====================================================
|
||||||
local bagUpdatePending = false
|
-- Efficient Update Throttling System
|
||||||
local lockUpdatePending = false
|
-- Uses a single reusable frame and true debouncing
|
||||||
|
-- (resets timer when new events come in)
|
||||||
|
--=====================================================
|
||||||
|
local updateThrottle = {
|
||||||
|
frame = nil,
|
||||||
|
pending = false,
|
||||||
|
delay = 0.1, -- Default delay (100ms)
|
||||||
|
elapsed = 0,
|
||||||
|
minDelay = 0.05, -- Minimum delay (50ms) for responsive feel
|
||||||
|
maxDelay = 0.3, -- Maximum delay (300ms) during heavy operations
|
||||||
|
}
|
||||||
|
|
||||||
-- Helper to schedule a debounced BagFrame update
|
-- Initialize the throttle frame (created once, reused)
|
||||||
local function ScheduleBagFrameUpdate(delay)
|
local function GetThrottleFrame()
|
||||||
if bagUpdatePending then return end
|
if not updateThrottle.frame then
|
||||||
bagUpdatePending = true
|
updateThrottle.frame = CreateFrame("Frame", "Guda_BagUpdateThrottle", UIParent)
|
||||||
local debounceFrame = CreateFrame("Frame")
|
updateThrottle.frame:Hide()
|
||||||
debounceFrame.elapsed = 0
|
updateThrottle.frame:SetScript("OnUpdate", function()
|
||||||
debounceFrame:SetScript("OnUpdate", function()
|
updateThrottle.elapsed = updateThrottle.elapsed + arg1
|
||||||
this.elapsed = this.elapsed + arg1
|
if updateThrottle.elapsed >= updateThrottle.delay then
|
||||||
if this.elapsed >= delay then
|
updateThrottle.frame:Hide()
|
||||||
this:SetScript("OnUpdate", nil)
|
updateThrottle.pending = false
|
||||||
bagUpdatePending = false
|
updateThrottle.elapsed = 0
|
||||||
if not currentViewChar and Guda_BagFrame:IsShown() then
|
-- Only update if frame is shown and viewing current character
|
||||||
BagFrame:Update()
|
if not currentViewChar and Guda_BagFrame and Guda_BagFrame:IsShown() then
|
||||||
|
BagFrame:Update()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
end)
|
end
|
||||||
|
return updateThrottle.frame
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Schedule a debounced BagFrame update
|
||||||
|
-- If already pending, resets the timer (true debounce behavior)
|
||||||
|
local function ScheduleBagFrameUpdate(delay)
|
||||||
|
delay = delay or updateThrottle.minDelay
|
||||||
|
|
||||||
|
-- Clamp delay to reasonable bounds
|
||||||
|
if delay < updateThrottle.minDelay then
|
||||||
|
delay = updateThrottle.minDelay
|
||||||
|
elseif delay > updateThrottle.maxDelay then
|
||||||
|
delay = updateThrottle.maxDelay
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Use longer delay if sorting is in progress
|
||||||
|
if addon.Modules.SortEngine and addon.Modules.SortEngine.sortingInProgress then
|
||||||
|
delay = updateThrottle.maxDelay
|
||||||
|
end
|
||||||
|
|
||||||
|
updateThrottle.delay = delay
|
||||||
|
updateThrottle.elapsed = 0 -- Reset timer (true debounce)
|
||||||
|
|
||||||
|
if not updateThrottle.pending then
|
||||||
|
updateThrottle.pending = true
|
||||||
|
GetThrottleFrame():Show()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cancel any pending update (useful when frame is hidden)
|
||||||
|
local function CancelPendingUpdate()
|
||||||
|
if updateThrottle.frame then
|
||||||
|
updateThrottle.frame:Hide()
|
||||||
|
end
|
||||||
|
updateThrottle.pending = false
|
||||||
|
updateThrottle.elapsed = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update on bag changes (debounced to prevent lag on rapid bag updates)
|
-- Update on bag changes (debounced to prevent lag on rapid bag updates)
|
||||||
addon.Modules.Events:OnBagUpdate(function()
|
addon.Modules.Events:OnBagUpdate(function()
|
||||||
if currentViewChar then return end
|
if currentViewChar then return end
|
||||||
if not Guda_BagFrame:IsShown() then return end
|
if not Guda_BagFrame:IsShown() then return end
|
||||||
|
-- Use standard delay, will auto-extend if sorting is in progress
|
||||||
ScheduleBagFrameUpdate(0.1)
|
ScheduleBagFrameUpdate(0.1)
|
||||||
end, "BagFrame")
|
end, "BagFrame")
|
||||||
|
|
||||||
@@ -2550,21 +2605,8 @@ function BagFrame:Initialize()
|
|||||||
addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function()
|
addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function()
|
||||||
if currentViewChar then return end
|
if currentViewChar then return end
|
||||||
if not Guda_BagFrame:IsShown() then return end
|
if not Guda_BagFrame:IsShown() then return end
|
||||||
-- Use slightly longer debounce for lock changes (they fire rapidly during drags)
|
-- Use slightly longer delay for lock changes (they fire rapidly during drags)
|
||||||
if lockUpdatePending then return end
|
ScheduleBagFrameUpdate(0.15)
|
||||||
lockUpdatePending = true
|
|
||||||
local debounceFrame = CreateFrame("Frame")
|
|
||||||
debounceFrame.elapsed = 0
|
|
||||||
debounceFrame:SetScript("OnUpdate", function()
|
|
||||||
this.elapsed = this.elapsed + arg1
|
|
||||||
if this.elapsed >= 0.15 then
|
|
||||||
this:SetScript("OnUpdate", nil)
|
|
||||||
lockUpdatePending = false
|
|
||||||
if Guda_BagFrame:IsShown() then
|
|
||||||
BagFrame:Update()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end, "BagFrame")
|
end, "BagFrame")
|
||||||
|
|
||||||
-- Auto-open bag frame when mail is opened
|
-- Auto-open bag frame when mail is opened
|
||||||
|
|||||||
+59
-33
@@ -89,6 +89,12 @@ function Guda_BankFrame_OnHide(self)
|
|||||||
-- Clear any pending update
|
-- Clear any pending update
|
||||||
bankPendingUpdate = false
|
bankPendingUpdate = false
|
||||||
|
|
||||||
|
-- Cancel any pending throttled updates
|
||||||
|
local throttleFrame = getglobal("Guda_BankUpdateThrottle")
|
||||||
|
if throttleFrame then
|
||||||
|
throttleFrame:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
-- Close the actual Blizzard bank too
|
-- Close the actual Blizzard bank too
|
||||||
local blizzardBankFrame = getglobal("BankFrame")
|
local blizzardBankFrame = getglobal("BankFrame")
|
||||||
if blizzardBankFrame and blizzardBankFrame:IsShown() then
|
if blizzardBankFrame and blizzardBankFrame:IsShown() then
|
||||||
@@ -1543,29 +1549,61 @@ function BankFrame:Initialize()
|
|||||||
end
|
end
|
||||||
end, "BankFrameUI")
|
end, "BankFrameUI")
|
||||||
|
|
||||||
-- Update on bag changes while bank is open
|
--=====================================================
|
||||||
-- Debounce state for BankFrame updates (prevents lag from rapid events)
|
-- Efficient Update Throttling System for BankFrame
|
||||||
local bankUpdatePending = false
|
-- Uses a single reusable frame and true debouncing
|
||||||
local bankLockUpdatePending = false
|
--=====================================================
|
||||||
|
local bankThrottle = {
|
||||||
|
frame = nil,
|
||||||
|
pending = false,
|
||||||
|
delay = 0.1,
|
||||||
|
elapsed = 0,
|
||||||
|
minDelay = 0.05,
|
||||||
|
maxDelay = 0.3,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function GetBankThrottleFrame()
|
||||||
|
if not bankThrottle.frame then
|
||||||
|
bankThrottle.frame = CreateFrame("Frame", "Guda_BankUpdateThrottle", UIParent)
|
||||||
|
bankThrottle.frame:Hide()
|
||||||
|
bankThrottle.frame:SetScript("OnUpdate", function()
|
||||||
|
bankThrottle.elapsed = bankThrottle.elapsed + arg1
|
||||||
|
if bankThrottle.elapsed >= bankThrottle.delay then
|
||||||
|
bankThrottle.frame:Hide()
|
||||||
|
bankThrottle.pending = false
|
||||||
|
bankThrottle.elapsed = 0
|
||||||
|
if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then
|
||||||
|
addon.Modules.BankFrame:Update()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
return bankThrottle.frame
|
||||||
|
end
|
||||||
|
|
||||||
-- Helper to schedule a debounced BankFrame update
|
|
||||||
local function ScheduleBankFrameUpdate(delay)
|
local function ScheduleBankFrameUpdate(delay)
|
||||||
if bankUpdatePending then return end
|
|
||||||
if not addon.Modules.BankScanner:IsBankOpen() then return end
|
if not addon.Modules.BankScanner:IsBankOpen() then return end
|
||||||
if currentViewChar then return end
|
if currentViewChar then return end
|
||||||
bankUpdatePending = true
|
|
||||||
local debounceFrame = CreateFrame("Frame")
|
delay = delay or bankThrottle.minDelay
|
||||||
debounceFrame.elapsed = 0
|
if delay < bankThrottle.minDelay then
|
||||||
debounceFrame:SetScript("OnUpdate", function()
|
delay = bankThrottle.minDelay
|
||||||
this.elapsed = this.elapsed + arg1
|
elseif delay > bankThrottle.maxDelay then
|
||||||
if this.elapsed >= delay then
|
delay = bankThrottle.maxDelay
|
||||||
this:SetScript("OnUpdate", nil)
|
end
|
||||||
bankUpdatePending = false
|
|
||||||
if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then
|
-- Use longer delay if sorting is in progress
|
||||||
addon.Modules.BankFrame:Update()
|
if addon.Modules.SortEngine and addon.Modules.SortEngine.sortingInProgress then
|
||||||
end
|
delay = bankThrottle.maxDelay
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
|
bankThrottle.delay = delay
|
||||||
|
bankThrottle.elapsed = 0 -- Reset timer (true debounce)
|
||||||
|
|
||||||
|
if not bankThrottle.pending then
|
||||||
|
bankThrottle.pending = true
|
||||||
|
GetBankThrottleFrame():Show()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
addon.Modules.Events:OnBagUpdate(function()
|
addon.Modules.Events:OnBagUpdate(function()
|
||||||
@@ -1578,20 +1616,8 @@ function BankFrame:Initialize()
|
|||||||
addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function()
|
addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function()
|
||||||
if not addon.Modules.BankScanner:IsBankOpen() then return end
|
if not addon.Modules.BankScanner:IsBankOpen() then return end
|
||||||
if currentViewChar then return end
|
if currentViewChar then return end
|
||||||
if bankLockUpdatePending then return end
|
-- Use slightly longer delay for lock changes
|
||||||
bankLockUpdatePending = true
|
ScheduleBankFrameUpdate(0.15)
|
||||||
local debounceFrame = CreateFrame("Frame")
|
|
||||||
debounceFrame.elapsed = 0
|
|
||||||
debounceFrame:SetScript("OnUpdate", function()
|
|
||||||
this.elapsed = this.elapsed + arg1
|
|
||||||
if this.elapsed >= 0.15 then
|
|
||||||
this:SetScript("OnUpdate", nil)
|
|
||||||
bankLockUpdatePending = false
|
|
||||||
if addon.Modules.BankScanner:IsBankOpen() then
|
|
||||||
addon.Modules.BankFrame:Update()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end, "BankFrameUI")
|
end, "BankFrameUI")
|
||||||
|
|
||||||
-- Register bank-specific update events (pfUI style, debounced)
|
-- Register bank-specific update events (pfUI style, debounced)
|
||||||
|
|||||||
Reference in New Issue
Block a user