Lua实现事件派发器(转)
转自:http://www.cppblog.com/sunicdavy/archive/2013/04/24/199692.html?opt=admin
之前想把在unity用c#实现的事件系统转到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 "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["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
用例:
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实现一遍的时候发现代码量少了很多。