You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.5 KiB

--[[
Manage events for all state drivers
]]
local ADDON_NAME, Internal = ...
local External = _G[ADDON_NAME]
local EventHandler = CreateFrame("Frame")
EventHandler.targets = {}
local _RegisterEvent = EventHandler.RegisterEvent
local _UnregisterEvent = EventHandler.UnregisterEvent
function EventHandler:RegisterEvent(target, event, callback, prio)
if not self.targets[event] then
self.targets[event] = setmetatable({}, {__mode="k"})
end
if next(self.targets[event]) == nil then
pcall(function ()
_RegisterEvent(self, event)
end)
end
if not self.targets[event][target] then
self.targets[event][target] = {}
end
self.targets[event][target][callback or "OnEvent"] = prio or 0
end
function EventHandler:UnregisterEvent(target, event, callback)
if not self.targets[event] then
return
end
if not self.targets[event][target] then
return
end
if callback == nil then
self.targets[event][target] = nil
else
self.targets[event][target][callback or "OnEvent"] = nil
if next(self.targets[event][target]) == nil then
self.targets[event][target] = nil
end
end
if next(self.targets[event]) == nil then
pcall(function ()
_UnregisterEvent(self, event)
end)
self.targets[event] = nil
end
end
function EventHandler:UnregisterEventsFor(target)
for event in pairs(self.targets) do
self:UnregisterEvent(target, event)
end
end
function EventHandler:OnEvent(event, ...)
if self.targets[event] then
self.event = event
local sorted = {}
for target,callbacks in pairs(self.targets[event]) do
for callback,prio in pairs(callbacks) do
if type(callback) == "string" then
callback = target[callback]
end
sorted[#sorted+1] = {target = target, func = callback, prio = prio}
end
end
table.sort(sorted, function (a, b)
return a.prio < b.prio
end)
for _,callback in ipairs(sorted) do
if callback.target == Internal then
callback.func(event, ...)
else
callback.func(callback.target, event, ...)
end
end
self.event = nil
end
end
EventHandler:SetScript("OnEvent", EventHandler.OnEvent)
function Internal.GetActiveEvent()
return EventHandler.event
end
function External.TriggerEvent(event, ...)
EventHandler:OnEvent(event, ...)
end
function Internal.RegisterEvent(target, event, callback, prio)
if target == nil then
target = Internal
end
if type(target) == "string" then -- Optional target arguement
target, event, callback, prio = Internal, target, event, callback
end
assert(target ~= Internal or callback ~= nil, "callback required with no target set")
EventHandler:RegisterEvent(target, event, callback, prio)
end
function Internal.UnregisterEvent(target, event, callback)
if type(target) == "string" then -- Optional target arguement
target, event, callback = Internal, target, event
end
assert(target ~= Internal or callback ~= nil, "callback required with no target set")
EventHandler:UnregisterEvent(target, event, callback)
end
function Internal.UnregisterEventsFor(target)
assert(target ~= Internal, "cannot clear all events for Internal")
EventHandler:UnregisterEventsFor(target)
end