这个分发器是之前做slg的丹神写的,后面再稍微修改了存在的bug(有注释部分是修改过的)。
Dispatcher.lua
local Dispatcher = {}
Dispatcher.obj = {}
function Dispatcher:addEventListener(eventName, class, callBackFunc)
if self.obj[eventName] then
local t = self.obj[eventName]
t[class] = callBackFunc
else
local t = {}
t[class] = callBackFunc
self.obj[eventName] = t
end
end
function Dispatcher:removeEventListener(eventName, class)
local t = self.obj[eventName]
if t then
t[class] = nil
local haveAnyChild = false
for _, _ in pairs(t) do
haveAnyChild = true
break
end
if not haveAnyChild then
self.obj[eventName] = nil
end
end
if(self.temps ~= nil) then
for _,temp in pairs(self.temps) do
if(temp.eventName == eventName) then
local keys = nil
for func,class_ in pairs(temp) do
if(class_ == class) then
keys = keys or {}
keys[func] = true
end
end
if(keys ~= nil) then
for func,_ in pairs(keys) do
temp[func] = nil
end
end
end
end
end
end
function Dispatcher:removeAllEventListener()
for k, v in pairs(self.obj) do
self.obj[k] = nil
end
end
function Dispatcher:dispatchEvent(event)
-- 遍历事件的时候产生的问题:
-- 某个函数的回调中增加或移除该类型的事件监听,造成表格混乱,遍历不到或多次遍历的问题
-- 为了解决上面的问题,引入一个临时表,但又引入了新的问题:
-- 在回调中移除临时表后面的回调函数的时候,临时表中的回调没有删除,这样继续引入新的表格控制
local eventName = event["name"]
local t = self.obj[eventName]
if t then
local helper = {} -- 为了解决某个函数的回调中增加或移除该类型的事件监听,造成表格混乱,遍历不到或多次遍历的问题
self.temps = self.temps or {} -- 解决上面遍历时移除事件监听的问题
self.temps[helper] = {}
local temp = self.temps[helper]
temp.eventName = eventName
for class, func in pairs(t) do
temp[func] = class
table.insert(helper, func)
end
repeat
local func = table.remove(helper, 1)
if(not func) then break end
if(temp[func] ~= nil) then
func(event)
end
until false
self.temps[helper] = nil
end
end
return Dispatcher
用法:
新增事件监听
Dispatcher:addEventListener(Event.UI_WINDOW_CLOSE, self, handler(self, self.onWindowClose))
移除事件监听
Dispatcher:removeEventListener(Event.UI_WINDOW_CLOSE, self)
网友评论