diff --git a/Bagnon/utility/itemEvents.lua b/Bagnon/utility/itemEvents.lua index fbd0dcc..acc1843 100644 --- a/Bagnon/utility/itemEvents.lua +++ b/Bagnon/utility/itemEvents.lua @@ -46,14 +46,6 @@ Bagnon.BagEvents = BagEvents local slots = {} local bagTypes = {} local pendingBags = {} -local retryCounts = {} - --- Retry knobs. Server lag spikes on Ascension can easily exceed a second; --- keep retrying so we don't broadcast an empty slot while item data is still --- in flight. Accept whatever we read after RETRY_MAX attempts so a genuinely --- emptied slot eventually resolves. -local RETRY_INTERVAL = 0.25 -local RETRY_MAX = 12 -- ~3s worst case local function ToIndex(bag, slot) return (bag < 0 and bag*100 - slot) or bag*100 + slot @@ -63,20 +55,20 @@ local function GetBagSize(bag) return (bag == KEYRING_CONTAINER and GetKeyRingSize()) or GetContainerNumSlots(bag) end +-- Defers a re-check of a bag by ~0.25s; used when a previously occupied slot +-- reads back nil (lag race between BAG_UPDATE and item data arriving). local retryFrame = CreateFrame('Frame') retryFrame.elapsed = 0 retryFrame:Hide() retryFrame:SetScript('OnUpdate', function(self, elapsed) self.elapsed = self.elapsed + elapsed - if self.elapsed < RETRY_INTERVAL then return end + if self.elapsed < 0.25 then return end self.elapsed = 0 + self:Hide() local bags = pendingBags pendingBags = {} for bag in pairs(bags) do - Bagnon.BagEvents:UpdateItems(bag) - end - if not next(pendingBags) then - self:Hide() + Bagnon.BagEvents:UpdateItems(bag, true) end end) @@ -142,9 +134,8 @@ function BagEvents:RemoveItem(bag, slot) end end -function BagEvents:UpdateItem(bag, slot) - local index = ToIndex(bag, slot) - local data = slots[index] +function BagEvents:UpdateItem(bag, slot, isRetry) + local data = slots[ToIndex(bag, slot)] if data then local prevLink = data[1] @@ -155,17 +146,12 @@ function BagEvents:UpdateItem(bag, slot) local onCooldown = (start > 0 and duration > 0 and enable > 0) -- A previously occupied slot reading back nil is usually a lag race between - -- BAG_UPDATE and item data arriving from the server. Keep deferring up to - -- RETRY_MAX times so a multi-second lag spike doesn't flash items empty. - if prevLink and (not link) then - local n = (retryCounts[index] or 0) + 1 - if n < RETRY_MAX then - retryCounts[index] = n - scheduleRetry(bag) - return - end + -- BAG_UPDATE and item data arriving from the server. Defer once before drawing + -- the slot as empty; on the second pass we trust whatever we read. + if prevLink and (not link) and (not isRetry) then + scheduleRetry(bag) + return end - retryCounts[index] = nil if not(prevLink == link and prevCount == count) then data[1] = link @@ -178,9 +164,9 @@ function BagEvents:UpdateItem(bag, slot) end end -function BagEvents:UpdateItems(bag) +function BagEvents:UpdateItems(bag, isRetry) for slot = 1, GetBagSize(bag) do - self:UpdateItem(bag, slot) + self:UpdateItem(bag, slot, isRetry) end end