转自:http://www.cppblog.com/sunicdavy/archive/2013/04/24/199692.html?opt=admin
之前想把在unity用c#实现的事件系统转到lua上实现,一搜,果然也有人实现了,那就直接拿来用了,也谢谢上面这篇博主的分享。
local Global = _Glocal package = _G.packagelocal setmetatable = _G.setmetatablelocal assert = _G.assertlocal table = _G.tablelocal pairs = _G.pairslocal ipairs = _G.ipairsmodule "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, ... ) endendfunction New( ) local NewObj = setmetatable( {}, { __index = package.loaded["EventDispatcher"] } ) -- 对象成员初始化 NewObj.mPreInvokeFunc = PreInvoke NewObj.mEventTable = {} return NewObjend-- 添加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 trueend-- 设置调用前回调function SetDispatchHook( Self, HookFunc ) Self.mPreInvokeFunc = HookFuncend-- 派发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 endend-- 回调是否存在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 falseend-- 清除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] = nilend-- 清除对象的所有回调function RemoveObjectAllFunc( Self, EventName, Object ) assert( Object ) local Event = Self.mEventTable[ EventName ] if not Event then return end Event[Object] = nilend
用例:
1 local EventDispatcher = require 'EventDispatcher' 2 3 local E = EventDispatcher.New() 4 5 6 E:Add( "a", function( a, b ) print( a, b ) end ) 7 8 local Func = function( a ) print( a ) end 9 E:Add( "a", Func )10 11 12 E:Dispatch("a", 1, 2 )13 print( E:Exist("a"), E:Exist("b"))14 15 E:Remove("a", Func )16 17 E:Dispatch("a", 1, 2 )18 print( E:Exist("a"), E:Exist("b"))
结语:发现lua真的很好用,用得好也很强大,将c#的东西用lua实现一遍的时候发现代码量少了很多。