lua消息机制

结合上一篇的内容:https://www.cnblogs.com/chenggg/p/13722086.html

参考一个消息管理器的设计 这个还存在点问题没有考虑到方法中存在协程的情况 稍微改下就可以

 

--[[
-- added by wsh @ 2017-11-28
-- 消息系统
-- 使用范例:
-- local Messenger = require "Framework.Common.Messenger";
-- local TestEventCenter = Messenger.New() --创建消息中心
-- TestEventCenter:AddListener(Type, callback) --添加监听
-- TestEventCenter:AddListener(Type, callback, ...) --添加监听
-- TestEventCenter:Broadcast(Type, ...) --发送消息
-- TestEventCenter:RemoveListener(Type, callback, ...) --移除监听
-- TestEventCenter:Cleanup() --清理消息中心
-- 注意:
-- 1、模块实例销毁时,要自动移除消息监听,不移除的话不能自动清理监听
-- 2、使用弱引用,即使监听不手动移除,消息系统也不会持有对象引用,所以对象的销毁是不受消息系统影响的
-- 3、换句话说:广播发出,回调一定会被调用,但回调参数中的实例对象,可能已经被销毁,所以回调函数一定要注意判空
--]]

--注册一个到Key为 {__cname = Messager,...}的表到 BaseClass的_class中  并将下面的方法填充到本类的虚表中
local Messenger = BaseClass("Messenger");

local function __init(self)
    self.events = {}
end

local function __delete(self)
    self.events = nil    
    self.error_handle = nil
end

--添加监听 通过":"调用 参数为类型和回调   ...为e_listtener对应的方法
local function AddListener(self, e_type, e_listener, ...)
    local event = self.events[e_type]
    if event == nil then
        --为每一个e_type都创建一个对Key弱引用的表
        event = setmetatable({}, {__mode = "k"})
    end
    --查重
    for k, v in pairs(event) do
        if k == e_listener then
            error("Aready cotains listener : "..tostring(e_listener))
            return
        end
    end
    --为每一个e_listener都创建一个对Key,Value弱引用的表
    event[e_listener] = setmetatable(SafePack(...), {__mode = "kv"}) 
    self.events[e_type] = event;
end

--广播事件
local function Broadcast(self, e_type, ...)
    local event = self.events[e_type]
    if event == nil then
        return
    end
    
    for k, v in pairs(event) do
        assert(k ~= nil)
        local args = ConcatSafePack(v, SafePack(...))
        k(SafeUnpack(args))
    end
end
--移除类型部分命令
local function RemoveListener(self, e_type, e_listener)
    local event = self.events[e_type]
    if event == nil then
        return
    end

    event[e_listener] = nil
end

local function RemoveListenerByType(self, e_type)
    self.events[e_type] = nil
end

local function Cleanup(self)
    self.events = {};
end

Messenger.__init = __init
Messenger.__delete = __delete
Messenger.AddListener = AddListener
Messenger.Broadcast = Broadcast
Messenger.RemoveListener = RemoveListener
Messenger.RemoveListenerByType = RemoveListenerByType
Messenger.Cleanup = Cleanup

return Messenger;

 

posted on 2020-09-24 17:57  深秋大街道  阅读(594)  评论(0编辑  收藏  举报

导航