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.

140 lines
3.8 KiB

local _, private = ...
local isRetail = WOW_PROJECT_ID == (WOW_PROJECT_MAINLINE or 1)
local tinsert, twipe = table.insert, table.wipe
---------------
-- Prototype --
---------------
local modulePrototype = {}
function modulePrototype:RegisterEvents(...)
local function HandleEvent(_, event, ...)
local handler = self[event]
if handler then
handler(self, ...)
end
end
for _, event in ipairs({...}) do
if event:sub(0, 5) == "UNIT_" then
local eventData = {strsplit(" ", event)}
if eventData[1]:sub(-11) == "_UNFILTERED" then
self.frame:RegisterEvent(eventData[1]:sub(0, -12))
else
if #eventData < 2 then
eventData = {eventData[1], "boss1", "boss2", "boss3", "boss4", "boss5", "target"}
if isRetail then
tinsert(eventData, "focus")
end
end
for i = 2, #eventData do
local unitId = eventData[i]
local frame = self.unitFrames[unitId]
if not frame then
frame = CreateFrame("Frame")
if unitId == "mouseover" then
frame:SetScript("OnEvent", function(_, event, _, ...)
HandleEvent(nil, event, "mouseover", ...)
end)
else
frame:SetScript("OnEvent", HandleEvent)
end
self.unitFrames[unitId] = frame
end
frame:RegisterUnitEvent(eventData[1], unitId)
end
end
else
self.frame:RegisterEvent(event)
end
end
end
function modulePrototype:RegisterShortTermEvents(...)
self:RegisterEvents(...)
for _, event in ipairs({...}) do
tinsert(self.shortTermEvents, event)
end
end
function modulePrototype:UnregisterShortTermEvents()
for _, event in ipairs(self.shortTermEvents) do
if event:sub(0, 5) == "UNIT_" and event:sub(-11) ~= "_UNFILTERED" then
local eventData = {strsplit(" ", event)}
if #eventData < 2 then
eventData = {eventData[1], "boss1", "boss2", "boss3", "boss4", "boss5", "target"}
if isRetail then
tinsert(eventData, "focus")
end
end
local eventName = eventData[1]
for i = 2, #eventData do
if self.unitFrames[eventData[i]] then
self.unitFrames[eventData[i]]:UnregisterEvent(eventName)
end
end
elseif event:sub(-11) == "_UNFILTERED" then
self.frame:UnregisterEvent(event:sub(0, -12))
else
self.frame:UnregisterEvent(event)
end
end
twipe(self.shortTermEvents)
end
-------------
-- Modules --
-------------
local modules = {}
function private:NewModule(name)
if modules[name] then
error("DBM:NewModule(): Module names must be unique", 2)
end
local frame = CreateFrame("Frame", "DBM" .. name)
local obj = setmetatable({
frame = frame,
unitFrames = {},
shortTermEvents = {}
}, {
__index = modulePrototype
})
frame:SetScript("OnEvent", function(_, event, ...)
if event:sub(0, 5) == "UNIT_" and event ~= "UNIT_DIED" and event ~= "UNIT_DESTROYED" then
-- UNIT_* events that come from mainFrame are _UNFILTERED variants and need their suffix
event = event .. "_UNFILTERED"
end
local handler = obj[event]
if handler then
handler(obj, ...)
end
end)
modules[name] = obj
return obj
end
function private:GetModule(name)
return modules[name]
end
--Needed in certain cases where we need to initialize module stuff after DBM Core loads
function private:OnModuleLoad()
for _, mod in pairs(modules) do
if mod.OnModuleLoad then
mod:OnModuleLoad()
end
end
end
--As more and more of DBM core gets modulized, it'd be a large waste of memory to store each and every modules tables in private.
--Therefor, modules tables should be localized and use this method (which is called in EndCombat in DBM Core)
--This will wipe module tables that can't wipe themselves when their functions get terminated early
function private:ClearModuleTasks()
for _, mod in pairs(modules) do
if mod.OnModuleEnd then
mod:OnModuleEnd()
end
end
end