cocos2d-x-LuaProxy学习日志(8) -- Lua实现事件派发器

简介:


      为了降低模块间的耦合, 很多系统使用事件派发机制, 接收方无需知道派发者是谁.在Qt中,这个系统被称作Slot&Signal, 需要配合moc代码生成机制, 但是系统本身是线程安全的.这里我们讨论的是lua的事件派发机制, 我将此写成lua模块, 方便配合cocos2dx-LuaProxy进行逻辑处理.


实现:


代码如下:

EventDispatcher.lua

local Global = _G
local package = _G.package
local setmetatable = _G.setmetatable
local assert = _G.assert
local table = _G.table
local pairs = _G.pairs
local ipairs = _G.ipairs
 
 
module "Core.EventDispatcher"
 
--[[
数据层次
 
["EventName1"] =
{
    ["_StaticFunc"] = { Func1, Func2 },
    
    [Object1] = { Func1, Func2 },
    [Object2] = { Func1, Func2 },
},
 
["EventName2"] =
{
    ...
}
 
]]
 
-- 默认调用函数
local function PreInvoke( EventName, Func, Object, UserData, ... )
    if Object then
        Func( Object, EventName, ... )
    else
        Func( EventName, ... )
    end
 
end
 
function New( )    
    
    local NewObj = setmetatable( {}, { __index = package.loaded["Core.EventDispatcher"] } )
    -- 对象成员初始化
    NewObj.mPreInvokeFunc = PreInvoke
    NewObj.mEventTable = {}
    return NewObj
end
 
-- 添加
function Add( Self, EventName, Func, Object, UserData )
    assert( Func )
    Self.mEventTable[ EventName ] = Self.mEventTable[ EventName ] or {}
    local Event = Self.mEventTable[ EventName ]

    if not Object then
        Object = "_StaticFunc"
    end
    
    Event[Object] = Event[Object] or {}
    local ObjectEvent = Event[Object]
 
    ObjectEvent[Func] = UserData or true
    
end
 
-- 设置调用前回调
function SetDispatchHook( Self, HookFunc )
    
    Self.mPreInvokeFunc = HookFunc
end
 
-- 派发
function Dispatch( Self, EventName, ... )
 
    assert( EventName )
    
    local Event = Self.mEventTable[ EventName ]
    
    for Object,ObjectFunc in pairs( Event ) do
        
        if Object == "_StaticFunc" then
                
            for Func, UserData in pairs( ObjectFunc ) do
                Self.mPreInvokeFunc( EventName, Func, nil, UserData, ... )    
            end
            
        else
        
            for Func, UserData in pairs( ObjectFunc ) do
                Self.mPreInvokeFunc( EventName, Func, Object, UserData, ... )
            end
        
        end
 
    end
 
end
 
-- 回调是否存在
function Exist( Self, EventName )
 
    assert( EventName )
    
    local Event = Self.mEventTable[ EventName ]
    
    if not Event then
        return false
    end
    
    -- 需要遍历下map, 可能有事件名存在, 但是没有任何回调的
    for Object,ObjectFunc in pairs( Event ) do
    
        for Func, _ in pairs( ObjectFunc ) do
            -- 居然有一个
            return true
        end
    
    end
    
    
    return false
    
end
 
-- 清除
function Remove( Self, EventName, Func, Object )
    
    assert( Func )
    
    local Event = Self.mEventTable[ EventName ]
    
    if not Event then
        return
    end
    
    if not Object then
        Object = "_StaticFunc"
    end   
    
    local ObjectEvent = Event[Object]
    
    if not ObjectEvent then
        return
    end
    
    ObjectEvent[Func] = nil
      
end
 
-- 清除对象的所有回调
function RemoveObjectAllFunc( Self, EventName, Object )

    assert( Object )
    
    local Event = Self.mEventTable[ EventName ]
    
    if not Event then
        return
    end
    
    Event[Object] = nil
 
end

测试代码:

hello.lua

local  EventDispatcher = require 'Core.EventDispatcher'
local  E = EventDispatcher.New()

print("**************")

E:Add( "ABC.ADA.ADA", function( a, b )  print("我是什么时候执行的1")  print( a, b ) end )

local Func = function( a )  print("我是什么时候执行的2") print( a ) end 
E:Add( "b", Func )

E:Dispatch("ABC.ADA.ADA", 1 )
   print( "这里是打印1",E:Exist("ABC"), E:Exist("ABC"))
 
E:Remove("b", Func )

E:Dispatch("ABC.ADA.ADA", 1, 2 )
    print( "这里是打印2",E:Exist("a"), E:Exist("b"))


输出结果:

Cocos2d: [LUA-print] **************

Cocos2d: [LUA-print]我是什么时候执行的1

Cocos2d: [LUA-print] ABC.ADA.ADA1

Cocos2d: [LUA-print]这里是打印1false false

Cocos2d: [LUA-print]我是什么时候执行的1

Cocos2d: [LUA-print] ABC.ADA.ADA1

Cocos2d: [LUA-print]这里是打印2false false


引用博文:http://www.cppblog.com/sunicdavy/archive/2013/04/24/199692.html?opt=admin


转载请注明出处:http://blog.csdn.net/rexuefengye/article/details/16855971

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热血枫叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值