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;
  • 相关阅读:
    C#XML操作详解
    浏览器检测JS代码(兼容目前各大主流浏览器)
    C# DataTable 详解
    MyEclipse设置java文件每行字符数
    springmvc,hibernate整合时候出现Cannot load JDBC driver class 'com.mysql.jdbc.Driver
    org.apache.catalina.util.DefaultAnnotationProcessor cannot be cast to org.apache.AnnotationProcessor
    hibernate使用注解生成表,有时无法生成数据表的原因
    rtthread STM32F4以太网
    STM32F4闹钟
    Keil MDK下如何设置非零初始化变量(转)
  • 原文地址:https://www.cnblogs.com/chenggg/p/13725501.html
Copyright © 2011-2022 走看看