事件分发器

作者: maikesen | 来源:发表于2018-03-22 10:06 被阅读0次

    这个分发器是之前做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)

    相关文章

      网友评论

        本文标题:事件分发器

        本文链接:https://www.haomeiwen.com/subject/ooioqftx.html