performance: sort engine performance
This commit is contained in:
+6
-9
@@ -173,9 +173,8 @@ function BankFrame:Update()
|
||||
-- Check if we have any displayed items
|
||||
local hasDisplayedItems = false
|
||||
for _, bankBagParent in pairs(bankBagParents) do
|
||||
if bankBagParent then
|
||||
local children = { bankBagParent:GetChildren() }
|
||||
for _, button in ipairs(children) do
|
||||
if bankBagParent and bankBagParent.itemButtons then
|
||||
for button in pairs(bankBagParent.itemButtons) do
|
||||
if button.hasItem and button:IsShown() then
|
||||
hasDisplayedItems = true
|
||||
break
|
||||
@@ -194,9 +193,8 @@ function BankFrame:Update()
|
||||
|
||||
-- Mark all existing buttons as not in use (we'll mark active ones during display)
|
||||
for _, bankBagParent in pairs(bankBagParents) do
|
||||
if bankBagParent then
|
||||
local buttons = { bankBagParent:GetChildren() }
|
||||
for _, button in ipairs(buttons) do
|
||||
if bankBagParent and bankBagParent.itemButtons then
|
||||
for button in pairs(bankBagParent.itemButtons) do
|
||||
if button.hasItem ~= nil then
|
||||
button.inUse = false
|
||||
end
|
||||
@@ -274,9 +272,8 @@ function BankFrame:Update()
|
||||
|
||||
-- Clean up unused buttons AFTER display is complete (prevents drag/drop issues)
|
||||
for _, bankBagParent in pairs(bankBagParents) do
|
||||
if bankBagParent then
|
||||
local buttons = { bankBagParent:GetChildren() }
|
||||
for _, button in ipairs(buttons) do
|
||||
if bankBagParent and bankBagParent.itemButtons then
|
||||
for button in pairs(bankBagParent.itemButtons) do
|
||||
if button.hasItem ~= nil and not button.inUse then
|
||||
button:Hide()
|
||||
button:ClearAllPoints()
|
||||
|
||||
+61
-19
@@ -135,44 +135,77 @@ function Guda_CategorizeItem(itemData, bagID, slotID, categories, specialItems,
|
||||
table.insert(categories[cat], {bagID = bagID, slotID = slotID, itemData = itemData})
|
||||
end
|
||||
|
||||
-- Initialize empty category tables
|
||||
--=====================================================
|
||||
-- Category Table Pooling (memory optimization)
|
||||
-- Reuses category tables instead of creating new ones
|
||||
--=====================================================
|
||||
local categoriesCache = nil
|
||||
local specialItemsCache = nil
|
||||
|
||||
-- Clear a table without creating a new one (Lua 5.0 compatible)
|
||||
local function WipeTable(t)
|
||||
if not t then return end
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize empty category tables (reuses cached tables)
|
||||
function Guda_InitCategories()
|
||||
-- Refresh category list from CategoryManager (enabled categories only for display)
|
||||
Guda_RefreshCategoryList()
|
||||
|
||||
-- Create tables for ALL categories (not just enabled) so items can be categorized
|
||||
-- Items in disabled categories simply won't be displayed
|
||||
local categories = {}
|
||||
-- Reuse or create categories table
|
||||
if not categoriesCache then
|
||||
categoriesCache = {}
|
||||
end
|
||||
|
||||
-- Clear existing category arrays (don't recreate the main table)
|
||||
for cat, items in pairs(categoriesCache) do
|
||||
WipeTable(items)
|
||||
end
|
||||
|
||||
if addon.Modules.CategoryManager then
|
||||
-- Get full category order (all categories, not just enabled)
|
||||
local allCategories = addon.Modules.CategoryManager:GetCategoryOrder()
|
||||
for _, cat in ipairs(allCategories) do
|
||||
categories[cat] = {}
|
||||
if not categoriesCache[cat] then
|
||||
categoriesCache[cat] = {}
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Fallback: use the display list
|
||||
for _, cat in ipairs(Guda_CategoryList) do
|
||||
categories[cat] = {}
|
||||
if not categoriesCache[cat] then
|
||||
categoriesCache[cat] = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Always ensure Miscellaneous exists as fallback
|
||||
if not categories["Miscellaneous"] then
|
||||
categories["Miscellaneous"] = {}
|
||||
if not categoriesCache["Miscellaneous"] then
|
||||
categoriesCache["Miscellaneous"] = {}
|
||||
end
|
||||
|
||||
-- Always ensure Keyring exists (handled specially in BagFrame)
|
||||
if not categories["Keyring"] then
|
||||
categories["Keyring"] = {}
|
||||
if not categoriesCache["Keyring"] then
|
||||
categoriesCache["Keyring"] = {}
|
||||
end
|
||||
|
||||
local specialItems = {
|
||||
Hearthstone = {},
|
||||
Mount = {},
|
||||
Tools = {}
|
||||
}
|
||||
return categories, specialItems
|
||||
-- Reuse or create specialItems table
|
||||
if not specialItemsCache then
|
||||
specialItemsCache = {
|
||||
Hearthstone = {},
|
||||
Mount = {},
|
||||
Tools = {}
|
||||
}
|
||||
else
|
||||
WipeTable(specialItemsCache.Hearthstone)
|
||||
WipeTable(specialItemsCache.Mount)
|
||||
WipeTable(specialItemsCache.Tools)
|
||||
end
|
||||
|
||||
return categoriesCache, specialItemsCache
|
||||
end
|
||||
|
||||
-- Sort items within a category
|
||||
@@ -254,17 +287,26 @@ function Guda_GetBagParent(framePrefix, parentsTable, bagID, containerName)
|
||||
if parentsTable[bagID].SetID then
|
||||
parentsTable[bagID]:SetID(bagID)
|
||||
end
|
||||
-- Track item buttons to avoid GetChildren() table allocation
|
||||
parentsTable[bagID].itemButtons = {}
|
||||
end
|
||||
return parentsTable[bagID]
|
||||
end
|
||||
|
||||
-- Register an item button with its parent for tracking
|
||||
function Guda_RegisterItemButton(parent, button)
|
||||
if parent and parent.itemButtons and button then
|
||||
parent.itemButtons[button] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Update lock/desaturation states for a table of parent frames
|
||||
-- Uses itemButtons tracking to avoid GetChildren() table allocation
|
||||
function Guda_UpdateLockStates(parentsTable)
|
||||
if not parentsTable then return end
|
||||
for _, parent in pairs(parentsTable) do
|
||||
if parent then
|
||||
local buttons = { parent:GetChildren() }
|
||||
for _, button in ipairs(buttons) do
|
||||
if parent and parent.itemButtons then
|
||||
for button in pairs(parent.itemButtons) do
|
||||
if button.hasItem ~= nil and button:IsShown() and button.bagID and button.slotID then
|
||||
-- GetContainerItemInfo returns: texture, itemCount, locked, quality, readable
|
||||
-- The 3rd return value is the lock state (boolean or nil)
|
||||
|
||||
+44
-26
@@ -23,37 +23,45 @@ local function IsQuestItem(bagID, slotID, isBank, itemData)
|
||||
end
|
||||
|
||||
--=====================================================
|
||||
-- Junk Icon Helper Functions (reusable for all views)
|
||||
-- Shows a vendor sell icon on junk items
|
||||
-- Junk Icon Pool (Baganator-inspired memory optimization)
|
||||
-- Uses frame pooling to avoid creating new frames per button
|
||||
--=====================================================
|
||||
local junkIconPool = {}
|
||||
|
||||
-- Create junk icon for a button (parented to UIParent for full opacity)
|
||||
local function CreateJunkIcon(button)
|
||||
if button.junkIcon then return button.junkIcon end
|
||||
-- Get a junk icon from pool or create new one
|
||||
local function AcquireJunkIcon()
|
||||
local icon = table.remove(junkIconPool)
|
||||
if not icon then
|
||||
icon = CreateFrame("Frame", nil, UIParent)
|
||||
icon:SetFrameStrata("HIGH")
|
||||
icon:SetWidth(14)
|
||||
icon:SetHeight(14)
|
||||
|
||||
local junkFrame = CreateFrame("Frame", nil, UIParent)
|
||||
junkFrame:SetFrameStrata("HIGH")
|
||||
junkFrame:SetWidth(14)
|
||||
junkFrame:SetHeight(14)
|
||||
|
||||
local texture = junkFrame:CreateTexture(nil, "OVERLAY")
|
||||
texture:SetAllPoints(junkFrame)
|
||||
texture:SetTexture("Interface\\GossipFrame\\VendorGossipIcon")
|
||||
texture:SetTexCoord(0, 1, 0, 1)
|
||||
|
||||
junkFrame:Hide()
|
||||
button.junkIcon = junkFrame
|
||||
return junkFrame
|
||||
local texture = icon:CreateTexture(nil, "OVERLAY")
|
||||
texture:SetAllPoints(icon)
|
||||
texture:SetTexture("Interface\\GossipFrame\\VendorGossipIcon")
|
||||
texture:SetTexCoord(0, 1, 0, 1)
|
||||
icon.texture = texture
|
||||
end
|
||||
return icon
|
||||
end
|
||||
|
||||
-- Update junk icon visibility and position
|
||||
local function UpdateJunkIcon(button, isJunk, iconSize)
|
||||
-- Create icon if it doesn't exist
|
||||
if not button.junkIcon then
|
||||
CreateJunkIcon(button)
|
||||
-- Release a junk icon back to the pool
|
||||
local function ReleaseJunkIcon(icon)
|
||||
if icon then
|
||||
icon:Hide()
|
||||
icon:ClearAllPoints()
|
||||
table.insert(junkIconPool, icon)
|
||||
end
|
||||
end
|
||||
|
||||
-- Update junk icon visibility and position (uses pooling)
|
||||
local function UpdateJunkIcon(button, isJunk, iconSize)
|
||||
if isJunk then
|
||||
-- Acquire from pool if needed
|
||||
if not button.junkIcon then
|
||||
button.junkIcon = AcquireJunkIcon()
|
||||
end
|
||||
-- Scale icon size based on button size
|
||||
local junkIconSize = math.max(10, math.min(14, iconSize * 0.30))
|
||||
button.junkIcon:SetWidth(junkIconSize)
|
||||
@@ -63,14 +71,19 @@ local function UpdateJunkIcon(button, isJunk, iconSize)
|
||||
button.junkIcon:SetAlpha(1.0)
|
||||
button.junkIcon:Show()
|
||||
else
|
||||
button.junkIcon:Hide()
|
||||
-- Release back to pool when not needed
|
||||
if button.junkIcon then
|
||||
ReleaseJunkIcon(button.junkIcon)
|
||||
button.junkIcon = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Hide junk icon (for cleanup/reset)
|
||||
-- Hide junk icon (releases to pool)
|
||||
local function HideJunkIcon(button)
|
||||
if button.junkIcon then
|
||||
button.junkIcon:Hide()
|
||||
ReleaseJunkIcon(button.junkIcon)
|
||||
button.junkIcon = nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -251,6 +264,11 @@ function Guda_GetItemButton(parent)
|
||||
buttonPool[nextButtonID] = button
|
||||
nextButtonID = nextButtonID + 1
|
||||
|
||||
-- Register button with parent for tracking (avoids GetChildren() allocation)
|
||||
if Guda_RegisterItemButton then
|
||||
Guda_RegisterItemButton(parent, button)
|
||||
end
|
||||
|
||||
return button
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user