diff --git a/RelationshipsQuestAndItemBrowser.lua b/RelationshipsQuestAndItemBrowser.lua index 4e78aa5..5828378 100644 --- a/RelationshipsQuestAndItemBrowser.lua +++ b/RelationshipsQuestAndItemBrowser.lua @@ -2484,23 +2484,100 @@ local function RQL_ProcessChatFrame(frame) end end -local RQL_PLUS_TIMER = 0 +-- Event-driven [+] scanning. +-- +-- The old implementation ran a full chat-frame scan ~33 times per second +-- (every 0.03s) regardless of whether chat had changed. On busy zones / +-- raids that constant `frame:GetRegions()` + regex work was a real source +-- of random lag spikes (GC pressure from throwaway region tables). +-- +-- Now we scan only when: +-- * a CHAT_MSG_* event arrives (with a tiny delay so the chat frame has +-- laid out the new region before we measure it), or +-- * the user scrolls / resizes a chat frame (hooked below), or +-- * the addon just finished loading (initial pass over existing chat). +-- +-- Scans are rate-limited to at most one every RQL_SCAN_MIN_INTERVAL. +local RQL_SCAN_MIN_INTERVAL = 0.25 -- hard cap: no more than 4 scans/sec +local RQL_SCAN_DELAY = 0.05 -- delay after event so regions are laid out +local RQL_SCAN_PENDING_AT = nil +local RQL_SCAN_LAST_AT = 0 + +function RQL_SchedulePlusScan(delay) + local now = GetTime() + local at = now + (delay or RQL_SCAN_DELAY) + local earliest = RQL_SCAN_LAST_AT + RQL_SCAN_MIN_INTERVAL + if at < earliest then at = earliest end + if not RQL_SCAN_PENDING_AT or at < RQL_SCAN_PENDING_AT then + RQL_SCAN_PENDING_AT = at + end +end + +-- Called every frame from the main OnUpdate. Cheap when idle: two compares +-- and an early return. Only does real work when a scan is due. function RQL_PlusTick(elapsed) - RQL_PLUS_TIMER = RQL_PLUS_TIMER + (elapsed or 0) - if RQL_PLUS_TIMER < 0.03 then return end - RQL_PLUS_TIMER = 0 + if not RQL_SCAN_PENDING_AT then return end + if GetTime() < RQL_SCAN_PENDING_AT then return end + RQL_SCAN_PENDING_AT = nil + RQL_SCAN_LAST_AT = GetTime() + RQL_PoolIndex = 0 local maxFrames = NUM_CHAT_WINDOWS or 7 for i = 1, maxFrames do local f = getglobal("ChatFrame" .. i) - if f then RQL_ProcessChatFrame(f) end + -- IsVisible() is false for docked tabs that aren't the front tab + -- and for hidden / minimized chat windows, so we naturally skip + -- all of those. + if f and f.IsVisible and f:IsVisible() then + RQL_ProcessChatFrame(f) + end end RQL_HideUnusedButtons() end +-- Watcher frame that listens for chat traffic and requests a rescan. +local RQL_ChatWatch = CreateFrame("Frame", "RQL_ChatWatch") +local RQL_CHAT_EVENTS = { + "CHAT_MSG_SAY", "CHAT_MSG_YELL", "CHAT_MSG_EMOTE", "CHAT_MSG_TEXT_EMOTE", + "CHAT_MSG_WHISPER", "CHAT_MSG_WHISPER_INFORM", + "CHAT_MSG_PARTY", "CHAT_MSG_RAID", "CHAT_MSG_RAID_LEADER", "CHAT_MSG_RAID_WARNING", + "CHAT_MSG_GUILD", "CHAT_MSG_OFFICER", + "CHAT_MSG_CHANNEL", + "CHAT_MSG_SYSTEM", "CHAT_MSG_LOOT", "CHAT_MSG_TRADESKILLS", + "CHAT_MSG_BATTLEGROUND", "CHAT_MSG_BATTLEGROUND_LEADER", +} +for i = 1, table.getn(RQL_CHAT_EVENTS) do + RQL_ChatWatch:RegisterEvent(RQL_CHAT_EVENTS[i]) +end +RQL_ChatWatch:SetScript("OnEvent", function() + RQL_SchedulePlusScan() +end) + local function RQL_HookChatLinks() - -- Nothing to hook up-front; the OnUpdate ticker in the event handler - -- calls RQL_PlusTick() every frame and it drives everything else. + -- Chat scrolling / paging moves existing linked lines but doesn't fire + -- an event. Wrap the standard scroll helpers so [+] follows the text. + local names = { "ScrollUp", "ScrollDown", "ScrollToTop", + "ScrollToBottom", "PageUp", "PageDown" } + local maxFrames = NUM_CHAT_WINDOWS or 7 + for i = 1, maxFrames do + local f = getglobal("ChatFrame" .. i) + if f then + for j = 1, table.getn(names) do + local n = names[j] + local flag = "_rql_hooked_" .. n + if f[n] and not f[flag] then + local orig = f[n] + f[flag] = orig + f[n] = function() + orig(f) + RQL_SchedulePlusScan() + end + end + end + end + end + -- Do one pass shortly after login so already-visible chat gets [+]. + RQL_SchedulePlusScan(0.3) end -- ---------- events / slash ---------- diff --git a/RelationshipsQuestAndItemBrowser.toc b/RelationshipsQuestAndItemBrowser.toc index 1107b21..cabd6c3 100644 --- a/RelationshipsQuestAndItemBrowser.toc +++ b/RelationshipsQuestAndItemBrowser.toc @@ -2,7 +2,7 @@ ## Title: Relationships Quest And Item Browser ## Notes: Click quest and item links in chat, browse and search the full quest and item database. ## Author: Relationship -## Version: 1.0 +## Version: 1.1 ## SavedVariables: RelationshipsQuestAndItemBrowserDB RelationshipsQuestAndItemBrowser.xml RelationshipsQuestAndItemBrowserData_Init.lua