perf: add caching and transfer limiting for bag/bank operations
This commit is contained in:
+110
-18
@@ -1,12 +1,100 @@
|
|||||||
-- Guda Bag Scanner
|
-- Guda Bag Scanner
|
||||||
-- Scans and stores bag contents
|
-- Scans and stores bag contents with caching and event pending tracking
|
||||||
|
|
||||||
local addon = Guda
|
local addon = Guda
|
||||||
|
|
||||||
local BagScanner = {}
|
local BagScanner = {}
|
||||||
addon.Modules.BagScanner = BagScanner
|
addon.Modules.BagScanner = BagScanner
|
||||||
|
|
||||||
-- Scan all bags and return data
|
-- Cache for bag data to avoid re-scanning all slots on every update
|
||||||
|
local bagCache = nil
|
||||||
|
local cacheValid = false
|
||||||
|
|
||||||
|
-- Event pending tracking (like Baganator's IsBagEventPending)
|
||||||
|
local eventPending = false
|
||||||
|
local dirtySlots = {} -- Track specific slots that changed: dirtySlots[bagID][slotID] = true
|
||||||
|
|
||||||
|
-- Clear the bag cache
|
||||||
|
function BagScanner:ClearCache()
|
||||||
|
bagCache = nil
|
||||||
|
cacheValid = false
|
||||||
|
dirtySlots = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if a bag event is pending (use before transfers)
|
||||||
|
function BagScanner:IsEventPending()
|
||||||
|
return eventPending
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clear the pending flag (call after processing)
|
||||||
|
function BagScanner:ClearEventPending()
|
||||||
|
eventPending = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Mark a specific slot as dirty (incremental tracking)
|
||||||
|
function BagScanner:MarkSlotDirty(bagID, slotID)
|
||||||
|
if not dirtySlots[bagID] then
|
||||||
|
dirtySlots[bagID] = {}
|
||||||
|
end
|
||||||
|
dirtySlots[bagID][slotID] = true
|
||||||
|
eventPending = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get dirty slots and clear them
|
||||||
|
function BagScanner:GetAndClearDirtySlots()
|
||||||
|
local dirty = dirtySlots
|
||||||
|
dirtySlots = {}
|
||||||
|
return dirty
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get cached bag data, or scan if cache is invalid
|
||||||
|
function BagScanner:GetBagData()
|
||||||
|
if cacheValid and bagCache then
|
||||||
|
-- Process any dirty slots incrementally
|
||||||
|
for bagID, slots in pairs(dirtySlots) do
|
||||||
|
if bagCache[bagID] then
|
||||||
|
for slotID in pairs(slots) do
|
||||||
|
local oldData = bagCache[bagID].slots[slotID]
|
||||||
|
local newData = self:ScanSlot(bagID, slotID)
|
||||||
|
bagCache[bagID].slots[slotID] = newData
|
||||||
|
|
||||||
|
-- Update free slot count
|
||||||
|
local wasEmpty = (oldData == nil)
|
||||||
|
local isEmpty = (newData == nil)
|
||||||
|
if wasEmpty and not isEmpty then
|
||||||
|
bagCache[bagID].freeSlots = bagCache[bagID].freeSlots - 1
|
||||||
|
elseif not wasEmpty and isEmpty then
|
||||||
|
bagCache[bagID].freeSlots = bagCache[bagID].freeSlots + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Bag not in cache, scan it
|
||||||
|
bagCache[bagID] = self:ScanBag(bagID)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dirtySlots = {}
|
||||||
|
return bagCache
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cache miss - do full scan
|
||||||
|
bagCache = self:ScanBags()
|
||||||
|
cacheValid = true
|
||||||
|
dirtySlots = {}
|
||||||
|
return bagCache
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Invalidate cache (force full re-scan on next update)
|
||||||
|
function BagScanner:InvalidateCache()
|
||||||
|
cacheValid = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Invalidate a specific bag in the cache
|
||||||
|
function BagScanner:InvalidateBag(bagID)
|
||||||
|
if not bagCache then return end
|
||||||
|
bagCache[bagID] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Scan all bags and return data (full scan)
|
||||||
function BagScanner:ScanBags()
|
function BagScanner:ScanBags()
|
||||||
local bagData = {}
|
local bagData = {}
|
||||||
|
|
||||||
@@ -61,8 +149,6 @@ function BagScanner:ScanSlot(bagID, slot)
|
|||||||
local itemLink = GetContainerItemLink(bagID, slot)
|
local itemLink = GetContainerItemLink(bagID, slot)
|
||||||
|
|
||||||
-- Get item info
|
-- Get item info
|
||||||
-- Correct order: itemName, itemLink, itemRarity, itemLevel, itemCategory, itemType,
|
|
||||||
-- itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice
|
|
||||||
local name, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice
|
local name, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice
|
||||||
if itemLink then
|
if itemLink then
|
||||||
name, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(itemLink)
|
name, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(itemLink)
|
||||||
@@ -76,9 +162,9 @@ function BagScanner:ScanSlot(bagID, slot)
|
|||||||
name = name,
|
name = name,
|
||||||
iLevel = iLevel,
|
iLevel = iLevel,
|
||||||
type = itemType,
|
type = itemType,
|
||||||
class = itemCategory, -- Category (e.g., "Consumable", "Armor")
|
class = itemCategory,
|
||||||
subclass = itemSubType, -- SubType (e.g., "Potion", "Cloth")
|
subclass = itemSubType,
|
||||||
equipSlot = itemEquipLoc, -- Equipment slot (e.g., "INVTYPE_HEAD") - correct now!
|
equipSlot = itemEquipLoc,
|
||||||
locked = locked,
|
locked = locked,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@@ -95,22 +181,28 @@ function BagScanner:SaveToDatabase()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Initialize with auto-save on bag changes
|
-- Initialize with event pending tracking
|
||||||
function BagScanner:Initialize()
|
function BagScanner:Initialize()
|
||||||
-- Create event frame for bag updates
|
|
||||||
local eventFrame = CreateFrame("Frame")
|
local eventFrame = CreateFrame("Frame")
|
||||||
self.eventFrame = eventFrame
|
self.eventFrame = eventFrame
|
||||||
|
|
||||||
-- Register bag update events
|
-- Register bag update events for pending tracking
|
||||||
eventFrame:RegisterEvent("BAG_UPDATE")
|
eventFrame:RegisterEvent("BAG_UPDATE")
|
||||||
eventFrame:RegisterEvent("BAG_UPDATE_DELAYED")
|
eventFrame:RegisterEvent("BAG_UPDATE_DELAYED")
|
||||||
--
|
eventFrame:SetScript("OnEvent", function()
|
||||||
--eventFrame:SetScript("OnEvent", function()
|
eventPending = true
|
||||||
-- if event == "BAG_UPDATE" or event == "BAG_UPDATE_DELAYED" then
|
-- Mark the specific bag as having changes
|
||||||
-- addon:Debug("Bag update detected, saving data...")
|
if arg1 then
|
||||||
-- self:SaveToDatabase()
|
if not dirtySlots[arg1] then
|
||||||
-- end
|
dirtySlots[arg1] = {}
|
||||||
--end)
|
end
|
||||||
|
-- We don't know which slot, so mark entire bag for rescan
|
||||||
|
-- by invalidating it
|
||||||
|
if bagCache and bagCache[arg1] then
|
||||||
|
bagCache[arg1] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
addon:Debug("Bag scanner initialized with auto-save")
|
addon:Debug("Bag scanner initialized with event pending tracking")
|
||||||
end
|
end
|
||||||
+101
-5
@@ -1,5 +1,5 @@
|
|||||||
-- Guda Bank Scanner
|
-- Guda Bank Scanner
|
||||||
-- Scans and stores bank contents
|
-- Scans and stores bank contents with caching and event pending tracking
|
||||||
|
|
||||||
local addon = Guda
|
local addon = Guda
|
||||||
|
|
||||||
@@ -8,7 +8,102 @@ addon.Modules.BankScanner = BankScanner
|
|||||||
|
|
||||||
local bankOpen = false
|
local bankOpen = false
|
||||||
|
|
||||||
-- Scan all bank bags and return data
|
-- Cache for bank data to avoid re-scanning all slots on every update
|
||||||
|
local bankCache = nil
|
||||||
|
local cacheValid = false
|
||||||
|
|
||||||
|
-- Event pending tracking (like Baganator's IsBagEventPending)
|
||||||
|
local eventPending = false
|
||||||
|
local dirtySlots = {} -- Track specific slots that changed
|
||||||
|
|
||||||
|
-- Clear the bank cache (called when bank opens or significant changes occur)
|
||||||
|
function BankScanner:ClearCache()
|
||||||
|
bankCache = nil
|
||||||
|
cacheValid = false
|
||||||
|
dirtySlots = {}
|
||||||
|
eventPending = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if a bank event is pending (use before transfers)
|
||||||
|
function BankScanner:IsEventPending()
|
||||||
|
return eventPending
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clear the pending flag (call after processing)
|
||||||
|
function BankScanner:ClearEventPending()
|
||||||
|
eventPending = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Mark a specific slot as dirty (incremental tracking)
|
||||||
|
function BankScanner:MarkSlotDirty(bagID, slotID)
|
||||||
|
if not dirtySlots[bagID] then
|
||||||
|
dirtySlots[bagID] = {}
|
||||||
|
end
|
||||||
|
dirtySlots[bagID][slotID] = true
|
||||||
|
eventPending = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get cached bank data, or scan if cache is invalid
|
||||||
|
function BankScanner:GetBankData()
|
||||||
|
if not bankOpen then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if cacheValid and bankCache then
|
||||||
|
-- Process any dirty slots incrementally
|
||||||
|
for bagID, slots in pairs(dirtySlots) do
|
||||||
|
if bankCache[bagID] then
|
||||||
|
for slotID in pairs(slots) do
|
||||||
|
local oldData = bankCache[bagID].slots[slotID]
|
||||||
|
local newData = addon.Modules.BagScanner:ScanSlot(bagID, slotID)
|
||||||
|
bankCache[bagID].slots[slotID] = newData
|
||||||
|
|
||||||
|
-- Update free slot count
|
||||||
|
local wasEmpty = (oldData == nil)
|
||||||
|
local isEmpty = (newData == nil)
|
||||||
|
if wasEmpty and not isEmpty then
|
||||||
|
bankCache[bagID].freeSlots = bankCache[bagID].freeSlots - 1
|
||||||
|
elseif not wasEmpty and isEmpty then
|
||||||
|
bankCache[bagID].freeSlots = bankCache[bagID].freeSlots + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Bag not in cache, scan it
|
||||||
|
bankCache[bagID] = self:ScanBankBag(bagID)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dirtySlots = {}
|
||||||
|
return bankCache
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cache miss - do full scan
|
||||||
|
bankCache = self:ScanBank()
|
||||||
|
cacheValid = true
|
||||||
|
dirtySlots = {}
|
||||||
|
return bankCache
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update a single slot in the cache (incremental update)
|
||||||
|
function BankScanner:UpdateSlot(bagID, slotID)
|
||||||
|
if not bankOpen then return end
|
||||||
|
|
||||||
|
-- Mark as dirty for next GetBankData call
|
||||||
|
self:MarkSlotDirty(bagID, slotID)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Invalidate cache (force full re-scan on next update)
|
||||||
|
function BankScanner:InvalidateCache()
|
||||||
|
cacheValid = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Invalidate a specific bag in the cache (force re-scan of just that bag)
|
||||||
|
function BankScanner:InvalidateBag(bagID)
|
||||||
|
if not bankOpen then return end
|
||||||
|
if not bankCache then return end
|
||||||
|
bankCache[bagID] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Scan all bank bags and return data (full scan)
|
||||||
function BankScanner:ScanBank()
|
function BankScanner:ScanBank()
|
||||||
if not bankOpen then
|
if not bankOpen then
|
||||||
addon:Debug("Cannot scan bank - not open")
|
addon:Debug("Cannot scan bank - not open")
|
||||||
@@ -67,16 +162,17 @@ function BankScanner:SaveToDatabase()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local bankData = self:ScanBank()
|
local bankData = self:GetBankData() -- Use cached data
|
||||||
addon.Modules.DB:SaveBank(bankData)
|
addon.Modules.DB:SaveBank(bankData)
|
||||||
addon:Debug("Bank data saved")
|
addon:Debug("Bank data saved")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Initialize bank scanner
|
-- Initialize bank scanner
|
||||||
function BankScanner:Initialize()
|
function BankScanner:Initialize()
|
||||||
-- Bank opened - save bank data
|
-- Bank opened - do initial scan
|
||||||
addon.Modules.Events:OnBankOpen(function()
|
addon.Modules.Events:OnBankOpen(function()
|
||||||
bankOpen = true
|
bankOpen = true
|
||||||
|
BankScanner:ClearCache() -- Clear cache on open
|
||||||
addon:Debug("Bank opened")
|
addon:Debug("Bank opened")
|
||||||
|
|
||||||
-- Delay scan to ensure bank is fully loaded
|
-- Delay scan to ensure bank is fully loaded
|
||||||
@@ -94,11 +190,11 @@ function BankScanner:Initialize()
|
|||||||
-- Bank closed
|
-- Bank closed
|
||||||
addon.Modules.Events:OnBankClose(function()
|
addon.Modules.Events:OnBankClose(function()
|
||||||
-- Do a final save on close before marking bank as closed
|
-- Do a final save on close before marking bank as closed
|
||||||
-- so that any last changes are captured.
|
|
||||||
addon:Debug("Bank closing - performing final save")
|
addon:Debug("Bank closing - performing final save")
|
||||||
BankScanner:SaveToDatabase()
|
BankScanner:SaveToDatabase()
|
||||||
|
|
||||||
bankOpen = false
|
bankOpen = false
|
||||||
|
BankScanner:ClearCache() -- Clear cache on close
|
||||||
addon:Debug("Bank closed")
|
addon:Debug("Bank closed")
|
||||||
end, "BankScanner")
|
end, "BankScanner")
|
||||||
end
|
end
|
||||||
|
|||||||
+40
-4
@@ -9,6 +9,17 @@ addon.Modules.SortEngine = SortEngine
|
|||||||
-- Flag to track if sorting is currently in progress
|
-- Flag to track if sorting is currently in progress
|
||||||
SortEngine.sortingInProgress = false
|
SortEngine.sortingInProgress = false
|
||||||
|
|
||||||
|
-- Performance: Max items to move per cycle (like Baganator's 5-item limit)
|
||||||
|
local MAX_MOVES_PER_CYCLE = 5
|
||||||
|
|
||||||
|
-- Transfer status constants (like Baganator's SortStatus)
|
||||||
|
local TransferStatus = {
|
||||||
|
Complete = 0, -- All moves done
|
||||||
|
WaitingMove = 1, -- Waiting for item move to complete
|
||||||
|
WaitingUnlock = 2, -- Item is locked, waiting
|
||||||
|
Partial = 3, -- Some moves done, more pending
|
||||||
|
}
|
||||||
|
|
||||||
-- Update sort button appearance based on sorting state
|
-- Update sort button appearance based on sorting state
|
||||||
function SortEngine:UpdateSortButtonState(isDisabled)
|
function SortEngine:UpdateSortButtonState(isDisabled)
|
||||||
local buttons = {
|
local buttons = {
|
||||||
@@ -1002,6 +1013,18 @@ end
|
|||||||
local function ApplySort(bagIDs, items, targetPositions)
|
local function ApplySort(bagIDs, items, targetPositions)
|
||||||
ClearCursor()
|
ClearCursor()
|
||||||
|
|
||||||
|
-- Check if events are pending (like Baganator's IsBagEventPending)
|
||||||
|
-- If so, wait for them to complete before moving more items
|
||||||
|
if addon.Modules.BagScanner:IsEventPending() or
|
||||||
|
(addon.Modules.BankScanner:IsBankOpen() and addon.Modules.BankScanner:IsEventPending()) then
|
||||||
|
-- Clear pending flags and return 0 - will retry on next pass
|
||||||
|
addon.Modules.BagScanner:ClearEventPending()
|
||||||
|
if addon.Modules.BankScanner:IsBankOpen() then
|
||||||
|
addon.Modules.BankScanner:ClearEventPending()
|
||||||
|
end
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
local moveToEmpty = {}
|
local moveToEmpty = {}
|
||||||
local swapOccupied = {}
|
local swapOccupied = {}
|
||||||
|
|
||||||
@@ -1036,9 +1059,16 @@ local function ApplySort(bagIDs, items, targetPositions)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Execute moves to empty slots first
|
-- Execute moves to empty slots first (with limit per cycle)
|
||||||
local moveCount = 0
|
local moveCount = 0
|
||||||
|
local lockedCount = 0
|
||||||
|
|
||||||
for _, move in ipairs(moveToEmpty) do
|
for _, move in ipairs(moveToEmpty) do
|
||||||
|
-- Limit moves per cycle to prevent slot locking (like Baganator)
|
||||||
|
if moveCount >= MAX_MOVES_PER_CYCLE then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
local _, _, locked = GetContainerItemInfo(move.sourceBag, move.sourceSlot)
|
local _, _, locked = GetContainerItemInfo(move.sourceBag, move.sourceSlot)
|
||||||
if not locked then
|
if not locked then
|
||||||
PickupContainerItem(move.sourceBag, move.sourceSlot)
|
PickupContainerItem(move.sourceBag, move.sourceSlot)
|
||||||
@@ -1046,13 +1076,17 @@ local function ApplySort(bagIDs, items, targetPositions)
|
|||||||
ClearCursor()
|
ClearCursor()
|
||||||
moveCount = moveCount + 1
|
moveCount = moveCount + 1
|
||||||
else
|
else
|
||||||
-- If item is locked, it might be due to server lag or another process.
|
lockedCount = lockedCount + 1
|
||||||
-- We don't increment moveCount but the item will be picked up in next pass.
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Execute swaps with occupied slots
|
-- Execute swaps with occupied slots (if we haven't hit the limit)
|
||||||
for _, move in ipairs(swapOccupied) do
|
for _, move in ipairs(swapOccupied) do
|
||||||
|
-- Limit moves per cycle
|
||||||
|
if moveCount >= MAX_MOVES_PER_CYCLE then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
local _, _, sourceLocked = GetContainerItemInfo(move.sourceBag, move.sourceSlot)
|
local _, _, sourceLocked = GetContainerItemInfo(move.sourceBag, move.sourceSlot)
|
||||||
local _, _, targetLocked = GetContainerItemInfo(move.targetBag, move.targetSlot)
|
local _, _, targetLocked = GetContainerItemInfo(move.targetBag, move.targetSlot)
|
||||||
|
|
||||||
@@ -1061,6 +1095,8 @@ local function ApplySort(bagIDs, items, targetPositions)
|
|||||||
PickupContainerItem(move.targetBag, move.targetSlot)
|
PickupContainerItem(move.targetBag, move.targetSlot)
|
||||||
ClearCursor()
|
ClearCursor()
|
||||||
moveCount = moveCount + 1
|
moveCount = moveCount + 1
|
||||||
|
else
|
||||||
|
lockedCount = lockedCount + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+13
-4
@@ -381,8 +381,8 @@ function BagFrame:Update()
|
|||||||
displayName = currentViewChar
|
displayName = currentViewChar
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Viewing current character
|
-- Viewing current character - use cached data for performance
|
||||||
bagData = addon.Modules.BagScanner:ScanBags()
|
bagData = addon.Modules.BagScanner:GetBagData()
|
||||||
displayName = UnitName("player") or "Character"
|
displayName = UnitName("player") or "Character"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2580,12 +2580,21 @@ function BagFrame:Initialize()
|
|||||||
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()
|
-- Register directly to access arg1 (bagID that changed) for incremental cache updates
|
||||||
|
local bagUpdateFrame = CreateFrame("Frame")
|
||||||
|
bagUpdateFrame:RegisterEvent("BAG_UPDATE")
|
||||||
|
bagUpdateFrame:SetScript("OnEvent", 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
|
||||||
|
|
||||||
|
-- Invalidate only the specific bag that changed (arg1 = bagID)
|
||||||
|
if arg1 and arg1 >= 0 and arg1 <= 4 then
|
||||||
|
addon.Modules.BagScanner:InvalidateBag(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
-- Use standard delay, will auto-extend if sorting is in progress
|
-- Use standard delay, will auto-extend if sorting is in progress
|
||||||
ScheduleBagFrameUpdate(0.1)
|
ScheduleBagFrameUpdate(0.1)
|
||||||
end, "BagFrame")
|
end)
|
||||||
|
|
||||||
-- Update item cooldown overlays when item cooldowns change
|
-- Update item cooldown overlays when item cooldowns change
|
||||||
addon.Modules.Events:Register("BAG_UPDATE_COOLDOWN", function()
|
addon.Modules.Events:Register("BAG_UPDATE_COOLDOWN", function()
|
||||||
|
|||||||
+25
-5
@@ -224,8 +224,8 @@ function BankFrame:Update()
|
|||||||
else
|
else
|
||||||
-- Viewing current character's bank
|
-- Viewing current character's bank
|
||||||
if bankIsOpen then
|
if bankIsOpen then
|
||||||
-- Bank is actually open - use live data (interactive mode)
|
-- Bank is actually open - use cached data for performance
|
||||||
bankData = addon.Modules.BankScanner:ScanBank()
|
bankData = addon.Modules.BankScanner:GetBankData()
|
||||||
-- Use current character's name for the title
|
-- Use current character's name for the title
|
||||||
local playerName = addon.Modules.DB:GetPlayerFullName()
|
local playerName = addon.Modules.DB:GetPlayerFullName()
|
||||||
getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
|
getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
|
||||||
@@ -1620,14 +1620,34 @@ function BankFrame:Initialize()
|
|||||||
ScheduleBankFrameUpdate(0.15)
|
ScheduleBankFrameUpdate(0.15)
|
||||||
end, "BankFrameUI")
|
end, "BankFrameUI")
|
||||||
|
|
||||||
-- Register bank-specific update events (pfUI style, debounced)
|
-- Register bank-specific update events with incremental slot tracking
|
||||||
local updateFrame = CreateFrame("Frame")
|
local updateFrame = CreateFrame("Frame")
|
||||||
updateFrame:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
|
updateFrame:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
|
||||||
updateFrame:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED")
|
updateFrame:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED")
|
||||||
|
updateFrame:RegisterEvent("BAG_UPDATE")
|
||||||
updateFrame:SetScript("OnEvent", function()
|
updateFrame:SetScript("OnEvent", function()
|
||||||
if addon.Modules.BankScanner:IsBankOpen() and not currentViewChar then
|
if not addon.Modules.BankScanner:IsBankOpen() then return end
|
||||||
ScheduleBankFrameUpdate(0.1)
|
if currentViewChar then return end
|
||||||
|
|
||||||
|
if event == "PLAYERBANKSLOTS_CHANGED" and arg1 then
|
||||||
|
-- Mark specific slot as dirty in main bank (bagID = -1)
|
||||||
|
addon.Modules.BankScanner:MarkSlotDirty(-1, arg1)
|
||||||
|
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 (we don't know which slot)
|
||||||
|
addon.Modules.BankScanner:InvalidateBag(arg1)
|
||||||
|
else
|
||||||
|
-- Not a bank bag, ignore for bank frame
|
||||||
|
return
|
||||||
|
end
|
||||||
|
elseif event == "PLAYERBANKBAGSLOTS_CHANGED" then
|
||||||
|
-- Bank container slot changed (bag added/removed)
|
||||||
|
-- Must clear entire cache since bag structure changed
|
||||||
|
addon.Modules.BankScanner:ClearCache()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ScheduleBankFrameUpdate(0.1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user