Compare with Previous | Blame | View Log
--[[ Addon communication plugin ]]-- -------------------------------------- -- Create plugin local RW = LibStub("AceAddon-3.0"):GetAddon("Raid Watch") local plugin = RW:NewModule("Comm", "AceComm-3.0", "AceSerializer-3.0", "AceTimer-3.0") if not plugin then return end RW.Com = plugin local prefix = "RW2" local db local throttle function plugin:OnInitialize() self.db = RW.db:RegisterNamespace("Comm", {profile={}}) self.listeners = {} throttle = {} self:RegisterComm(prefix) end function plugin:OnEnable() end local function handleCom(self, sender, dist, success, ...) if success then local listener = ... if self.listeners[listener] then for module in pairs(self.listeners[listener]) do if module[listener] and type(module[listener]) == "function" then module[listener](module, sender, dist, select(2, ...)) else if module.OnSync then module:OnSync(listener, sender, dist, select(2, ...)) else --[===[@debug@ error(("Module %q is missing handler for %q"):format(module.GetName and module:GetName() or module, listener)) --@end-debug@]===] end end end end end end function plugin:OnCommReceived(_, message, dist, sender) handleCom(self, sender, dist, self:Deserialize(message)) end -------------------------------------- -- Message handling --- Register a message to listen for. -- @param module table The module that want to listen to the message. -- @param listener string A function with this name must exist on the module object, or the module must have an OnSync function that takes looks like func(listener, sender, dist, ...). function plugin:RegisterListener(module, listener) if RWDEBUG then assert(module and type(module) == "table", "Usage: RegisterListener(module, listener) - module must be a table") assert(listener and type(listener) == "string", "Usage: RegisterListener(module, listener) - listener must be a string") assert((module[listener] and type(module[listener]) == "function") or (module[OnSync] and type(module[OnSync]) == "function"), ("Usage: RegisterListener(module, listener) - module must have either a function named %q or %q"):format(listener, "OnSync")) end self.listeners[listener] = self.listeners[listener] or {} self.listeners[listener][module] = true end --- Unregister a listening message for a module. -- @param module table The module that wants to unregister for a message. -- @param listener string The message to stop listening for. function plugin:UnregisterListener(module, listener) if RWDEBUG then assert(module and type(module) == "table", "Usage: UnregisterListener(module, listener) - module must be a table") assert(listener and type(listener) == "string", "Usage: UnregisterListener(module, listener) - listener must be a string") end if self.listeners[listener] then self.listeners[listener][module] = nil end end --- Unregister all listening messages for a module. -- @param module table The module that wants all messages unregistered. function plugin:UnregisterAllListeners(module) assert(module and type(module) == "table", "Usage: UnregisterAllListeners(module) - module must be a table") for listener, modules in pairs(self.listeners) do modules[module] = nil end end --- Send a message over the addon communication channel -- @param comMsg string The string that ideintifies the message. -- @param dist string The distrubution to use (GUILD, RAID, WHISPER etc.) -- @optional target string The target to send the message to, only used when the dist is WHISPER. -- @optional ... data Any kind of data to send along with the message. function plugin:Send(comMsg, dist, target, ...) -- Throttle the sending of the same message one 2 seconds local message = self:Serialize(comMsg, ...) if not throttle[message..(dist or "")..(target or "")] then -- If no dist is proviced, RAID will be used over PARTY, if none of them are true then no message is sent dist = dist or (GetRealNumRaidMembers() > 0 and "RAID" or (GetRealNumPartyMembers() > 0 and "PARTY" or nil)) if dist ~= nil then self:SendCommMessage(prefix, message, dist, target) throttle[message..dist..(target or "")] = true self:ScheduleTimer("RemoveThrottle", 2, message..dist..(target or "")) end else --[===[@debug@ error(("Sending of %q"..(target ~=nil and (" to "..target) or "") .." (spammed) "..(dist or "No Dist")):format(comMsg)) --@end-debug@]===] end end function plugin:RemoveThrottle(message) throttle[message] = nil end