Bastion aims to serve as a highly performant, simplisitic, and expandable World of Warcraft data visualization framework.
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.
Bastion/src/EventManager/EventManager.lua

170 lines
4.5 KiB

---@type Tinkr
local Tinkr,
---@class Bastion
Bastion = ...
-- Create an EventManager class
---@class Bastion.EventManager
---@field frame Frame
---@field events table<string, { [number]: fun(...) }>
---@field eventHandlers table<string, { [number]: fun(...) }>
---@field wowEventHandlers table<WowEvent, { [number]: { sendEvent: boolean, fun: fun(...) } }>
---@field selfCombatEventHandlers table<string, { [number]: fun(...) }>
---@field CombatEventHandlers table<string, { [number]: fun(...) }>
---@field playerGUID string|boolean
local EventManager = {
events = {},
eventHandlers = {},
wowEventHandlers = {},
selfCombatEventHandlers = {
["*"] = {},
},
CombatEventHandlers = {
["*"] = {},
},
}
EventManager.__index = EventManager
-- Constructor
---@return Bastion.EventManager
function EventManager:New()
local self = setmetatable({}, EventManager)
self.playerGUID = UnitGUID("player") or false
-- Frame for wow events
self.frame = CreateFrame("Frame")
self.frame:SetScript("OnEvent", function(f, event, ...)
if self.wowEventHandlers[event] then
for _, eventHandler in ipairs(self.wowEventHandlers[event]) do
if eventHandler.sendEvent then
eventHandler.fun(event, ...)
else
eventHandler.fun(...)
end
end
end
end)
self:RegisterWoWEvent("COMBAT_LOG_EVENT_UNFILTERED", function()
self:CLEUHandler(CombatLogGetCurrentEventInfo())
end)
return self
end
-- Register an event
---@param event string
---@param handler fun(...)
---@return nil
function EventManager:RegisterEvent(event, handler)
if not self.events[event] then
self.events[event] = {}
end
table.insert(self.events[event], handler)
end
-- Register a wow event
---@param events WowEvent | WowEvent[]
---@param handler fun(...)
---@param sendEvent? boolean
function EventManager:RegisterWoWEvent(events, handler, sendEvent)
if type(events) == "string" then
events = { events }
end
for _, event in ipairs(events) do
if not self.wowEventHandlers[event] then
self.wowEventHandlers[event] = {}
self.frame:RegisterEvent(event)
end
table.insert(self.wowEventHandlers[event], {
fun = handler,
sendEvent = sendEvent or false,
})
end
end
-- Trigger an event
---@param event string
---@param ... any
function EventManager:TriggerEvent(event, ...)
if self.events[event] then
for _, handler in pairs(self.events[event]) do
handler(...)
end
end
end
---@param subevents string | string[]
---@param handler fun(...)
function EventManager:RegisterSelfCombatEvent(subevents, handler)
if type(subevents) == "string" then
subevents = { subevents }
end
for _, subevent in ipairs(subevents) do
if not self.selfCombatEventHandlers[subevent] then
self.selfCombatEventHandlers[subevent] = {}
end
table.insert(self.selfCombatEventHandlers[subevent], handler)
end
end
---@param subevents string | string[]
---@param handler fun(...)
function EventManager:RegisterCombatEvent(subevents, handler)
if type(subevents) == "string" then
subevents = { subevents }
end
for _, subevent in ipairs(subevents) do
if not self.CombatEventHandlers[subevent] then
self.CombatEventHandlers[subevent] = {}
end
table.insert(self.CombatEventHandlers[subevent], handler)
end
end
---@param ... any
function EventManager:CLEUHandler(...)
---@type number
local timestamp = select(1, ...)
---@type string
local subevent = select(2, ...)
---@type string
local sourceGUID = select(4, ...)
---@type string
local destGUID = select(8, ...)
local keys = {
subevent,
"*"
}
local isSelf = self.playerGUID and sourceGUID == self.playerGUID
for _, key in ipairs(keys) do
if isSelf then
if self.selfCombatEventHandlers[key] then
for _, callback in ipairs(self.selfCombatEventHandlers[key]) do
callback(...)
end
end
end
if self.CombatEventHandlers[key] then
for _, callback in ipairs(self.CombatEventHandlers[key]) do
callback(...)
end
end
end
end
function EventManager:SetOnUpdate(func)
self.frame:SetScript("OnUpdate", func)
end
Bastion.EventManager = EventManager
--Bastion.Globals.EventManager = Bastion.EventManager:New()