Cheaper window open, lock-only button refresh, re-sort only changed groups
- UiFrame_OnShow requests a full categorization pass only if the last one was more than 60 seconds ago. - Lock-only cache updates refresh just the affected item buttons (AssignItemToItemButton) instead of running UpdateWindow(). - SortGroups() reuses a group's previous sorted order when none of its items were re-categorized and it holds exactly the same items; any full categorization pass invalidates all sorted orders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019W3rwt5PZSpEDkXYzRuRhH
This commit is contained in:
@@ -60,6 +60,9 @@ Bagshui:AddComponent(function()
|
||||
-- Before doing anything else, we need to know if we're online.
|
||||
self:UpdateOnlineStatus()
|
||||
|
||||
-- Was a full redraw already requested before the cache update?
|
||||
local windowUpdateWasNeeded = self.windowUpdateNeeded
|
||||
|
||||
-- Always update the cache if we get this far.
|
||||
self:UpdateCache()
|
||||
|
||||
@@ -70,6 +73,25 @@ Bagshui:AddComponent(function()
|
||||
return
|
||||
end
|
||||
|
||||
-- Only items locking/unlocking (picked up, or moving between bags and bank): refresh those
|
||||
-- buttons so they turn gray and back, instead of redrawing the whole window.
|
||||
if
|
||||
self.cacheOnlyLockChanges
|
||||
and not windowUpdateWasNeeded
|
||||
and not self.forceResort
|
||||
and not self.resortNeeded
|
||||
and not self.lookupTablesStale
|
||||
and not self.editMode
|
||||
then
|
||||
self:RefreshLockChangedItemButtons()
|
||||
self.windowUpdateNeeded = false
|
||||
self.windowUpdateBlocked = false
|
||||
if update_cascadeInventory then
|
||||
update_cascadeInventory:Update()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Nothing changed and nothing is waiting for a redraw -- skip the entire pipeline.
|
||||
-- This is the primary optimization for spurious BAG_UPDATE events.
|
||||
if not self.cacheChanged and not self.windowUpdateNeeded and not self.forceResort and not self.lookupTablesStale then
|
||||
@@ -139,6 +161,21 @@ Bagshui:AddComponent(function()
|
||||
self:Update(cascade)
|
||||
end
|
||||
|
||||
--- Re-apply the look of item buttons whose item only locked or unlocked in the last cache update
|
||||
--- (gray while locked, badges dimmed). Same as what a full redraw does for those buttons.
|
||||
function Inventory:RefreshLockChangedItemButtons()
|
||||
local changed = self.lockOnlyChangedItems
|
||||
if not changed then
|
||||
return
|
||||
end
|
||||
for _, button in ipairs(self.ui.buttons.itemSlots) do
|
||||
local buttonInfo = button.bagshuiData
|
||||
if buttonInfo and buttonInfo.item and changed[buttonInfo.item] and button:IsVisible() then
|
||||
self.ui:AssignItemToItemButton(button, buttonInfo.item, buttonInfo.groupId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Refresh only item slot colors without all the overhead of calculating the window layout.
|
||||
--- High-performance -- much better than `UpdateWindow()`/`ForceUpdateWindow()`, so it should be used for
|
||||
--- changing highlights or opacity (searching, bag bar mouseover, Edit Mode highlighting, etc.).
|
||||
@@ -416,6 +453,9 @@ Bagshui:AddComponent(function()
|
||||
end
|
||||
end
|
||||
|
||||
-- Sorted-order cache helpers, defined below SortGroups()'s cache tables.
|
||||
local MarkGroupForResort, InvalidateAllSortedGroups
|
||||
|
||||
--- Assign categories and groups to all items in the inventory cache.
|
||||
--- **Should not be called directly!** Use `Inventory:Update()` to coordinate the process.
|
||||
---
|
||||
@@ -447,6 +487,9 @@ Bagshui:AddComponent(function()
|
||||
if fullPass then
|
||||
self.categorizeEpoch = (self.categorizeEpoch or 0) + 1
|
||||
self.fullCategorizeNeeded = false
|
||||
self.lastFullCategorizeTime = _G.GetTime()
|
||||
-- Every group gets re-sorted after a full pass (see SortGroups()).
|
||||
InvalidateAllSortedGroups()
|
||||
end
|
||||
|
||||
-- Perform the actual categorization.
|
||||
@@ -461,6 +504,7 @@ Bagshui:AddComponent(function()
|
||||
-- items are always categorized so they never show up with an unknown category in the
|
||||
-- Bagshui tooltip; unchanged items keep the category from the last pass.
|
||||
if fullPass or self:CategoryCacheStale(self.inventory[bagNum][slotNum]) then
|
||||
local previousGroupId = self.inventory[bagNum][slotNum].bagshuiGroupId
|
||||
BsCategories:Categorize(
|
||||
self.inventory[bagNum][slotNum],
|
||||
nil, -- Categorization as any alternate character is not currently enabled.
|
||||
@@ -468,6 +512,9 @@ Bagshui:AddComponent(function()
|
||||
self.categoryIdsGroupedBySequence
|
||||
)
|
||||
self:StoreCategorySignature(self.inventory[bagNum][slotNum])
|
||||
-- The group this item left and the group it's in now both need re-sorting.
|
||||
MarkGroupForResort(previousGroupId)
|
||||
MarkGroupForResort(self.inventory[bagNum][slotNum].bagshuiGroupId)
|
||||
end
|
||||
|
||||
-- Fall back to the default group if one wasn't assigned.
|
||||
@@ -500,6 +547,69 @@ Bagshui:AddComponent(function()
|
||||
self.errorText = BsCategories:GetErrors(self.activeCategoryIds)
|
||||
end
|
||||
|
||||
-- Sorted-order cache for groups (see SortGroups()). A group's cached order is reused when none of
|
||||
-- its items were re-categorized since it was sorted (an item that changed in any way the sort can
|
||||
-- see is re-categorized, see CategoryCacheStale()) and it still holds exactly the same items.
|
||||
-- `groupSortVersions[groupId]` goes up whenever an item enters or leaves a group or changes;
|
||||
-- `sortEpoch` goes up after every full categorization pass (rules, settings, sort orders...).
|
||||
local groupSortVersions = {}
|
||||
local sortEpoch = 0
|
||||
-- { [groupItems table] = { list = {...}, set = { [item] = true }, count, version, epoch } }
|
||||
local sortedGroupCache = setmetatable({}, { __mode = "k" })
|
||||
|
||||
MarkGroupForResort = function(groupId)
|
||||
if groupId and groupId ~= "" then
|
||||
groupSortVersions[groupId] = (groupSortVersions[groupId] or 0) + 1
|
||||
end
|
||||
end
|
||||
|
||||
InvalidateAllSortedGroups = function()
|
||||
sortEpoch = sortEpoch + 1
|
||||
end
|
||||
|
||||
--- Put a group's items back in their last sorted order if nothing relevant changed.
|
||||
---@return boolean restored
|
||||
local function RestoreSortedGroup(items, groupId)
|
||||
local cached = sortedGroupCache[items]
|
||||
local count = table.getn(items)
|
||||
if
|
||||
not cached
|
||||
or cached.epoch ~= sortEpoch
|
||||
or cached.version ~= (groupSortVersions[groupId] or 0)
|
||||
or cached.count ~= count
|
||||
then
|
||||
return false
|
||||
end
|
||||
for i = 1, count do
|
||||
if not cached.set[items[i]] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
for i = 1, count do
|
||||
items[i] = cached.list[i]
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- Remember a group's sorted order.
|
||||
local function StoreSortedGroup(items, groupId)
|
||||
local cached = sortedGroupCache[items]
|
||||
if not cached then
|
||||
cached = { list = {}, set = {} }
|
||||
sortedGroupCache[items] = cached
|
||||
end
|
||||
BsUtil.TableClear(cached.list)
|
||||
BsUtil.TableClear(cached.set)
|
||||
local count = table.getn(items)
|
||||
for i = 1, count do
|
||||
table.insert(cached.list, items[i])
|
||||
cached.set[items[i]] = true
|
||||
end
|
||||
cached.count = count
|
||||
cached.epoch = sortEpoch
|
||||
cached.version = groupSortVersions[groupId] or 0
|
||||
end
|
||||
|
||||
-- What each item's last categorization was based on: { [item] = signature }.
|
||||
-- Weak keys so replaced item tables don't linger; kept out of the item tables so nothing extra
|
||||
-- ends up in SavedVariables.
|
||||
@@ -551,7 +661,11 @@ Bagshui:AddComponent(function()
|
||||
-- **Should not be called directly!** Use `Inventory:Update()` to coordinate the process.
|
||||
function Inventory:SortGroups()
|
||||
for groupId, groupConfig in pairs(self.activeGroups) do
|
||||
BsSortOrders:SortGroup(self.groupItems[groupId], groupConfig, self.settings.defaultSortOrder)
|
||||
-- Groups whose items didn't change keep their previous sorted order (see RestoreSortedGroup()).
|
||||
if not RestoreSortedGroup(self.groupItems[groupId], groupId) then
|
||||
BsSortOrders:SortGroup(self.groupItems[groupId], groupConfig, self.settings.defaultSortOrder)
|
||||
StoreSortedGroup(self.groupItems[groupId], groupId)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user