category view issues

This commit is contained in:
Salikh Gurgenidze
2026-01-24 13:19:51 +04:00
parent f53d566534
commit 8019e19e37
5 changed files with 132 additions and 103 deletions
+27 -1
View File
@@ -15,13 +15,39 @@ local detectionCache = {}
local cacheHits = 0 local cacheHits = 0
local cacheMisses = 0 local cacheMisses = 0
-- Clear the detection cache -- Clear the entire detection cache (use sparingly - only for major events)
-- For simple item moves, use InvalidateItem() or don't invalidate at all
function ItemDetection:ClearCache() function ItemDetection:ClearCache()
detectionCache = {} detectionCache = {}
cacheHits = 0 cacheHits = 0
cacheMisses = 0 cacheMisses = 0
end end
-- Invalidate a specific item from cache (by itemLink)
-- Use this when a specific item's properties might have changed
function ItemDetection:InvalidateItem(itemLink)
if itemLink then
detectionCache[itemLink] = nil
end
end
-- Invalidate multiple items from cache
-- Use this for batch operations
function ItemDetection:InvalidateItems(itemLinks)
if itemLinks then
for _, link in ipairs(itemLinks) do
if link then
detectionCache[link] = nil
end
end
end
end
-- Check if we have cached data for an item (useful for debugging)
function ItemDetection:IsCached(itemLink)
return itemLink and detectionCache[itemLink] ~= nil
end
-- Get cache statistics -- Get cache statistics
function ItemDetection:GetCacheStats() function ItemDetection:GetCacheStats()
local total = cacheHits + cacheMisses local total = cacheHits + cacheMisses
+33 -34
View File
@@ -578,10 +578,12 @@ local function ConsolidateStacks(bagIDs)
if maxStack > 1 then if maxStack > 1 then
-- Sort stacks: higher priority bags first, then larger stacks -- Sort stacks: higher priority bags first, then larger stacks
table.sort(group.stacks, function(a, b) table.sort(group.stacks, function(a, b)
if a.priority ~= b.priority then if not a then return false end
return a.priority > b.priority if not b then return true end
if (a.priority or 0) ~= (b.priority or 0) then
return (a.priority or 0) > (b.priority or 0)
end end
return a.count > b.count return (a.count or 0) > (b.count or 0)
end) end)
-- Greedy consolidation: fill stacks from left to right -- Greedy consolidation: fill stacks from left to right
@@ -826,9 +828,13 @@ local function SortItems(items)
end end
table.sort(items, function(a, b) table.sort(items, function(a, b)
-- Guard against nil entries
if not a then return false end
if not b then return true end
-- 1. Priority items first (Hearthstone, etc.) -- 1. Priority items first (Hearthstone, etc.)
if a.priority ~= b.priority then if (a.priority or 0) ~= (b.priority or 0) then
return a.priority < b.priority return (a.priority or 0) < (b.priority or 0)
end end
-- 2. Equippable items always come before non-equippable items -- 2. Equippable items always come before non-equippable items
@@ -1018,10 +1024,12 @@ local function BuildTargetPositions(bagIDs, itemCount)
-- Only sort if we have more than one element -- Only sort if we have more than one element
if table.getn(sortedBags) > 1 then if table.getn(sortedBags) > 1 then
table.sort(sortedBags, function(a, b) table.sort(sortedBags, function(a, b)
if a.priority ~= b.priority then if not a then return false end
return a.priority > b.priority if not b then return true end
if (a.priority or 0) ~= (b.priority or 0) then
return (a.priority or 0) > (b.priority or 0)
end end
return a.bagID < b.bagID return (a.bagID or 0) < (b.bagID or 0)
end) end)
end end
@@ -1189,10 +1197,12 @@ local function BuildGreyTailPositions(bagIDs, greyCount)
-- Only sort if we have more than one element -- Only sort if we have more than one element
if table.getn(ordered) > 1 then if table.getn(ordered) > 1 then
table.sort(ordered, function(a, b) table.sort(ordered, function(a, b)
if a.priority ~= b.priority then if not a then return false end
return a.priority < b.priority -- lowest first if not b then return true end
if (a.priority or 0) ~= (b.priority or 0) then
return (a.priority or 0) < (b.priority or 0) -- lowest first
end end
return a.bagID > b.bagID -- higher bagID later (treated as further to the right) return (a.bagID or 0) > (b.bagID or 0) -- higher bagID later (treated as further to the right)
end) end)
end end
@@ -1214,15 +1224,17 @@ local function BuildGreyTailPositions(bagIDs, greyCount)
-- Ascending order: Priority DESC, BagID ASC, Slot ASC (matching BuildTargetPositions) -- Ascending order: Priority DESC, BagID ASC, Slot ASC (matching BuildTargetPositions)
if table.getn(tailSlots) > 1 then if table.getn(tailSlots) > 1 then
table.sort(tailSlots, function(a, b) table.sort(tailSlots, function(a, b)
if not a then return false end
if not b then return true end
local aPrio = tonumber(addon.Modules.Utils:GetContainerPriority(a.bag)) or 0 local aPrio = tonumber(addon.Modules.Utils:GetContainerPriority(a.bag)) or 0
local bPrio = tonumber(addon.Modules.Utils:GetContainerPriority(b.bag)) or 0 local bPrio = tonumber(addon.Modules.Utils:GetContainerPriority(b.bag)) or 0
if aPrio ~= bPrio then if aPrio ~= bPrio then
return aPrio > bPrio return aPrio > bPrio
end end
if a.bag ~= b.bag then if (a.bag or 0) ~= (b.bag or 0) then
return a.bag < b.bag return (a.bag or 0) < (b.bag or 0)
end end
return a.slot < b.slot return (a.slot or 0) < (b.slot or 0)
end) end)
end end
@@ -1518,11 +1530,9 @@ function SortEngine:SortBags()
end end
end end
-- Clear caches after sorting to ensure fresh detection on next UI update -- Clear bag position cache after sorting to ensure fresh slot data on next UI update
-- NOTE: Don't clear ItemDetection cache - item properties don't change when items move
addon.Modules.BagScanner:ClearCache() addon.Modules.BagScanner:ClearCache()
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
-- Return total moves made -- Return total moves made
return routeCount + consolidateCount + specializedMoves + regularMoves return routeCount + consolidateCount + specializedMoves + regularMoves
@@ -1655,11 +1665,9 @@ function SortEngine:SortBank()
end end
end end
-- Clear caches after sorting to ensure fresh detection on next UI update -- Clear bag position cache after sorting to ensure fresh slot data on next UI update
-- NOTE: Don't clear ItemDetection cache - item properties don't change when items move
addon.Modules.BankScanner:ClearCache() addon.Modules.BankScanner:ClearCache()
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
-- Return total moves made -- Return total moves made
return routeCount + consolidateCount + specializedMoves + regularMoves return routeCount + consolidateCount + specializedMoves + regularMoves
@@ -1727,15 +1735,12 @@ function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sort
SortEngine.sortingInProgress = false SortEngine.sortingInProgress = false
SortEngine:UpdateSortButtonState(false) SortEngine:UpdateSortButtonState(false)
currentSortType = "bags" -- Reset sort context currentSortType = "bags" -- Reset sort context
-- Clear caches after sorting to ensure fresh detection -- Clear bag position cache - item properties don't change on move
if sortType == "bank" then if sortType == "bank" then
addon.Modules.BankScanner:ClearCache() addon.Modules.BankScanner:ClearCache()
else else
addon.Modules.BagScanner:ClearCache() addon.Modules.BagScanner:ClearCache()
end end
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
updateFrame() updateFrame()
end) end)
elseif passCount >= safetyLimit then elseif passCount >= safetyLimit then
@@ -1748,15 +1753,12 @@ function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sort
SortEngine.sortingInProgress = false SortEngine.sortingInProgress = false
SortEngine:UpdateSortButtonState(false) SortEngine:UpdateSortButtonState(false)
currentSortType = "bags" -- Reset sort context currentSortType = "bags" -- Reset sort context
-- Clear caches after sorting to ensure fresh detection -- Clear bag position cache - item properties don't change on move
if sortType == "bank" then if sortType == "bank" then
addon.Modules.BankScanner:ClearCache() addon.Modules.BankScanner:ClearCache()
else else
addon.Modules.BagScanner:ClearCache() addon.Modules.BagScanner:ClearCache()
end end
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
updateFrame() updateFrame()
end) end)
else else
@@ -1776,15 +1778,12 @@ function SortEngine:ExecuteSort(sortFunction, analyzeFunction, updateFrame, sort
SortEngine.sortingInProgress = false SortEngine.sortingInProgress = false
SortEngine:UpdateSortButtonState(false) SortEngine:UpdateSortButtonState(false)
currentSortType = "bags" -- Reset sort context currentSortType = "bags" -- Reset sort context
-- Clear caches after sorting to ensure fresh detection -- Clear bag position cache - item properties don't change on move
if sortType == "bank" then if sortType == "bank" then
addon.Modules.BankScanner:ClearCache() addon.Modules.BankScanner:ClearCache()
else else
addon.Modules.BagScanner:ClearCache() addon.Modules.BagScanner:ClearCache()
end end
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
updateFrame() updateFrame()
end) end)
return return
+28 -15
View File
@@ -21,6 +21,7 @@ function BagFrame:GetCurrentViewChar()
end end
local searchText = "" local searchText = ""
local itemButtons = {} local itemButtons = {}
local slotToButton = {} -- Fast O(1) lookup: slotToButton[bagID][slotID] = button
local showKeyring = false -- Toggle for keyring display local showKeyring = false -- Toggle for keyring display
local hiddenBags = {} -- Track which bags are hidden (bagID -> true/false) local hiddenBags = {} -- Track which bags are hidden (bagID -> true/false)
local bagParents = {} -- Per-bag parent frames to carry bagID for Blizzard item button templates local bagParents = {} -- Per-bag parent frames to carry bagID for Blizzard item button templates
@@ -243,16 +244,13 @@ function BagFrame:UpdateChangedSlots(bagID)
local numSlots = GetContainerNumSlots(bagID) local numSlots = GetContainerNumSlots(bagID)
if not numSlots or numSlots == 0 then return -1 end if not numSlots or numSlots == 0 then return -1 end
-- Check if we have the slot lookup table for this bag
if not slotToButton[bagID] then return -1 end
local updatedCount = 0 local updatedCount = 0
for slotID = 1, numSlots do for slotID = 1, numSlots do
-- Find button for this slot -- O(1) button lookup using hash table
local targetButton = nil local targetButton = slotToButton[bagID][slotID]
for _, button in ipairs(itemButtons) do
if button.bagID == bagID and button.slotID == slotID then
targetButton = button
break
end
end
if not targetButton then if not targetButton then
-- Button not found, need full redraw -- Button not found, need full redraw
@@ -498,10 +496,13 @@ function BagFrame:Update()
-- Display items -- Display items
local viewType = addon.Modules.DB:GetSetting("bagViewType") or "single" local viewType = addon.Modules.DB:GetSetting("bagViewType") or "single"
-- Clear itemButtons table before rebuilding (prevents stale references) -- Clear itemButtons table and slot lookup before rebuilding (prevents stale references)
for k in pairs(itemButtons) do for k in pairs(itemButtons) do
itemButtons[k] = nil itemButtons[k] = nil
end end
for k in pairs(slotToButton) do
slotToButton[k] = nil
end
-- Reset all section headers before displaying items -- Reset all section headers before displaying items
local i = 1 local i = 1
@@ -704,6 +705,9 @@ function BagFrame:DisplayItemsByCategory(bagData, isOtherChar, charName)
Guda_ItemButton_SetItem(button, bagID, slot, itemData, false, isOtherChar and charName or nil, matchesFilter, isOtherChar) Guda_ItemButton_SetItem(button, bagID, slot, itemData, false, isOtherChar and charName or nil, matchesFilter, isOtherChar)
button.inUse = true button.inUse = true
table.insert(itemButtons, button) table.insert(itemButtons, button)
-- Populate slot lookup for O(1) access
if not slotToButton[bagID] then slotToButton[bagID] = {} end
slotToButton[bagID][slot] = button
col = col + 1 col = col + 1
if col >= blockCols then if col >= blockCols then
@@ -766,8 +770,11 @@ function BagFrame:DisplayItemsByCategory(bagData, isOtherChar, charName)
if numItems > 0 then if numItems > 0 then
if sec.name == "Tools" then if sec.name == "Tools" then
table.sort(items, function(a, b) table.sort(items, function(a, b)
if a.itemData.quality ~= b.itemData.quality then -- Guard against nil entries
return a.itemData.quality > b.itemData.quality if not a or not a.itemData then return false end
if not b or not b.itemData then return true end
if (a.itemData.quality or 0) ~= (b.itemData.quality or 0) then
return (a.itemData.quality or 0) > (b.itemData.quality or 0)
end end
return (a.itemData.name or "") < (b.itemData.name or "") return (a.itemData.name or "") < (b.itemData.name or "")
end) end)
@@ -830,6 +837,9 @@ function BagFrame:DisplayItemsByCategory(bagData, isOtherChar, charName)
Guda_ItemButton_SetItem(button, item.bagID, item.slotID, item.itemData, false, isOtherChar and charName or nil, self:PassesSearchFilter(item.itemData), isOtherChar) Guda_ItemButton_SetItem(button, item.bagID, item.slotID, item.itemData, false, isOtherChar and charName or nil, self:PassesSearchFilter(item.itemData), isOtherChar)
button.inUse = true button.inUse = true
table.insert(itemButtons, button) table.insert(itemButtons, button)
-- Populate slot lookup for O(1) access
if not slotToButton[item.bagID] then slotToButton[item.bagID] = {} end
slotToButton[item.bagID][item.slotID] = button
sCol = sCol + 1 sCol = sCol + 1
if sCol >= blockCols then if sCol >= blockCols then
@@ -1005,6 +1015,9 @@ function BagFrame:DisplayItems(bagData, isOtherChar, charName)
Guda_ItemButton_SetItem(button, bagID, slot, itemData, false, isOtherChar and charName or nil, matchesFilter, isOtherChar) Guda_ItemButton_SetItem(button, bagID, slot, itemData, false, isOtherChar and charName or nil, matchesFilter, isOtherChar)
table.insert(itemButtons, button) table.insert(itemButtons, button)
-- Populate slot lookup for O(1) access
if not slotToButton[bagID] then slotToButton[bagID] = {} end
slotToButton[bagID][slot] = button
-- Advance position -- Advance position
col = col + 1 col = col + 1
@@ -1746,7 +1759,9 @@ function Guda_BagFrame_MergeStacks()
if table.getn(group.stacks) > 1 then if table.getn(group.stacks) > 1 then
-- Sort stacks: larger stacks first (targets), smaller stacks last (sources) -- Sort stacks: larger stacks first (targets), smaller stacks last (sources)
table.sort(group.stacks, function(a, b) table.sort(group.stacks, function(a, b)
return a.count > b.count if not a then return false end
if not b then return true end
return (a.count or 0) > (b.count or 0)
end) end)
local sourceLoopStart = table.getn(group.stacks) local sourceLoopStart = table.getn(group.stacks)
@@ -2688,10 +2703,8 @@ function BagFrame:Initialize()
if not isSorting then if not isSorting then
-- Try incremental update for manual item moves -- Try incremental update for manual item moves
-- NOTE: Don't clear ItemDetection cache - item properties don't change on move
addon.Modules.BagScanner:InvalidateBag(arg1) addon.Modules.BagScanner:InvalidateBag(arg1)
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
-- Try to update only changed slots in this bag -- Try to update only changed slots in this bag
local result = BagFrame:UpdateChangedSlots(arg1) local result = BagFrame:UpdateChangedSlots(arg1)
+38 -48
View File
@@ -14,6 +14,7 @@ local searchText = ""
local isReadOnlyMode = false -- Track if viewing saved bank (read-only) or live bank (interactive) local isReadOnlyMode = false -- Track if viewing saved bank (read-only) or live bank (interactive)
local hiddenBankBags = {} -- Track which bank bags are hidden (bagID -> true/false) local hiddenBankBags = {} -- Track which bank bags are hidden (bagID -> true/false)
local bankBagParents = {} -- Parent frames per bank bag (same approach as BagFrame) local bankBagParents = {} -- Parent frames per bank bag (same approach as BagFrame)
local bankSlotToButton = {} -- Fast O(1) lookup: bankSlotToButton[bagID][slotID] = button
-- Global click catcher for clearing bank search focus -- Global click catcher for clearing bank search focus
local bankClickCatcher = nil local bankClickCatcher = nil
@@ -135,18 +136,9 @@ function BankFrame:UpdateSingleSlot(bagID, slotID)
if not Guda_BankFrame:IsShown() then return false end if not Guda_BankFrame:IsShown() then return false end
if currentViewChar then return false end -- Can't do single-slot for other characters if currentViewChar then return false end -- Can't do single-slot for other characters
-- Find the button for this slot -- O(1) button lookup using hash table
local bankBagParent = bankBagParents[bagID] if not bankSlotToButton[bagID] then return false end
if not bankBagParent or not bankBagParent.itemButtons then return false end local targetButton = bankSlotToButton[bagID][slotID]
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 return false end if not targetButton then return false end
-- Get fresh item data for this slot -- Get fresh item data for this slot
@@ -190,22 +182,16 @@ function BankFrame:UpdateChangedSlots(bagID)
if not Guda_BankFrame:IsShown() then return -1 end if not Guda_BankFrame:IsShown() then return -1 end
if currentViewChar then return -1 end if currentViewChar then return -1 end
local bankBagParent = bankBagParents[bagID] -- Check if we have the slot lookup table for this bag
if not bankBagParent or not bankBagParent.itemButtons then return -1 end if not bankSlotToButton[bagID] then return -1 end
local numSlots = addon.Modules.Utils:GetBagSlotCount(bagID) local numSlots = addon.Modules.Utils:GetBagSlotCount(bagID)
if not numSlots or numSlots == 0 then return -1 end if not numSlots or numSlots == 0 then return -1 end
local updatedCount = 0 local updatedCount = 0
for slotID = 1, numSlots do for slotID = 1, numSlots do
-- Find button for this slot -- O(1) button lookup using hash table
local targetButton = nil local targetButton = bankSlotToButton[bagID][slotID]
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 if not targetButton then
-- Button not found, need full redraw -- Button not found, need full redraw
@@ -302,7 +288,7 @@ function BankFrame:Update()
end 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)
-- Mark all existing buttons as not in use (we'll mark active ones during display) -- Also clear the slot lookup table for fresh rebuild
for _, bankBagParent in pairs(bankBagParents) do for _, bankBagParent in pairs(bankBagParents) do
if bankBagParent and bankBagParent.itemButtons then if bankBagParent and bankBagParent.itemButtons then
for button in pairs(bankBagParent.itemButtons) do for button in pairs(bankBagParent.itemButtons) do
@@ -312,6 +298,9 @@ function BankFrame:Update()
end end
end end
end end
for k in pairs(bankSlotToButton) do
bankSlotToButton[k] = nil
end
-- Determine if we're in read-only mode: -- Determine if we're in read-only mode:
-- - If viewing another character → read-only -- - If viewing another character → read-only
@@ -522,6 +511,9 @@ function BankFrame:DisplayItemsByCategory(bankData, isOtherChar, charName)
local matchesFilter = self:PassesSearchFilter(itemData) local matchesFilter = self:PassesSearchFilter(itemData)
Guda_ItemButton_SetItem(button, bagID, slot, itemData, true, isOtherChar and charName or nil, matchesFilter, isOtherChar or isReadOnlyMode) Guda_ItemButton_SetItem(button, bagID, slot, itemData, true, isOtherChar and charName or nil, matchesFilter, isOtherChar or isReadOnlyMode)
button.inUse = true button.inUse = true
-- Populate slot lookup for O(1) access
if not bankSlotToButton[bagID] then bankSlotToButton[bagID] = {} end
bankSlotToButton[bagID][slot] = button
col = col + 1 col = col + 1
if col >= blockCols then if col >= blockCols then
@@ -580,8 +572,11 @@ function BankFrame:DisplayItemsByCategory(bankData, isOtherChar, charName)
if numItems > 0 then if numItems > 0 then
if sec.name == "Tools" then if sec.name == "Tools" then
table.sort(items, function(a, b) table.sort(items, function(a, b)
if a.itemData.quality ~= b.itemData.quality then -- Guard against nil entries
return a.itemData.quality > b.itemData.quality if not a or not a.itemData then return false end
if not b or not b.itemData then return true end
if (a.itemData.quality or 0) ~= (b.itemData.quality or 0) then
return (a.itemData.quality or 0) > (b.itemData.quality or 0)
end end
return (a.itemData.name or "") < (b.itemData.name or "") return (a.itemData.name or "") < (b.itemData.name or "")
end) end)
@@ -642,7 +637,10 @@ function BankFrame:DisplayItemsByCategory(bankData, isOtherChar, charName)
button:Show() button:Show()
Guda_ItemButton_SetItem(button, item.bagID, item.slotID, item.itemData, true, isOtherChar and charName or nil, self:PassesSearchFilter(item.itemData), isOtherChar or isReadOnlyMode) Guda_ItemButton_SetItem(button, item.bagID, item.slotID, item.itemData, true, isOtherChar and charName or nil, self:PassesSearchFilter(item.itemData), isOtherChar or isReadOnlyMode)
button.inUse = true button.inUse = true
-- Populate slot lookup for O(1) access
if not bankSlotToButton[item.bagID] then bankSlotToButton[item.bagID] = {} end
bankSlotToButton[item.bagID][item.slotID] = button
sCol = sCol + 1 sCol = sCol + 1
if sCol >= blockCols then if sCol >= blockCols then
sCol = 0 sCol = 0
@@ -795,6 +793,9 @@ function BankFrame:DisplayItems(bankData, isOtherChar, charName)
button:SetPoint("TOPLEFT", itemContainer, "TOPLEFT", xPos, yPos) button:SetPoint("TOPLEFT", itemContainer, "TOPLEFT", xPos, yPos)
Guda_ItemButton_SetItem(button, bagID, slot, itemData, true, isOtherChar and charName or nil, matchesFilter, isReadOnlyMode) Guda_ItemButton_SetItem(button, bagID, slot, itemData, true, isOtherChar and charName or nil, matchesFilter, isReadOnlyMode)
-- Populate slot lookup for O(1) access
if not bankSlotToButton[bagID] then bankSlotToButton[bagID] = {} end
bankSlotToButton[bagID][slot] = button
col = col + 1 col = col + 1
if col >= perRow then if col >= perRow then
@@ -1229,7 +1230,9 @@ function Guda_BankFrame_MergeStacks()
if table.getn(group.stacks) > 1 then if table.getn(group.stacks) > 1 then
-- Sort stacks: larger stacks first (targets), smaller stacks last (sources) -- Sort stacks: larger stacks first (targets), smaller stacks last (sources)
table.sort(group.stacks, function(a, b) table.sort(group.stacks, function(a, b)
return a.count > b.count if not a then return false end
if not b then return true end
return (a.count or 0) > (b.count or 0)
end) end)
local sourceLoopStart = table.getn(group.stacks) local sourceLoopStart = table.getn(group.stacks)
@@ -1730,11 +1733,9 @@ function BankFrame:Initialize()
-- arg1 is the slot number (1-28 for main bank) -- arg1 is the slot number (1-28 for main bank)
-- Try single-slot update if not sorting -- Try single-slot update if not sorting
if not isSorting then if not isSorting then
-- Invalidate cache for fresh data -- Invalidate bag scanner cache for fresh slot data
-- NOTE: Don't clear ItemDetection cache - item properties don't change on move
addon.Modules.BankScanner:InvalidateBag(-1) addon.Modules.BankScanner:InvalidateBag(-1)
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
-- Try single-slot update -- Try single-slot update
if BankFrame:UpdateSingleSlot(-1, arg1) then if BankFrame:UpdateSingleSlot(-1, arg1) then
return -- Success, no full redraw needed return -- Success, no full redraw needed
@@ -1742,30 +1743,21 @@ function BankFrame:Initialize()
end end
-- Fallback: full redraw (sorting or single-slot failed) -- Fallback: full redraw (sorting or single-slot failed)
addon.Modules.BankScanner:InvalidateBag(-1) addon.Modules.BankScanner:InvalidateBag(-1)
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
elseif event == "BAG_UPDATE" and arg1 then elseif event == "BAG_UPDATE" and arg1 then
-- Check if this is a bank bag (5-10) -- Check if this is a bank bag (5-10)
if arg1 >= 5 and arg1 <= 10 then if arg1 >= 5 and arg1 <= 10 then
-- Invalidate bag scanner cache for fresh slot data
-- NOTE: Don't clear ItemDetection cache - item properties don't change on move
addon.Modules.BankScanner:InvalidateBag(arg1)
-- Try incremental update if not sorting -- Try incremental update if not sorting
if not isSorting then 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 -- Try to update only changed slots
local result = BankFrame:UpdateChangedSlots(arg1) local result = BankFrame:UpdateChangedSlots(arg1)
if result >= 0 then if result >= 0 then
return -- Success, no full redraw needed return -- Success, no full redraw needed
end end
-- Fall through to full redraw -- 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 end
else else
-- Not a bank bag, ignore for bank frame -- Not a bank bag, ignore for bank frame
@@ -1773,11 +1765,9 @@ function BankFrame:Initialize()
end end
elseif event == "PLAYERBANKBAGSLOTS_CHANGED" then elseif event == "PLAYERBANKBAGSLOTS_CHANGED" then
-- Bank container slot changed (bag added/removed) -- Bank container slot changed (bag added/removed)
-- Must clear entire cache since bag structure changed -- Clear bag scanner cache since structure changed
-- NOTE: Don't clear ItemDetection cache - item properties don't change
addon.Modules.BankScanner:ClearCache() addon.Modules.BankScanner:ClearCache()
if addon.Modules.ItemDetection then
addon.Modules.ItemDetection:ClearCache()
end
end end
-- Slightly longer delay to ensure WoW API has updated -- Slightly longer delay to ensure WoW API has updated
+6 -5
View File
@@ -212,11 +212,12 @@ end
function Guda_SortCategoryItems(items) function Guda_SortCategoryItems(items)
if not items then return end if not items then return end
table.sort(items, function(a, b) table.sort(items, function(a, b)
-- Nil guards for sort stability -- Guard against nil entries
if not a then return false end if not a then return false end
if not b then return true end if not b then return true end
if not a.itemData then return false end if not a.itemData then return false end
if not b.itemData then return true end if not b.itemData then return true end
-- Rank Trade Goods: meat (name ends with 'meat') = 2, egg (contains 'egg') = 1, others = 0 -- Rank Trade Goods: meat (name ends with 'meat') = 2, egg (contains 'egg') = 1, others = 0
local function tgRank(d) local function tgRank(d)
if not d or not d.name then return 0 end if not d or not d.name then return 0 end
@@ -233,8 +234,8 @@ function Guda_SortCategoryItems(items)
return ra > rb return ra > rb
end end
-- Priority: consumable restore tags (eat > drink > restore > nil) -- Priority: consumable restore tags (eat > drink > restore > nil)
local pa = a.itemData and a.itemData.restoreTag or nil local pa = a.itemData.restoreTag
local pb = b.itemData and b.itemData.restoreTag or nil local pb = b.itemData.restoreTag
local function pr(t) local function pr(t)
if t == "eat" then return 3 end if t == "eat" then return 3 end
if t == "drink" then return 2 end if t == "drink" then return 2 end
@@ -248,8 +249,8 @@ function Guda_SortCategoryItems(items)
if a.itemData.subclass ~= b.itemData.subclass then if a.itemData.subclass ~= b.itemData.subclass then
return (a.itemData.subclass or "") < (b.itemData.subclass or "") return (a.itemData.subclass or "") < (b.itemData.subclass or "")
end end
if a.itemData.quality ~= b.itemData.quality then if (a.itemData.quality or 0) ~= (b.itemData.quality or 0) then
return a.itemData.quality > b.itemData.quality return (a.itemData.quality or 0) > (b.itemData.quality or 0)
end end
return (a.itemData.name or "") < (b.itemData.name or "") return (a.itemData.name or "") < (b.itemData.name or "")
end) end)