performance: debouncing added to some operations
This commit is contained in:
+15
-2
@@ -647,12 +647,25 @@ function Tooltip:Initialize()
|
||||
addon:Debug("Tooltip cache cleared")
|
||||
end
|
||||
|
||||
-- Clear cache on bag updates
|
||||
-- Clear cache on bag updates (debounced to prevent lag on rapid updates)
|
||||
local frame = CreateFrame("Frame")
|
||||
local cacheClearPending = false
|
||||
frame:RegisterEvent("BAG_UPDATE")
|
||||
frame:SetScript("OnEvent", function()
|
||||
if event == "BAG_UPDATE" then
|
||||
Tooltip:ClearCache()
|
||||
if cacheClearPending then return end
|
||||
cacheClearPending = true
|
||||
-- Debounce: batch rapid BAG_UPDATE events
|
||||
local debounceFrame = CreateFrame("Frame")
|
||||
debounceFrame.elapsed = 0
|
||||
debounceFrame:SetScript("OnUpdate", function()
|
||||
this.elapsed = this.elapsed + arg1
|
||||
if this.elapsed >= 0.2 then
|
||||
this:SetScript("OnUpdate", nil)
|
||||
cacheClearPending = false
|
||||
Tooltip:ClearCache()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
+44
-8
@@ -2235,11 +2235,33 @@ function BagFrame:Initialize()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Update on bag changes
|
||||
-- Debounce state for BagFrame updates (prevents lag from rapid events)
|
||||
local bagUpdatePending = false
|
||||
local lockUpdatePending = false
|
||||
|
||||
-- Helper to schedule a debounced BagFrame update
|
||||
local function ScheduleBagFrameUpdate(delay)
|
||||
if bagUpdatePending then return end
|
||||
bagUpdatePending = true
|
||||
local debounceFrame = CreateFrame("Frame")
|
||||
debounceFrame.elapsed = 0
|
||||
debounceFrame:SetScript("OnUpdate", function()
|
||||
this.elapsed = this.elapsed + arg1
|
||||
if this.elapsed >= delay then
|
||||
this:SetScript("OnUpdate", nil)
|
||||
bagUpdatePending = false
|
||||
if not currentViewChar and Guda_BagFrame:IsShown() then
|
||||
BagFrame:Update()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Update on bag changes (debounced to prevent lag on rapid bag updates)
|
||||
addon.Modules.Events:OnBagUpdate(function()
|
||||
if not currentViewChar then
|
||||
BagFrame:Update()
|
||||
end
|
||||
if currentViewChar then return end
|
||||
if not Guda_BagFrame:IsShown() then return end
|
||||
ScheduleBagFrameUpdate(0.1)
|
||||
end, "BagFrame")
|
||||
|
||||
-- Update item cooldown overlays when item cooldowns change
|
||||
@@ -2256,11 +2278,25 @@ function BagFrame:Initialize()
|
||||
BagFrame:UpdateMoney()
|
||||
end, "BagFrame")
|
||||
|
||||
-- Update when items get locked/unlocked (for trading, mailing, etc.)
|
||||
-- Update when items get locked/unlocked (debounced for trading, mailing, etc.)
|
||||
addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function()
|
||||
if not currentViewChar then
|
||||
BagFrame:Update()
|
||||
end
|
||||
if currentViewChar then return end
|
||||
if not Guda_BagFrame:IsShown() then return end
|
||||
-- Use slightly longer debounce for lock changes (they fire rapidly during drags)
|
||||
if lockUpdatePending then return end
|
||||
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")
|
||||
|
||||
-- Auto-open bag frame when mail is opened
|
||||
|
||||
+44
-7
@@ -1447,26 +1447,63 @@ function BankFrame:Initialize()
|
||||
end, "BankFrameUI")
|
||||
|
||||
-- Update on bag changes while bank is open
|
||||
-- Debounce state for BankFrame updates (prevents lag from rapid events)
|
||||
local bankUpdatePending = false
|
||||
local bankLockUpdatePending = false
|
||||
|
||||
-- Helper to schedule a debounced BankFrame update
|
||||
local function ScheduleBankFrameUpdate(delay)
|
||||
if bankUpdatePending then return end
|
||||
if not addon.Modules.BankScanner:IsBankOpen() then return end
|
||||
if currentViewChar then return end
|
||||
bankUpdatePending = true
|
||||
local debounceFrame = CreateFrame("Frame")
|
||||
debounceFrame.elapsed = 0
|
||||
debounceFrame:SetScript("OnUpdate", function()
|
||||
this.elapsed = this.elapsed + arg1
|
||||
if this.elapsed >= delay then
|
||||
this:SetScript("OnUpdate", nil)
|
||||
bankUpdatePending = false
|
||||
if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then
|
||||
addon.Modules.BankFrame:Update()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
addon.Modules.Events:OnBagUpdate(function()
|
||||
if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then
|
||||
addon.Modules.BankFrame:Update()
|
||||
ScheduleBankFrameUpdate(0.1)
|
||||
end
|
||||
end, "BankFrameUI")
|
||||
|
||||
-- Update when items get locked/unlocked (for trading, mailing, etc.)
|
||||
-- Update when items get locked/unlocked (debounced for trading, mailing, etc.)
|
||||
addon.Modules.Events:Register("ITEM_LOCK_CHANGED", function()
|
||||
if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then
|
||||
addon.Modules.BankFrame:Update()
|
||||
end
|
||||
if not addon.Modules.BankScanner:IsBankOpen() then return end
|
||||
if currentViewChar then return end
|
||||
if bankLockUpdatePending then return end
|
||||
bankLockUpdatePending = 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)
|
||||
bankLockUpdatePending = false
|
||||
if addon.Modules.BankScanner:IsBankOpen() then
|
||||
addon.Modules.BankFrame:Update()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end, "BankFrameUI")
|
||||
|
||||
-- Register bank-specific update events (pfUI style)
|
||||
-- Register bank-specific update events (pfUI style, debounced)
|
||||
local updateFrame = CreateFrame("Frame")
|
||||
updateFrame:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
|
||||
updateFrame:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED")
|
||||
updateFrame:SetScript("OnEvent", function()
|
||||
if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then
|
||||
addon.Modules.BankFrame:Update()
|
||||
ScheduleBankFrameUpdate(0.1)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
+61
-62
@@ -24,89 +24,44 @@ local function GetScanTooltip()
|
||||
return scanTooltip
|
||||
end
|
||||
|
||||
-- Check if an item is usable by scanning its tooltip for "Use:"
|
||||
local function IsItemUsable(bagID, slotID)
|
||||
if not bagID or not slotID then return false end
|
||||
-- Combined function to check if an item is a quest item AND usable in ONE tooltip scan
|
||||
-- This avoids the expensive double-scan that was causing lag
|
||||
function QuestItemBar:CheckQuestItemUsable(bagID, slotID)
|
||||
if not bagID or not slotID then return false, false, false end
|
||||
|
||||
local tooltip = GetScanTooltip()
|
||||
tooltip:ClearLines()
|
||||
tooltip:SetBagItem(bagID, slotID)
|
||||
|
||||
local isQuestItem = false
|
||||
local isQuestStarter = false
|
||||
local isUsable = false
|
||||
|
||||
for i = 1, tooltip:NumLines() do
|
||||
local line = getglobal("Guda_QuestBarScanTooltipTextLeft" .. i)
|
||||
if line then
|
||||
local text = line:GetText()
|
||||
if text then
|
||||
local tl = string.lower(text)
|
||||
-- Match explicit usability phrases (case-insensitive). Avoid generic 'quest item' matches.
|
||||
if string.find(tl, "use:") or string.find(tl, "begins a quest") or string.find(tl, "starts a quest") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Scan bags for quest items
|
||||
function QuestItemBar:ScanForQuestItems()
|
||||
questItems = {}
|
||||
|
||||
local foundAny = false
|
||||
-- Scan backpack and 4 bags
|
||||
for bagID = 0, 4 do
|
||||
local numSlots = GetContainerNumSlots(bagID)
|
||||
for slotID = 1, numSlots do
|
||||
local texture, count = GetContainerItemInfo(bagID, slotID)
|
||||
if texture then
|
||||
local isQuest, isStarter = self:IsQuestItem(bagID, slotID)
|
||||
if isQuest and IsItemUsable(bagID, slotID) then
|
||||
table.insert(questItems, {
|
||||
bagID = bagID,
|
||||
slotID = slotID,
|
||||
texture = texture,
|
||||
count = count
|
||||
})
|
||||
foundAny = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Disabled DB fallback: only show items actually present in bags and usable
|
||||
-- Fallback to database caused non-usable quest items to be shown in the bar
|
||||
-- Returning early to ensure only real, usable items from bags are considered
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
-- Local implementation of IsQuestItem (similar to the one in ItemButton.lua)
|
||||
function QuestItemBar:IsQuestItem(bagID, slotID)
|
||||
local tooltip = GetScanTooltip()
|
||||
tooltip:ClearLines()
|
||||
tooltip:SetBagItem(bagID, slotID)
|
||||
|
||||
local isQuestItem = false
|
||||
local isQuestStarter = false
|
||||
|
||||
for i = 1, tooltip:NumLines() do
|
||||
local line = getglobal("Guda_QuestBarScanTooltipTextLeft" .. i)
|
||||
if line then
|
||||
local text = line:GetText()
|
||||
if text then
|
||||
-- Check for quest item indicators
|
||||
if string.find(text, "Quest Starter") or
|
||||
string.find(text, "This Item Begins a Quest") or
|
||||
string.find(text, "Use: Starts a Quest") then
|
||||
isQuestItem = true
|
||||
isQuestStarter = true
|
||||
break
|
||||
isUsable = true -- Quest starters are always usable
|
||||
elseif string.find(text, "Quest Item") then
|
||||
isQuestItem = true
|
||||
end
|
||||
-- Check for usability (case-insensitive)
|
||||
if string.find(tl, "use:") or string.find(tl, "begins a quest") or string.find(tl, "starts a quest") then
|
||||
isUsable = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Fallback check for quest category if not detected from tooltip
|
||||
if not isQuestItem then
|
||||
local link = GetContainerItemLink(bagID, slotID)
|
||||
if link and addon.Modules.Utils and addon.Modules.Utils.ExtractItemID and addon.Modules.Utils.GetItemInfoSafe then
|
||||
@@ -120,6 +75,37 @@ function QuestItemBar:IsQuestItem(bagID, slotID)
|
||||
end
|
||||
end
|
||||
|
||||
return isQuestItem, isQuestStarter, isUsable
|
||||
end
|
||||
|
||||
-- Scan bags for quest items (optimized: single tooltip scan per item)
|
||||
function QuestItemBar:ScanForQuestItems()
|
||||
questItems = {}
|
||||
|
||||
-- Scan backpack and 4 bags
|
||||
for bagID = 0, 4 do
|
||||
local numSlots = GetContainerNumSlots(bagID)
|
||||
for slotID = 1, numSlots do
|
||||
local texture, count = GetContainerItemInfo(bagID, slotID)
|
||||
if texture then
|
||||
-- Single combined check instead of two separate tooltip scans
|
||||
local isQuest, isStarter, isUsable = self:CheckQuestItemUsable(bagID, slotID)
|
||||
if isQuest and isUsable then
|
||||
table.insert(questItems, {
|
||||
bagID = bagID,
|
||||
slotID = slotID,
|
||||
texture = texture,
|
||||
count = count
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Legacy function kept for compatibility (now calls combined function)
|
||||
function QuestItemBar:IsQuestItem(bagID, slotID)
|
||||
local isQuestItem, isQuestStarter, _ = self:CheckQuestItemUsable(bagID, slotID)
|
||||
return isQuestItem, isQuestStarter
|
||||
end
|
||||
|
||||
@@ -639,9 +625,22 @@ function QuestItemBar:Initialize()
|
||||
frame:SetPoint(pos.point, UIParent, pos.relativePoint or pos.point, pos.x, pos.y)
|
||||
end
|
||||
|
||||
-- Register for events
|
||||
-- Register for events with debouncing to prevent lag on rapid bag updates
|
||||
local bagUpdatePending = false
|
||||
addon.Modules.Events:Register("BAG_UPDATE", function()
|
||||
QuestItemBar:Update()
|
||||
if bagUpdatePending then return end
|
||||
bagUpdatePending = true
|
||||
-- Debounce: wait 0.15 seconds before updating to batch rapid events
|
||||
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)
|
||||
bagUpdatePending = false
|
||||
QuestItemBar:Update()
|
||||
end
|
||||
end)
|
||||
end, "QuestItemBar")
|
||||
|
||||
addon.Modules.Events:Register("BAG_UPDATE_COOLDOWN", function()
|
||||
|
||||
+15
-2
@@ -212,9 +212,22 @@ function TrackedItemBar:Initialize()
|
||||
frame:SetPoint(pos.point, UIParent, pos.relativePoint or pos.point, pos.x, pos.y)
|
||||
end
|
||||
|
||||
-- Register for events
|
||||
-- Register for events with debouncing to prevent lag on rapid bag updates
|
||||
local bagUpdatePending = false
|
||||
addon.Modules.Events:Register("BAG_UPDATE", function()
|
||||
TrackedItemBar:Update()
|
||||
if bagUpdatePending then return end
|
||||
bagUpdatePending = true
|
||||
-- Debounce: wait 0.15 seconds before updating to batch rapid events
|
||||
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)
|
||||
bagUpdatePending = false
|
||||
TrackedItemBar:Update()
|
||||
end
|
||||
end)
|
||||
end, "TrackedItemBar")
|
||||
|
||||
addon.Modules.Events:Register("PLAYER_ENTERING_WORLD", function()
|
||||
|
||||
Reference in New Issue
Block a user