zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    Entity Framework Core 2.0 新特性
    asp.net core部署时自定义监听端口,提高部署的灵活性
    asp.net core使用jexus部署在linux无法正确 获取远程ip的解决办法
    使用xshell连接服务器,数字键盘无法使用解决办法
    使用Jexus 5.8.2在Centos下部署运行Asp.net core
    【DevOps】DevOps成功的八大炫酷工具
    【Network】Calico, Flannel, Weave and Docker Overlay Network 各种网络模型之间的区别
    【Network】UDP 大包怎么发? MTU怎么设置?
    【Network】高性能 UDP 应该怎么做?
    【Network】golang 容器项目 flannel/UDP相关资料
  • 原文地址:https://www.cnblogs.com/chenggg/p/13725501.html
Copyright © 2011-2022 走看看