Lua実装イベントディスパッチ
17227 ワード
モジュール間の結合を低減するために、多くのシステムはイベント配布メカニズムを使用し、受信者は配布者が誰であるかを知る必要はない.Qtでは、このシステムをSlot&Signalと呼ぶ、mocコードの生成メカニズムに合わせる必要があるが、システム自体はスレッドが安全である.
ここではluaのイベント配布メカニズムについて議論します.私はこれをluaモジュールと書いて、cocos 2 dxと協力して論理処理を行うのに便利です.
ここで注意してください.私はEventDispatcherです.luaはCoreディレクトリの下に配置されているため、require「Core.EventDispatcher」を使用して呼び出す必要があります.
使用例
ここではluaのイベント配布メカニズムについて議論します.私はこれをluaモジュールと書いて、cocos 2 dxと協力して論理処理を行うのに便利です.
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
ここで注意してください.私はEventDispatcherです.luaはCoreディレクトリの下に配置されているため、require「Core.EventDispatcher」を使用して呼び出す必要があります.
使用例
local EventDispatcher = require 'Core.EventDispatcher'
local E = EventDispatcher.New()
E:Add( "a", function( a, b ) print( a, b ) end )
local Func = function( a ) print( a ) end
E:Add( "a", Func )
E:Dispatch("a", 1, 2 )
print( E:Exist("a"), E:Exist("b"))
E:Remove("a", Func )
E:Dispatch("a", 1, 2 )
print( E:Exist("a"), E:Exist("b"))