diff --git a/ComboPointTracker.lua b/ComboPointTracker.lua index 23d8e17..11f229d 100644 --- a/ComboPointTracker.lua +++ b/ComboPointTracker.lua @@ -745,7 +745,7 @@ function Extension.OnLoad() Extension.RegisterEvent("SPELLCAST_FAILED", "OnSpellcastFailed") Extension.RegisterEvent("SPELLCAST_INTERRUPTED", "OnSpellcastInterrupted") Extension.RegisterEvent("PLAYER_TARGET_CHANGED", "OnTargetChanged") - Extension.RegisterEvent("UNIT_AURA", "OnUnitAura") + Extension.RegisterUnitEvent("UNIT_AURA", "OnUnitAura", "target", "player") Extension.RegisterEvent("PLAYER_COMBO_POINTS", "OnComboPointsChanged") -- PERFORMANCE OPTIMIZATION: Removed OnUpdate polling for combo points @@ -765,10 +765,10 @@ function Extension.OnTargetChanged() CleveRoids.UpdateComboPoints() end +-- Registered as a unit event for target and player, so arg1 is always one of +-- those two -- no token check needed. function Extension.OnUnitAura() - if arg1 == "target" or arg1 == "player" then - CleveRoids.UpdateComboPoints() - end + CleveRoids.UpdateComboPoints() end function Extension.OnComboPointsChanged() diff --git a/Core.lua b/Core.lua index 97eea0a..91de01d 100644 --- a/Core.lua +++ b/Core.lua @@ -591,6 +591,10 @@ frame:SetScript("OnEvent", function() if type(CleveRoidMacros.macrocheck) ~= "number" then CleveRoidMacros.macrocheck = 1 -- enabled by default end + + -- The saved realtime setting is only readable now; the unit streams were + -- registered at load assuming event-driven mode. + CleveRoids.ApplyUnitStreamEvents() end) -- Queues a full update of all action bars. @@ -4464,18 +4468,36 @@ if type(C_LossOfControl) == "table" then CleveRoids.Frame:RegisterEvent("LOSS_OF_CONTROL_ADDED") CleveRoids.Frame:RegisterEvent("LOSS_OF_CONTROL_UPDATE") end --- Use GUID events when available (v2.39+), fall back to standard per-token events +-- The unit state streams that drive icon refresh: GUID events when Nampower +-- provides them (v2.39+, one event per unit change rather than one per token), +-- else the stock per-token events. These cannot become RegisterUnitEvent calls +-- -- the handlers ignore the unit and refresh every macro, because a conditional +-- may name any unit ([@party3,hp:<50], @focus, @mouseover), so narrowing the +-- token set would leave those icons stale. +local unitStreamEvents if CleveRoids.NampowerAPI.features.hasUnitGuidEvents then - CleveRoids.Frame:RegisterEvent("UNIT_AURA_GUID") - CleveRoids.Frame:RegisterEvent("UNIT_HEALTH_GUID") - CleveRoids.Frame:RegisterEvent("UNIT_MANA_GUID") - CleveRoids.Frame:RegisterEvent("UNIT_RAGE_GUID") - CleveRoids.Frame:RegisterEvent("UNIT_ENERGY_GUID") + unitStreamEvents = { "UNIT_AURA_GUID", "UNIT_HEALTH_GUID", "UNIT_MANA_GUID", "UNIT_RAGE_GUID", "UNIT_ENERGY_GUID" } else - CleveRoids.Frame:RegisterEvent("UNIT_AURA") - CleveRoids.Frame:RegisterEvent("UNIT_HEALTH") - CleveRoids.Frame:RegisterEvent("UNIT_POWER") + unitStreamEvents = { "UNIT_AURA", "UNIT_HEALTH", "UNIT_POWER" } end + +-- They do fire continuously for every unit in range, and in realtime mode their +-- handlers do nothing at all: the OnUpdate refreshes on every throttled tick and +-- QueueActionUpdate no-ops. Rather than pay a Lua dispatch per event to return +-- early, drop the registrations entirely while realtime is on. Re-applied at +-- VARIABLES_LOADED (when the saved value is first known) and whenever +-- `/cleveroid realtime` flips it. +function CleveRoids.ApplyUnitStreamEvents() + local eventDriven = not CleveRoidMacros or CleveRoidMacros.realtime == 0 + for i = 1, table.getn(unitStreamEvents) do + if eventDriven then + CleveRoids.Frame:RegisterEvent(unitStreamEvents[i]) + else + CleveRoids.Frame:UnregisterEvent(unitStreamEvents[i]) + end + end +end +CleveRoids.ApplyUnitStreamEvents() if CleveRoids.hasSuperwow then CleveRoids.Frame:RegisterEvent("UNIT_CASTEVENT") end @@ -5808,6 +5830,8 @@ SlashCmdList["CLEVEROID"] = function(msg) local num = tonumber(val) if num == 0 or num == 1 then CleveRoidMacros.realtime = num + -- The unit streams are only worth receiving in event-driven mode. + CleveRoids.ApplyUnitStreamEvents() CleveRoids.Print("realtime set to " .. num) else CleveRoids.Print("Usage: /cleveroid realtime 0 or 1 - Force realtime updates rather than event based updates (Default: 0. 1 = on, increases CPU load.)") diff --git a/ExtensionsManager.lua b/ExtensionsManager.lua index b0cb84f..ff6a62a 100644 --- a/ExtensionsManager.lua +++ b/ExtensionsManager.lua @@ -66,6 +66,10 @@ function CleveRoids.RegisterExtension(name) CleveRoids.RegisterEvent(name, eventName, callbackName) end + extension.RegisterUnitEvent = function(eventName, callbackName, ...) + CleveRoids.RegisterUnitEvent(name, eventName, callbackName, unpack(arg)) + end + extension.Hook = function(functionName, callbackName, dontCallOriginal) CleveRoids.RegisterHook(name, functionName, callbackName, dontCallOriginal) end @@ -146,6 +150,20 @@ function CleveRoids.RegisterEvent(extensionName, eventName, callbackName) extension.internal.frame:RegisterEvent(eventName) end +-- Registers a callback for a UNIT_* event, filtered to the given unit tokens. +-- The callback then only runs for those units: the client drops every other +-- unit's copy, instead of all of them reaching Lua to be compared away. Use +-- this over RegisterEvent whenever the handler starts by testing arg1. +-- extensionName: The name of the extension trying to register the callback +-- eventName: The UNIT_* event to register +-- callbackName: The name of the callback that gets called when the event fires +-- ...: the unit tokens to accept (e.g. "player", "target") +function CleveRoids.RegisterUnitEvent(extensionName, eventName, callbackName, ...) + local extension = CleveRoids.Extensions[extensionName] + extension.internal.eventHandlers[eventName] = callbackName + extension.internal.frame:RegisterUnitEvent(eventName, unpack(arg)) +end + -- Hooks the given function by it's name -- extensionName: The name of the extension trying to register the callback -- functionName: The name of the function that'll be hooked diff --git a/Utility.lua b/Utility.lua index 72a4297..419a631 100644 --- a/Utility.lua +++ b/Utility.lua @@ -4115,7 +4115,7 @@ end) local ev = CreateFrame("Frame", "CleveRoidsLibDebuffFrame", UIParent) ev:RegisterEvent("PLAYER_TARGET_CHANGED") -ev:RegisterEvent("UNIT_AURA") +ev:RegisterUnitEvent("UNIT_AURA", "target") ev:RegisterEvent("ADDON_LOADED") -- For pfUI integration initialization ev:RegisterEvent("ZONE_CHANGED_NEW_AREA") -- Clear known enemy GUIDs on zone change @@ -4214,7 +4214,7 @@ ev:SetScript("OnEvent", function() end SeedUnit("target") - elseif event == "UNIT_AURA" and arg1 == "target" then + elseif event == "UNIT_AURA" then SeedUnit("target") elseif event == "UNIT_CASTEVENT" then