WoWInterface SVN RaidWatch2

[/] [trunk/] [RaidWatch_Core/] [BasePlugins/] [Comm.lua] - Rev 22

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

Compare with Previous | Blame