为了降低模块间的耦合, 很多系统使用事件派发机制, 接收方无需知道派发者是谁.在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://blog.csdn.net/rexuefengye/article/details/16855971