I might as well post mine, I have many versions of this and I don't even know if this is the latest one. I keep recreating it for every addon I need it in.
Lua Code:
local Name,Addon=...;
local C_Timer_After=C_Timer.After;
local next=next;
local pairs=pairs;
local setmetatable=setmetatable;
local tostring=tostring;
local type=type;
--------------------------
--[[ Event Frame ]]
--------------------------
local function OnEvent(self,event,...)
local list=self[event];
if list and next(list) then
for funcobj in pairs(list) do funcobj[0](funcobj,event,...); end
else
self:UnregisterEvent(event);
end
end
local EventFrame=CreateFrame("Frame");
EventFrame:SetScript("OnEvent",OnEvent);
------------------------------------------
--[[ Callback Object Registry ]]
------------------------------------------
local CallbackMeta={__index={},__call=function(t,...) return t[0](t,...); end};
local FuncObject=setmetatable({},{__index=function(t,k) local obj=setmetatable({[0]=k},CallbackMeta); t[k],t[obj]=obj,obj; return obj; end});
function CallbackMeta.__index:RegisterEvent(...)-- Obj:RegisterEvent(Event<s>) -or- Addon.RegisterEvent(Func/Obj,Event<s>)
self=FuncObject[self];-- Make sure we have our custom object (Can be used as an AddOn API call)
for i=1,select("#",...) do
local event=tostring(select(i,...)):upper();
local list=EventFrame[event];
if not list then list={}; EventFrame[event]=list; end
if not list[self] then
list[self]=true;
EventFrame:RegisterEvent(event);
end
end
return self;
end
function CallbackMeta.__index:UnregisterEvent(...)-- Obj:UnregisterEvent(Event<s>) -or- Addon.UnregisterEvent(Func/Obj,Event<s>)
self=FuncObject[self];-- Make sure we have our custom object (Can be used as an AddOn API call)
local argcount=select("#",...);
if argcount>0 then
for i=1,argcount do
local event=tostring(select(i,...)):upper();
local list=EventFrame[event];
if list then
list[self]=nil;
if not next(list) then EventFrame:UnregisterEvent(event); end
end
end
else
for i,j in pairs(EventFrame) do
if type(j)=="table" then j[self]=nil; end
end
end
return self;
end
function CallbackMeta.__index:DelayedCall(delay) C_Timer_After(delay,self[0]); end
----------------------------------
--[[ API Registration ]]
----------------------------------
Addon.RegisterEvent=CallbackMeta.__index.RegisterEvent;
Addon.UnregisterEvent=CallbackMeta.__index.UnregisterEvent;
function Addon.FireEvent(event,...) OnEvent(EventFrame,tostring(event):upper(),...); end
function Addon.GetCallbackObject(func) return FuncObject[func]; end