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

前端之家收集整理的这篇文章主要介绍了[cocos2dx]事件分发机制--lua源码(二)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

使用过程

--加载组件
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.lua
local Component = import("..Component")
local EventProtocol = class("EventProtocol",Component)

function EventProtocol:ctor()
    EventProtocol.super.ctor(self,"EventProtocol")
    self.listeners_ = {}
    self.nextListenerHandleIndex_ = 0
end

function 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,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 handle
end

function EventProtocol:dispatchEvent(event)
    event.name = string.upper(tostring(event.name))
    local eventName = event.name
    if DEBUG > 1 then
        printInfo("%s [EventProtocol] dispatchEvent() - event %s",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",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",eventName)
            end
            break
        end
    end

    return self.target_
end

function 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",eventName)
                end
                return self.target_
            end
        end
    end

    return self.target_
end

function EventProtocol:removeEventListenersByTag(tagToRemove)
    for eventName,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",eventName)
                end
            end
        end
    end

    return self.target_
end

function EventProtocol:removeEventListenersByEvent(eventName)
    self.listeners_[string.upper(eventName)] = nil
    if DEBUG > 1 then
        printInfo("%s [EventProtocol] removeAllEventListenersForEvent() - remove all listeners for event %s",eventName)
    end
    return self.target_
end

function EventProtocol:removeAllEventListeners()
    self.listeners_ = {}
    if DEBUG > 1 then
        printInfo("%s [EventProtocol] removeAllEventListeners() - remove all listeners",tostring(self.target_))
    end
    return self.target_
end

function 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 false
end

function 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_
end

function EventProtocol:exportMethods()
    self:exportMethods_({
        "addEventListener","dispatchEvent","removeEventListener","removeEventListenersByTag","removeEventListenersByEvent","removeAllEventListenersForEvent","removeAllEventListeners","hasEventListener","dumpAllEventListeners",})
    return self.target_
end

function EventProtocol:onBind_()
end

function EventProtocol:onUnbind_()
end

return EventProtocol

从源码可以看出,

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

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

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

猜你在找的Cocos2d-x相关文章