Replace WDB tooltip warmup with GET_ITEM_INFO_RECEIVED handler

ClassicAPI hooks the global GetItemInfo to auto-warm the item cache on a
miss and fires GET_ITEM_INFO_RECEIVED when the async fill lands, so the
tooltip-scan warmup is obsolete: IndexItems's own GetItemInfo calls
already trigger the same warmup, and owned items (bags + equipped) are
priority-prefetched by the engine. The old warmup also assumed the fill
was synchronous, which no longer holds.

Drop DoWDBWarmup and its login scheduling; instead listen for
GET_ITEM_INFO_RECEIVED and run a debounced re-index. IndexItems records
owned itemIDs it could not resolve into pendingItemInfo, and the handler
ignores any fill not in that set (quest DB scans, AH sweeps, chat-link
hovers, inspects) in O(1) so unrelated bursts do not cause reindex churn.
This commit is contained in:
Brues
2026-08-21 21:02:59 -05:00
parent cf47d8caba
commit 63b484b1ea
2 changed files with 47 additions and 55 deletions
+33 -55
View File
@@ -3942,10 +3942,21 @@ function CleveRoids.OnUpdate(self)
return
end
-- PERFORMANCE: Delayed WDB warmup after login (ensures GetItemInfo works after WDB clear)
if CR.wdbWarmupTime and time >= CR.wdbWarmupTime then
CR.wdbWarmupTime = nil
CR.DoWDBWarmup()
-- Coalesced re-index after async item data arrives (GET_ITEM_INFO_RECEIVED).
-- ClassicAPI warms the item cache asynchronously, so items that were still
-- uncached during an earlier index pass land here once their
-- SMSG_ITEM_QUERY_SINGLE response resolves. Bursts are debounced into one
-- re-index via CR.itemInfoReindexTime (armed by the event handler).
if CR.itemInfoReindexTime and time >= CR.itemInfoReindexTime then
CR.itemInfoReindexTime = nil
-- In combat: drop it; PLAYER_LEAVE_COMBAT does a full re-index once safe.
if not UnitAffectingCombat("player") then
CR.lastItemIndexTime = GetTime()
CR.IndexItems()
CR.Actions = {}
CR.Macros = {}
CR.IndexActionBars()
end
end
-- PERFORMANCE: Cache refresh rate calculation (avoid per-frame division)
@@ -4824,6 +4835,7 @@ CleveRoids.Frame:RegisterEvent("UPDATE_MACROS")
CleveRoids.Frame:RegisterEvent("SPELLS_CHANGED")
CleveRoids.Frame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
CleveRoids.Frame:RegisterEvent("BAG_UPDATE_DELAYED")
CleveRoids.Frame:RegisterEvent("GET_ITEM_INFO_RECEIVED")
CleveRoids.Frame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
CleveRoids.Frame:RegisterEvent("UNIT_PET")
@@ -4964,57 +4976,6 @@ function CleveRoids.Frame:PLAYER_LOGIN()
-- PERFORMANCE: Initialize event-driven cache states
CleveRoids._cachedPlayerInCombat = UnitAffectingCombat("player") and true or false
-- Schedule delayed WDB warmup (loads items into client cache via tooltip scan)
-- This ensures GetItemInfo() works for all inventory items after a WDB clear
CleveRoids.wdbWarmupTime = GetTime() + 3.0 -- 3 second delay after login
end
-- PERFORMANCE: WDB warmup - tooltip scan all bag items to ensure they're cached
-- This prevents GetItemInfo() returning nil for items after a WDB clear
function CleveRoids.DoWDBWarmup()
if CleveRoids.wdbWarmupDone then return end
CleveRoids.wdbWarmupDone = true
-- Create a hidden tooltip for scanning if it doesn't exist
local tip = CleveRoidsWDBTip
if not tip then
tip = CreateFrame("GameTooltip", "CleveRoidsWDBTip", UIParent, "GameTooltipTemplate")
tip:SetOwner(WorldFrame, "ANCHOR_NONE")
end
local scanned = 0
-- Scan all bag slots
for bag = 0, 4 do
local slots = GetContainerNumSlots(bag) or 0
for slot = 1, slots do
if C_Container.GetContainerItemID(bag, slot) then
-- Tooltip scan loads the item into WDB
tip:ClearLines()
tip:SetBagItem(bag, slot)
scanned = scanned + 1
end
end
end
-- Scan equipped items
for slot = 1, 19 do
if GetInventoryItemID("player", slot) then
tip:ClearLines()
tip:SetInventoryItem("player", slot)
scanned = scanned + 1
end
end
-- Now trigger a full item index to populate the cache with valid data
if CleveRoids.IndexItems then
CleveRoids.IndexItems()
end
if CleveRoids.debug then
CleveRoids.Print("|cff88ff88[WDB Warmup]|r Scanned " .. scanned .. " items into cache")
end
end
function CleveRoids.Frame:ADDON_LOADED(addon)
@@ -5690,6 +5651,23 @@ function CleveRoids.Frame:ACTIONBAR_SLOT_CHANGED()
end
end
-- ClassicAPI fires GET_ITEM_INFO_RECEIVED when an async item-cache fill lands
-- (the hooked GetItemInfo auto-warms on a miss). It fires for EVERY fill in the
-- game though - quest DB scans, AH sweeps, chat-link hovers, inspects - so we
-- ignore anything not in pendingItemInfo (items we own that missed the last
-- index pass). That check is O(1) and keeps unrelated bursts free.
function CleveRoids.Frame:GET_ITEM_INFO_RECEIVED()
local pending = CleveRoids.pendingItemInfo
if not (pending and pending[arg1]) then return end
-- Skip during combat; PLAYER_LEAVE_COMBAT re-indexes once it's safe.
if UnitAffectingCombat("player") then return end
-- Arm once per burst; the update loop clears it after re-indexing. Later
-- arrivals re-arm it, guaranteeing the final resolved state is captured.
if not CleveRoids.itemInfoReindexTime then
CleveRoids.itemInfoReindexTime = GetTime() + 0.5
end
end
function CleveRoids.Frame:BAG_UPDATE_DELAYED()
-- In combat: Skip expensive indexing but still queue icon update
-- so conditionals like [inbag] re-evaluate (they use live bag APIs)