mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
c8bc4c134d
Two handlers opened by testing arg1 against a fixed set of unit tokens, so every other unit's copy of UNIT_AURA reached Lua only to be compared away -- in a raid that is the bulk of them. ClassicAPI's RegisterUnitEvent pushes that filter into the client, so the handler only runs for the units named. Filtering is per (frame, event), so the other events sharing the libdebuff frame are unaffected. Utility.lua UNIT_AURA -> "target" (libdebuff seeding) ComboPointTracker UNIT_AURA -> "target", "player" Extensions register through CleveRoids.RegisterEvent, so ExtensionsManager gains a RegisterUnitEvent alongside it. Separately, the main frame's unit state streams (UNIT_AURA / UNIT_HEALTH / UNIT_POWER, or the _GUID variants under Nampower v2.39+) are now registered only in event-driven mode. Their handlers are wholly wrapped in `realtime == 0`, so with realtime on every one of them crossed into Lua and returned immediately while the OnUpdate did the refreshing. Registration is applied at load, again at VARIABLES_LOADED once the saved setting is readable, and whenever /cleveroid realtime flips it. Those three stay plain RegisterEvent calls: their handlers ignore the unit and refresh every macro, and a conditional may name any unit ([@party3,hp:<50], @focus, @mouseover), so narrowing the token set would leave those icons stale. The _GUID variants could not be filtered anyway -- their first argument is a GUID, not a unit token.
263 lines
9.3 KiB
Lua
263 lines
9.3 KiB
Lua
--[[
|
|
Author: Dennis Werner Garske (DWG) / brian / Mewtiny
|
|
License: MIT License
|
|
]]
|
|
local _G = _G or getfenv(0)
|
|
local CleveRoids = _G.CleveRoids or {}
|
|
|
|
-- A list of all registered extensions
|
|
CleveRoids.Extensions = CleveRoids.Extensions or {}
|
|
|
|
-- Calls the "OnLoad" function of every extension
|
|
function CleveRoids.InitializeExtensions()
|
|
for k, v in pairs(CleveRoids.Extensions) do
|
|
local func = v["OnLoad"]
|
|
if not func then
|
|
CleveRoids.Print("CleveRoids.InitializeExtensions - Couldn't find 'OnLoad' function for extension "..k)
|
|
else
|
|
func()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Removes the given hook
|
|
-- hook: The hook to remove
|
|
function CleveRoids.RemoveHook(hook)
|
|
_G[hook.name] = hook.original
|
|
end
|
|
|
|
-- Removes the given hook from the given object
|
|
-- object: The object to remove the hook from
|
|
-- hook: The hook to remove
|
|
function CleveRoids.RemoveMethodHook(object, hook)
|
|
object[hook.name] = hook.original
|
|
end
|
|
|
|
-- Clears all previously declared hooks
|
|
function CleveRoids.ClearHooks()
|
|
for k, v in pairs(CleveRoids.Extensions) do
|
|
for k2, v2 in pairs(v.internal.memberHooks) do
|
|
for k3, v3 in pairs(v2) do
|
|
CleveRoids.RemoveMethodHook(k2, v3)
|
|
end
|
|
end
|
|
|
|
for k2, v2 in pairs(v.internal.hooks) do
|
|
CleveRoids.RemoveHook(v2)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Creates a new extension with the given name
|
|
-- name: the name of the extension
|
|
function CleveRoids.RegisterExtension(name)
|
|
local extension = {
|
|
internal =
|
|
{
|
|
frame = CreateFrame("FRAME"),
|
|
eventHandlers = {},
|
|
hooks = {},
|
|
memberHooks = {},
|
|
activeHooks = {}, -- Re-entrancy guard: tracks hooks currently executing
|
|
},
|
|
}
|
|
|
|
extension.RegisterEvent = function(eventName, callbackName)
|
|
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
|
|
|
|
extension.HookMethod = function(object, functionName, callbackName, dontCallOriginal)
|
|
CleveRoids.RegisterMethodHook(name, object, functionName, callbackName, dontCallOriginal)
|
|
end
|
|
|
|
|
|
extension.UnregisterEvent = function(eventName, callbackName)
|
|
CleveRoids.UnregisterEvent(name, eventName, callbackName)
|
|
end
|
|
|
|
extension.internal.OnEvent = function()
|
|
local callbackName = extension.internal.eventHandlers[event]
|
|
if callbackName then
|
|
extension[callbackName]()
|
|
end
|
|
end
|
|
|
|
|
|
-- This is a function wrapper that we swap with the function that we want to hook
|
|
-- @return Value of Callback() or Origininal() if dontCallOriginal is false
|
|
extension.internal.OnHook = function(object, functionName, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
-- Generate a unique key for this hook (handles both global and method hooks)
|
|
local hookKey = tostring(object or "global") .. ":" .. functionName
|
|
|
|
-- Re-entrancy guard: if this hook is already executing, call original directly
|
|
if extension.internal.activeHooks[hookKey] then
|
|
local hook
|
|
if object then
|
|
hook = extension.internal.memberHooks[object][functionName]
|
|
else
|
|
hook = extension.internal.hooks[functionName]
|
|
end
|
|
if hook and hook.original then
|
|
return hook.original(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
end
|
|
return
|
|
end
|
|
|
|
local hook
|
|
if object then
|
|
hook = extension.internal.memberHooks[object][functionName]
|
|
else
|
|
hook = extension.internal.hooks[functionName]
|
|
end
|
|
|
|
-- Mark this hook as active
|
|
extension.internal.activeHooks[hookKey] = true
|
|
|
|
local retval = hook.callback(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
if not hook.dontCallOriginal then
|
|
retval = hook.original(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
end
|
|
|
|
-- Mark this hook as inactive
|
|
extension.internal.activeHooks[hookKey] = nil
|
|
|
|
return retval
|
|
end
|
|
|
|
|
|
extension.internal.frame:SetScript("OnEvent", extension.internal.OnEvent)
|
|
|
|
CleveRoids.Extensions[name] = extension
|
|
|
|
return extension
|
|
end
|
|
|
|
-- Registers a callback function for a given event name
|
|
-- extensionName: The name of the extension trying to register the callback
|
|
-- eventName: The event's name we'd like to register a callback for
|
|
-- callbackName: The name of the callback that get's called when the event fires
|
|
function CleveRoids.RegisterEvent(extensionName, eventName, callbackName)
|
|
local extension = CleveRoids.Extensions[extensionName]
|
|
extension.internal.eventHandlers[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
|
|
-- callbackName: The name of the callback that get's called when the hooked function is called
|
|
-- dontCallOriginal: Set to true when the original function should not be called
|
|
function CleveRoids.RegisterHook(extensionName, functionName, callbackName, dontCallOriginal)
|
|
local orig = _G[functionName]
|
|
local extension = CleveRoids.Extensions[extensionName]
|
|
|
|
if not orig then
|
|
CleveRoids.Print("CleveRoids.RegisterHook - Invalid function to hook: "..functionName)
|
|
end
|
|
|
|
if not extension then
|
|
CleveRoids.Print("CleveRoids.RegisterHook - Invalid extension: "..extension)
|
|
return
|
|
end
|
|
|
|
if not extension[callbackName] then
|
|
CleveRoids.Print("CleveRoids.RegisterHook - Couldn't find callback: "..callbackName)
|
|
return
|
|
end
|
|
|
|
|
|
extension.internal.hooks[functionName] = {
|
|
original = orig,
|
|
callback = extension[callbackName],
|
|
name = functionName,
|
|
dontCallOriginal = dontCallOriginal
|
|
}
|
|
|
|
_G[functionName] = function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
return extension.internal.OnHook(nil, functionName, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
end
|
|
end
|
|
|
|
-- Hooks the given object's function
|
|
-- object: The object you want to hook
|
|
-- extensionName: The name of the extension trying to register the callback
|
|
-- functionName: The name of the function that'll be hooked
|
|
-- callbackName: The name of the callback that get's called when the hooked function is called
|
|
function CleveRoids.RegisterMethodHook(extensionName, object, functionName, callbackName, dontCallOriginal)
|
|
if not object then
|
|
CleveRoids.Print("CleveRoids.RegisterMethodHook - The object could not be found!")
|
|
return
|
|
end
|
|
|
|
if type(object) ~= "table" then
|
|
CleveRoids.Print("CleveRoids.RegisterMethodHook - The object needs to be a table!")
|
|
return
|
|
end
|
|
|
|
local orig = object[functionName]
|
|
|
|
if not orig then
|
|
CleveRoids.Print("CleveRoids.RegisterMethodHook - The object doesn't have a function named "..functionName)
|
|
return
|
|
end
|
|
|
|
local extension = CleveRoids.Extensions[extensionName]
|
|
|
|
if not extension then
|
|
CleveRoids.Print("CleveRoids.RegisterMethodHook - Invalid extension: "..extension)
|
|
return
|
|
end
|
|
|
|
if not extension[callbackName] then
|
|
CleveRoids.Print("CleveRoids.RegisterMethodHook - Couldn't find callback: "..callbackName)
|
|
return
|
|
end
|
|
|
|
if not extension.internal.memberHooks[object] then
|
|
extension.internal.memberHooks[object] = {}
|
|
end
|
|
|
|
extension.internal.memberHooks[object][functionName] = {
|
|
original = orig,
|
|
callback = extension[callbackName],
|
|
name = functionName,
|
|
dontCallOriginal = dontCallOriginal
|
|
}
|
|
|
|
object[functionName] = function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
return extension.internal.OnHook(object, functionName, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
|
|
end
|
|
end
|
|
|
|
function CleveRoids.UnregisterEvent(extensionName, eventName, callbackName)
|
|
local extension = CleveRoids.Extensions[extensionName]
|
|
if extension.internal.eventHandlers[eventName] then
|
|
extension.internal.eventHandlers[eventName] = nil
|
|
extension.internal.frame:UnregisterEvent(eventName)
|
|
end
|
|
end
|
|
|
|
_G["CleveRoids"] = CleveRoids
|