為了降低模塊間的耦合, 很多系統(tǒng)使用事件派發(fā)機(jī)制, 接收方無需知道派發(fā)者是誰.在Qt中,這個系統(tǒng)被稱作Slot&Signal, 需要配合moc代碼生成機(jī)制, 但是系統(tǒng)本身是線程安全的.
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"
--[[
數(shù)據(jù)層次
["EventName1"] =
{
["_StaticFunc"] = { Func1, Func2 },
[Object1] = { Func1, Func2 },
[Object2] = { Func1, Func2 },
},
["EventName2"] =
{
...
}
]]
-- 默認(rèn)調(diào)用函數(shù)
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
-- 設(shè)置調(diào)用前回調(diào)
function SetDispatchHook( Self, HookFunc )
Self.mPreInvokeFunc = HookFunc
end
-- 派發(fā)
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
-- 回調(diào)是否存在
function Exist( Self, EventName )
assert( EventName )
local Event = Self.mEventTable[ EventName ]
if not Event then
return false
end
-- 需要遍歷下map, 可能有事件名存在, 但是沒有任何回調(diào)的
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
-- 清除對象的所有回調(diào)
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”進(jìn)行調(diào)用