[cocos2dx]事件分发机制--lua源码(二)

来源:互联网 发布:linux nslookup mx 编辑:程序博客网 时间:2024/05/22 09:47

使用过程

--加载组件cc(self):addComponent("components.behavior.EventProtocol"):exportMethods()--添加监听事件self:addEventListener("EVENT_PLAYER_DEAD", handler(self, self.changePlayerHead))--分发调用消息self:dispatchEvent({name = "EVENT_PLAYER_DEAD"})
下面来看看addEventListener(),dispatchEvent()重要函数的源码

event源码

--cc.components.behavior.EventProtocol.lualocal Component = import("..Component")local EventProtocol = class("EventProtocol", Component)function EventProtocol:ctor()    EventProtocol.super.ctor(self, "EventProtocol")    self.listeners_ = {}    self.nextListenerHandleIndex_ = 0endfunction EventProtocol:addEventListener(eventName, listener, tag)    assert(type(eventName) == "string" and eventName ~= "",        "EventProtocol:addEventListener() - invalid eventName")    eventName = string.upper(eventName)    if self.listeners_[eventName] == nil then        self.listeners_[eventName] = {}    end    local ttag = type(tag)    if ttag == "table" or ttag == "userdata" then        PRINT_DEPRECATED("EventProtocol:addEventListener(eventName, listener, target) is deprecated, please use EventProtocol:addEventListener(eventName, handler(target, listener), tag)")        listener = handler(tag, listener)        tag = ""    end    self.nextListenerHandleIndex_ = self.nextListenerHandleIndex_ + 1    local handle = tostring(self.nextListenerHandleIndex_)    tag = tag or ""    self.listeners_[eventName][handle] = {listener, tag}    if DEBUG > 1 then        printInfo("%s [EventProtocol] addEventListener() - event: %s, handle: %s, tag: %s", tostring(self.target_), eventName, handle, tostring(tag))    end    return handleendfunction EventProtocol:dispatchEvent(event)    event.name = string.upper(tostring(event.name))    local eventName = event.name    if DEBUG > 1 then        printInfo("%s [EventProtocol] dispatchEvent() - event %s", tostring(self.target_), eventName)    end    if self.listeners_[eventName] == nil then return end    event.target = self.target_    event.stop_ = false    event.stop = function(self)        self.stop_ = true    end    for handle, listener in pairs(self.listeners_[eventName]) do        if DEBUG > 1 then            printInfo("%s [EventProtocol] dispatchEvent() - dispatching event %s to listener %s", tostring(self.target_), eventName, handle)        end        -- listener[1] = listener        -- listener[2] = tag        event.tag = listener[2]        listener[1](event)        if event.stop_ then            if DEBUG > 1 then                printInfo("%s [EventProtocol] dispatchEvent() - break dispatching for event %s", tostring(self.target_), eventName)            end            break        end    end    return self.target_endfunction EventProtocol:removeEventListener(handleToRemove)    for eventName, listenersForEvent in pairs(self.listeners_) do        for handle, _ in pairs(listenersForEvent) do            if handle == handleToRemove then                listenersForEvent[handle] = nil                if DEBUG > 1 then                    printInfo("%s [EventProtocol] removeEventListener() - remove listener [%s] for event %s", tostring(self.target_), handle, eventName)                end                return self.target_            end        end    end    return self.target_endfunction EventProtocol:removeEventListenersByTag(tagToRemove)    for eventName, listenersForEvent in pairs(self.listeners_) do        for handle, listener in pairs(listenersForEvent) do            -- listener[1] = listener            -- listener[2] = tag            if listener[2] == tagToRemove then                listenersForEvent[handle] = nil                if DEBUG > 1 then                    printInfo("%s [EventProtocol] removeEventListener() - remove listener [%s] for event %s", tostring(self.target_), handle, eventName)                end            end        end    end    return self.target_endfunction EventProtocol:removeEventListenersByEvent(eventName)    self.listeners_[string.upper(eventName)] = nil    if DEBUG > 1 then        printInfo("%s [EventProtocol] removeAllEventListenersForEvent() - remove all listeners for event %s", tostring(self.target_), eventName)    end    return self.target_endfunction EventProtocol:removeAllEventListeners()    self.listeners_ = {}    if DEBUG > 1 then        printInfo("%s [EventProtocol] removeAllEventListeners() - remove all listeners", tostring(self.target_))    end    return self.target_endfunction EventProtocol:hasEventListener(eventName)    eventName = string.upper(tostring(eventName))    local t = self.listeners_[eventName]    if not t then        return false    end    for _, __ in pairs(t) do        return true    end    return falseendfunction EventProtocol:dumpAllEventListeners()    print("---- EventProtocol:dumpAllEventListeners() ----")    for name, listeners in pairs(self.listeners_) do        printf("-- event: %s", name)        for handle, listener in pairs(listeners) do            printf("--     listener: %s, handle: %s", tostring(listener[1]), tostring(handle))        end    end    return self.target_endfunction EventProtocol:exportMethods()    self:exportMethods_({        "addEventListener",        "dispatchEvent",        "removeEventListener",        "removeEventListenersByTag",        "removeEventListenersByEvent",        "removeAllEventListenersForEvent",        "removeAllEventListeners",        "hasEventListener",        "dumpAllEventListeners",    })    return self.target_endfunction EventProtocol:onBind_()endfunction EventProtocol:onUnbind_()endreturn EventProtocol

从源码可以看出,

  • 函数addEventListener(eventName, listener, tag)作用就是把事件名和监听函数已key-value的形式保存到listeners_表中,已便于后续的调用。
  • 函数dispatchEvent(event)作用就是通过事件名的形式来调用监听函数。
事件分发机制的实质就是,把事件名以及监听事件名监听函数保存到一个容器中,然后通过事件名的形式来调用监听函数。

事件分发本质是采用的观察者模式: 注册观察者,事件产生并回调,取消注册。

[cocos2dx]事件分发机制(一)

0 0
原创粉丝点击