diff --git a/Bagnon/components/item.lua b/Bagnon/components/item.lua index e5c8324..9bded9a 100644 --- a/Bagnon/components/item.lua +++ b/Bagnon/components/item.lua @@ -248,6 +248,38 @@ end --[[ Update Methods ]] -- +-- Lag-race protection for slots that read nil briefly after being occupied. +-- When this happens we keep the prior draw and schedule ONE re-check at the +-- grace deadline; we never poll. After the deadline, whatever the live read +-- says wins, so genuinely emptied slots resolve within GRACE_WINDOW seconds. +local GRACE_WINDOW = 0.5 +local pendingVerify = {} -- slot -> deadline (GetTime) +local verifyFrame = CreateFrame('Frame') +verifyFrame:Hide() +verifyFrame:SetScript('OnUpdate', function(self, elapsed) + self.tick = (self.tick or 0) + elapsed + if self.tick < 0.1 then return end + self.tick = 0 + local now = GetTime() + for slot, deadline in pairs(pendingVerify) do + if now >= deadline then + pendingVerify[slot] = nil + if slot:IsVisible() then + slot:Update() + end + end + end + if not next(pendingVerify) then + self:Hide() + end +end) + +local function scheduleVerify(slot) + if pendingVerify[slot] then return end + pendingVerify[slot] = GetTime() + GRACE_WINDOW + verifyFrame:Show() +end + -- Update the texture, lock status, and other information about an item function ItemSlot:Update() @@ -255,6 +287,18 @@ function ItemSlot:Update() local texture, count, locked, quality, readable, lootable, link = self:GetItemSlotInfo() + -- If the slot was occupied at our last good draw and the live read just + -- returned nil within the grace window, keep the previous draw and queue + -- a single re-check. No retry storm. + if (not link) and self.hasItem and (self.lastGoodTime or 0) + GRACE_WINDOW > GetTime() then + scheduleVerify(self) + return + end + + if link then + self.lastGoodTime = GetTime() + end + self:SetItem(link) self:SetTexture(texture) self:SetCount(count)