Hi AMR devs,
I investigated a small but persistent CPU issue in the current addon version. The addon appears to keep consuming a lot of CPU time even when the main panel is closed, and the root cause looks like the custom Amr.Wait helper in Core.lua.
Amr.Wait creates a frame named AmrWaitFrame and attaches an OnUpdate handler, but it never clears that handler or hides the frame after the wait queue becomes empty. Since startup initialization schedules a delayed wait via Amr.Wait(5, …), the frame starts running after login and continues receiving OnUpdate forever, even when no waits are pending and the AMR UI is closed.
Relevant code path:
-- Core.lua
local _waitTable = {}
local _waitFrame = nil
function Amr.Wait(delay, func, ...)
if not _waitFrame then
_waitFrame = CreateFrame("Frame", "AmrWaitFrame", UIParent)
_waitFrame:SetScript("OnUpdate", function (self, elapse)
local count = #_waitTable
local i = 1
while(i <= count) do
local waitRecord = table.remove(_waitTable, i)
local d = table.remove(waitRecord, 1)
local f = table.remove(waitRecord, 1)
local p = table.remove(waitRecord, 1)
if d > elapse then
table.insert(_waitTable, i, { d-elapse, f, p })
i = i + 1
else
count = count - 1
f(unpack(p))
end
end
end)
end
table.insert(_waitTable, { delay, func, {...} })
return true
end
Suggested fix: make the wait frame active only while _waitTable has pending callbacks. For example:
local _waitTable = {}
local _waitFrame = nil
local function onWaitFrameUpdate(self, elapse)
local count = #_waitTable
local i = 1
while(i <= count) do
local waitRecord = table.remove(_waitTable, i)
local d = table.remove(waitRecord, 1)
local f = table.remove(waitRecord, 1)
local p = table.remove(waitRecord, 1)
if d > elapse then
table.insert(_waitTable, i, { d-elapse, f, p })
i = i + 1
else
count = count - 1
f(unpack(p))
end
end
if #_waitTable == 0 then
self:SetScript("OnUpdate", nil)
self:Hide()
end
end
function Amr.Wait(delay, func, ...)
if not _waitFrame then
_waitFrame = CreateFrame("Frame", "AmrWaitFrame", UIParent)
_waitFrame:Hide()
end
table.insert(_waitTable, { delay, func, {...} })
if not _waitFrame:IsShown() then
_waitFrame:SetScript("OnUpdate", onWaitFrameUpdate)
_waitFrame:Show()
end
return true
end
The important cases should still work:
- A queued wait wakes the frame.
- The frame stays active while a wait is pending.
- The frame clears OnUpdate and hides itself once the queue drains.
- A wait callback can schedule another Amr.Wait, and the frame remains active for the newly queued wait.
This should remove the continuous idle OnUpdate CPU cost without changing any other event-driven background features.
Thanks!