----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- local _detalhes = _G.Details local Loc = LibStub("AceLocale-3.0"):GetLocale ( "Details" ) local _ local addonName, Details222 = ... --Event types: _detalhes.RegistredEvents = { --instances ["DETAILS_INSTANCE_OPEN"] = {}, ["DETAILS_INSTANCE_CLOSE"] = {}, ["DETAILS_INSTANCE_SIZECHANGED"] = {}, ["DETAILS_INSTANCE_STARTRESIZE"] = {}, ["DETAILS_INSTANCE_ENDRESIZE"] = {}, ["DETAILS_INSTANCE_STARTSTRETCH"] = {}, ["DETAILS_INSTANCE_ENDSTRETCH"] = {}, ["DETAILS_INSTANCE_CHANGESEGMENT"] = {}, ["DETAILS_INSTANCE_CHANGEATTRIBUTE"] = {}, ["DETAILS_INSTANCE_CHANGEMODE"] = {}, ["DETAILS_INSTANCE_NEWROW"] = {}, --misc ["DETAILS_OPTIONS_MODIFIED"] = {}, ["UNIT_SPEC"] = {}, ["UNIT_TALENTS"] = {}, ["PLAYER_TARGET"] = {}, ["DETAILS_PROFILE_APPLYED"] = {}, --data ["DETAILS_DATA_RESET"] = {}, ["DETAILS_DATA_SEGMENTREMOVED"] = {}, --combat ["COMBAT_ENCOUNTER_START"] = {}, ["COMBAT_ENCOUNTER_END"] = {}, ["COMBAT_PLAYER_ENTER"] = {}, ["COMBAT_PLAYER_LEAVE"] = {}, ["COMBAT_PLAYER_TIMESTARTED"] = {}, ["COMBAT_BOSS_WIPE"] = {}, ["COMBAT_BOSS_DEFEATED"] = {}, ["COMBAT_BOSS_FOUND"] = {}, ["COMBAT_INVALID"] = {}, ["COMBAT_PREPOTION_UPDATED"] = {}, ["COMBAT_CHARTTABLES_CREATING"] = {}, ["COMBAT_CHARTTABLES_CREATED"] = {}, ["COMBAT_ENCOUNTER_PHASE_CHANGED"] = {}, ["COMBAT_ARENA_START"] = {}, ["COMBAT_ARENA_END"] = {}, ["COMBAT_MYTHICDUNGEON_START"] = {}, ["COMBAT_MYTHICDUNGEON_END"] = {}, --area ["ZONE_TYPE_CHANGED"] = {}, --roster ["GROUP_ONENTER"] = {}, ["GROUP_ONLEAVE"] = {}, --buffs ["BUFF_UPDATE"] = {}, ["BUFF_UPDATE_DEBUFFPOWER"] = {}, --network ["REALM_CHANNEL_ENTER"] = {}, --deprecated (realm channels are disabled) ["REALM_CHANNEL_LEAVE"] = {}, --deprecated ["COMM_EVENT_RECEIVED"] = {}, --added on core 129 ["COMM_EVENT_SENT"] = {}, --added on core 129 } local function AlreadyRegistred (_tables, _object) for index, _this_object in ipairs(_tables) do if (_this_object.__eventtable) then if (_this_object [1] == _object) then return index end elseif (_this_object == _object) then return index end end return false end local common_events = { ["DETAILS_INSTANCE_OPEN"] = true, ["DETAILS_INSTANCE_CLOSE"] = true, ["DETAILS_INSTANCE_SIZECHANGED"] = true, ["DETAILS_INSTANCE_STARTRESIZE"] = true, ["DETAILS_INSTANCE_ENDRESIZE"] = true, ["DETAILS_INSTANCE_STARTSTRETCH"] = true, ["DETAILS_INSTANCE_ENDSTRETCH"] = true, ["DETAILS_INSTANCE_CHANGESEGMENT"] = true, ["DETAILS_INSTANCE_CHANGEATTRIBUTE"] = true, ["DETAILS_INSTANCE_CHANGEMODE"] = true, ["DETAILS_INSTANCE_NEWROW"] = true, ["DETAILS_OPTIONS_MODIFIED"] = true, ["DETAILS_DATA_RESET"] = true, ["DETAILS_DATA_SEGMENTREMOVED"] = true, ["COMBAT_ENCOUNTER_START"] = true, ["COMBAT_ENCOUNTER_END"] = true, ["COMBAT_PLAYER_ENTER"] = true, ["COMBAT_PLAYER_LEAVE"] = true, ["COMBAT_PLAYER_TIMESTARTED"] = true, ["COMBAT_BOSS_WIPE"] = true, ["COMBAT_BOSS_DEFEATED"] = true, ["COMBAT_BOSS_FOUND"] = true, ["COMBAT_INVALID"] = true, ["COMBAT_PREPOTION_UPDATED"] = true, ["COMBAT_CHARTTABLES_CREATING"] = true, ["COMBAT_CHARTTABLES_CREATED"] = true, ["COMBAT_ENCOUNTER_PHASE_CHANGED"] = true, ["COMBAT_ARENA_START"] = true, ["COMBAT_ARENA_END"] = true, ["COMBAT_MYTHICDUNGEON_START"] = true, ["COMBAT_MYTHICDUNGEON_END"] = true, ["GROUP_ONENTER"] = true, ["GROUP_ONLEAVE"] = true, ["ZONE_TYPE_CHANGED"] = true, ["REALM_CHANNEL_ENTER"] = true, ["REALM_CHANNEL_LEAVE"] = true, ["COMM_EVENT_RECEIVED"] = true, ["COMM_EVENT_SENT"] = true, ["UNIT_SPEC"] = true, ["UNIT_TALENTS"] = true, ["PLAYER_TARGET"] = true, ["DETAILS_PROFILE_APPLYED"] = true, } ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --register a event function _detalhes:RegisterEvent(object, event, func) if (not _detalhes.RegistredEvents [event]) then if (object.Msg) then object:DelayMsg ("[debug] unknown event:", event, object.__name) else _detalhes:DelayMsg ("[debug] unknown event:", event, object.__name) end return end if (common_events [event]) then if (not AlreadyRegistred (_detalhes.RegistredEvents [event], object)) then if (func) then tinsert(_detalhes.RegistredEvents [event], {object, func, __eventtable = true}) else tinsert(_detalhes.RegistredEvents [event], object) end return true else return false end else if (event == "BUFF_UPDATE") then if (not AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE"], object)) then if (func) then tinsert(_detalhes.RegistredEvents ["BUFF_UPDATE"], {object, func, __eventtable = true}) else tinsert(_detalhes.RegistredEvents ["BUFF_UPDATE"], object) end _detalhes.Buffs:CatchBuffs() _detalhes.RecordPlayerSelfBuffs = true _detalhes:UpdateParserGears() return true else return false end elseif (event == "BUFF_UPDATE_DEBUFFPOWER") then if (not AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], object)) then if (func) then tinsert(_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], {object, func, __eventtable = true}) else tinsert(_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], object) end _detalhes.RecordPlayerAbilityWithBuffs = true _detalhes:UpdateDamageAbilityGears() _detalhes:UpdateParserGears() return true else return false end end end end ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Unregister a Event function _detalhes:UnregisterEvent (object, event) if (not _detalhes.RegistredEvents [event]) then if (object.Msg) then object:Msg("(debug) unknown event", event) else _detalhes:Msg("(debug) unknown event", event) end return end if (common_events [event]) then local index = AlreadyRegistred (_detalhes.RegistredEvents [event], object) if (index) then table.remove (_detalhes.RegistredEvents [event], index) return true else return false end else if (event == "BUFF_UPDATE") then local index = AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE"], object) if (index) then table.remove (_detalhes.RegistredEvents ["BUFF_UPDATE"], index) if (#_detalhes.RegistredEvents ["BUFF_UPDATE"] < 1) then _detalhes.RecordPlayerSelfBuffs = true _detalhes:UpdateParserGears() end return true else return false end elseif (event == "BUFF_UPDATE_DEBUFFPOWER") then local index = AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], object) if (index) then table.remove (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], index) if (#_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"] < 1) then _detalhes.RecordPlayerAbilityWithBuffs = false _detalhes:UpdateDamageAbilityGears() _detalhes:UpdateParserGears() end return true else return false end end end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --internal functions local dispatch_error = function(name, errortext) _detalhes:Msg((name or ""), " |cFFFF9900error|r: ", errortext) end --safe call an external func with payload and without telling who is calling function _detalhes:QuickDispatchEvent (func, event, ...) if (type(func) ~= "function") then return elseif (type(event) ~= "string") then return end local okay, errortext = pcall(func, event, ...) if (not okay) then --trigger an error msg dispatch_error (_, errortext) return end return true end --quick dispatch with context, send the caller object within the payload function _detalhes:QuickDispatchEventWithContext (context, func, event, ...) if (type(context) ~= "table") then return elseif (type(func) ~= "function") then return elseif (type(event) ~= "string") then return end local okay, errortext = pcall(func, context, event, ...) if (not okay) then --attempt to get the context name local objectName = context.__name or context._name or context.name or context.Name --trigger an error msg dispatch_error (objectName, errortext) return end return true end --Send Event function _detalhes:SendEvent(event, object, ...) --send event to all registred plugins if (event == "PLUGIN_DISABLED" or event == "PLUGIN_ENABLED") then return object:OnDetailsEvent (event, ...) elseif (not object) then --iterate among all plugins which registered a function for this event for _, PluginObject in ipairs(_detalhes.RegistredEvents[event]) do --when __eventtable is true, the plugin registered a function or method name to callback --if is false, we call OnDetailsEvent method on the plugin if (PluginObject.__eventtable) then local pluginTable = PluginObject [1] --check if the plugin is enabled if (pluginTable.Enabled and pluginTable.__enabled) then --check if fegistered a function if (type(PluginObject [2]) == "function") then local func = PluginObject [2] _detalhes:QuickDispatchEvent (func, event, ...) --PluginObject [2] (event, ...) --if not it must be a method name else local methodName = PluginObject [2] local func = pluginTable [methodName] _detalhes:QuickDispatchEventWithContext (pluginTable, func, event, ...) --PluginObject [1] [PluginObject [2]] (PluginObject, event, ...) end end --if no function(only registred the event) sent the event to OnDetailsEvent else if (PluginObject.Enabled and PluginObject.__enabled) then _detalhes:QuickDispatchEventWithContext (PluginObject, PluginObject.OnDetailsEvent, event, ...) --PluginObject:OnDetailsEvent (event, ...) end end end --plugin notifications (does not send to listeners) elseif (type(object) == "string" and object == "SEND_TO_ALL") then for _, PluginObject in ipairs(_detalhes.RaidTables.Plugins) do if (PluginObject.__enabled) then _detalhes:QuickDispatchEventWithContext (PluginObject, PluginObject.OnDetailsEvent, event) --PluginObject:OnDetailsEvent (event) end end for _, PluginObject in ipairs(_detalhes.SoloTables.Plugins) do if (PluginObject.__enabled) then _detalhes:QuickDispatchEventWithContext (PluginObject, PluginObject.OnDetailsEvent, event) --PluginObject:OnDetailsEvent (event) end end for _, PluginObject in ipairs(_detalhes.ToolBar.Plugins) do if (PluginObject.__enabled) then _detalhes:QuickDispatchEventWithContext (PluginObject, PluginObject.OnDetailsEvent, event) --PluginObject:OnDetailsEvent (event) end end else --send the event only for requested plugin if (object.Enabled and object.__enabled) then return _detalhes:QuickDispatchEventWithContext (object, object.OnDetailsEvent, event, ...) --return object:OnDetailsEvent (event, ...) end end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --special cases function _detalhes:SendOptionsModifiedEvent (instance) _detalhes.last_options_modified = _detalhes.last_options_modified or (GetTime() - 5) if (_detalhes.last_options_modified + 0.3 < GetTime()) then _detalhes:SendEvent("DETAILS_OPTIONS_MODIFIED", nil, instance) _detalhes.last_options_modified = GetTime() if (_detalhes.last_options_modified_schedule) then _detalhes:CancelTimer(_detalhes.last_options_modified_schedule) _detalhes.last_options_modified_schedule = nil end else if (_detalhes.last_options_modified_schedule) then _detalhes:CancelTimer(_detalhes.last_options_modified_schedule) end _detalhes.last_options_modified_schedule = _detalhes:ScheduleTimer("SendOptionsModifiedEvent", 0.31, instance) end end ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --listeners local listener_meta = setmetatable({}, _detalhes) listener_meta.__index = listener_meta function listener_meta:RegisterEvent(event, func) return _detalhes:RegisterEvent(self, event, func) end function listener_meta:UnregisterEvent (event) return _detalhes:UnregisterEvent (self, event) end function _detalhes:CreateEventListener() local new = {Enabled = true, __enabled = true} setmetatable(new, listener_meta) return new end