Files
Guda-ClassicAPI/Core/CacheWarmer.lua
T

115 lines
4.9 KiB
Lua

-- Guda CacheWarmer
-- Pre-warms ItemDetection and category-related tooltip caches shortly after
-- PLAYER_LOGIN so the first bag open does not pay for cold tooltip scans.
--
-- Guda ClassicAPI uses the low-latency FIFO in Core/Performance.lua. Heavy
-- tooltip operations stay as separate work items so a single callback cannot
-- accidentally bundle several expensive tooltip scans into one frame.
local addon = Guda
local CacheWarmer = {}
addon.Modules.CacheWarmer = CacheWarmer
-- Populate the real BagScanner cache once. The original implementation called
-- ScanBag() for bags 0-4 but discarded every returned table, then GetBagData()
-- immediately scanned the bags again. Returning GetBagData() here makes the
-- warmup useful and gives the later stages the exact cached snapshot.
function CacheWarmer:WarmBagScanner()
local BagScanner = Guda.Modules.BagScanner
if not BagScanner or not BagScanner.GetBagData then return nil end
return BagScanner:GetBagData()
end
-- Queue tooltip/cache work using the already-cached BagScanner snapshot.
-- This avoids another round of GetContainerNumSlots/GetContainerItemLink and
-- avoids GetItemInfo calls just to discover the item class.
function CacheWarmer:WarmItemDetectionCache(bagData)
local Utils = Guda.Modules.Utils
local ItemDetection = Guda.Modules.ItemDetection
local CategoryManager = Guda.Modules.CategoryManager
local BagScanner = Guda.Modules.BagScanner
if not (Utils and Utils.QueueWork) then return end
if not (ItemDetection and ItemDetection.GetItemProperties) then return end
bagData = bagData or (BagScanner and BagScanner.GetBagData
and BagScanner:GetBagData())
if not bagData then return end
for bagID = 0, 4 do
local bag = bagData[bagID]
if bag and bag.slots then
for slotID, slotData in pairs(bag.slots) do
if slotData and slotData.link then
local b, s = bagID, slotID
local snapshot = {
link = slotData.link,
itemID = slotData.itemID,
name = slotData.name,
class = slotData.class,
type = slotData.type,
subclass = slotData.subclass,
quality = slotData.quality,
texture = slotData.texture,
equipSlot = slotData.equipSlot,
}
-- Central property scan. Keep this as its own queue item:
-- SetBagItem can be expensive on a cold client cache.
Utils:QueueWork(function()
ItemDetection:GetItemProperties(snapshot, b, s)
end, "CacheWarmer.itemDetection")
-- Only consumables need the restore-text tooltip cache.
if snapshot.class == "Consumable"
and Utils.GetConsumableRestoreTag then
Utils:QueueWork(function()
snapshot.restoreTag =
Utils:GetConsumableRestoreTag(b, s, snapshot.link)
end, "CacheWarmer.restoreTag")
end
-- Only equipment can be Bind on Equip.
if (snapshot.class == "Weapon" or snapshot.class == "Armor")
and Utils.IsBindOnEquip then
Utils:QueueWork(function()
Utils:IsBindOnEquip(b, s, snapshot.link)
end, "CacheWarmer.boe")
end
-- Runs after the relevant warmers because the queue is FIFO,
-- so category rules hit warm ItemDetection/tooltip caches.
if CategoryManager and CategoryManager.CategorizeItem then
Utils:QueueWork(function()
CategoryManager:CategorizeItem(snapshot, b, s, false)
end, "CacheWarmer.category")
end
end
end
end
end
end
function CacheWarmer:Initialize()
-- Defer startup work so we do not compete with the login frame.
Guda_ScheduleTimer(0.5, function()
local bagData = CacheWarmer:WarmBagScanner()
CacheWarmer:WarmItemDetectionCache(bagData)
-- Completion marker runs after all prior FIFO work drains.
local Utils = Guda.Modules.Utils
if Utils and Utils.QueueWork then
Utils:QueueWork(function()
if Guda_BagFrame and Guda_BagFrame:IsShown()
and Guda.Modules.BagFrame and Guda.Modules.BagFrame.Update then
Guda.Modules.BagFrame:Update()
end
if Guda_BagFrame_UpdateAllUsabilityTints then
Guda_BagFrame_UpdateAllUsabilityTints()
end
end, "CacheWarmer.completionSweep")
end
end)
end