高性能事件分发器,lua 版

来源:互联网 发布:619什么意思网络用语 编辑:程序博客网 时间:2024/05/19 10:12
1.设计目标 将ui与逻辑分离 不依赖与cocos2dx,使用消息-订阅模式
2.支持长监听、一次性监听、支持多事件池,防止事件池中消息过多。发消息会有O(n)的延迟
3.采用java 中的 hash 算法 分离事件
--[[
@brief:事件分发器
@by 李俊
]]

--[[
例如我在主场景中添加了一个长监听函数
我们需要
1.声明自己的一个事件
local EVENT_UPDAT_USER_GOLD = "EVENT_UPDAT_USER_GOLD"
2.声明自己事件回调的函数
local function onUpdateUserGold(gold)
    BUI:setText(KW_BFNT_USER_GOLD,gold)
end
3.往全局事件分发器中添加函数
wolf.DispatcherUtils.addEventListener(EVENT_UPDAT_USER_GOLD,onUpdateUserGold)
4.在别的类中触发事件
wolf.DispatcherUtils.dispatchEvent(EVENT_UPDAT_USER_GOLD,"666666666")

用于实现消息订阅模式。为消息源和订阅者解耦合。例如UI只需要订阅自己的更新事件。
而service层只需要告诉分发器我发布的消息。
]]--
local Dispatcher = class("Dispatcher")

function Dispatcher:ctor()
    self._eventDispatcher = {}
end
-------------------------------------------
--订阅某个事件的常驻监听,该监听不会自动删除,适用于长监听
--@param event_name 事件名称
--@param func 监听函数
--@return listener 监听器
-------------------------------------------
function Dispatcher:addEventListener(event_name,func)
    local listener = { e=event_name , f=func }
    self._eventDispatcher[listener] = false 
    return listener
end

-------------------------------------------
--安全的订阅某个事件的常驻监听,并且会做安全检查,防止相同的监听添加,该监听不会自动删除,适用于长监听
--@param event_name 事件名称
--@param func 监听函数
--@return listener 监听器
-------------------------------------------
function Dispatcher:addEventListenerSafe(event_name,func)
    for k, _ in pairs(self._eventDispatcher) do
        if(k.e == event_name and k.f == func) then
            return k
        end
    end
    return self:addEventListener(event_name,func)
end

-------------------------------------------
--订阅某个事件的自动监听,该种监听在收到一次后会自动将自己删除,适用于一次性监听
--@param event_name 事件名称
--@param func 监听函数
-------------------------------------------
function Dispatcher:addAutoEventListener(event_name,func)
    local listener = { e=event_name , f=func}  
    self._eventDispatcher[listener] = true 
end

-------------------------------------------
--触发某个事件
--@param event_name 事件名称o(n)
--@param ... 触发事件带出的参数
-------------------------------------------
function Dispatcher:dispatchEvent(event_name,...)
    local gc = {}
    for k, v in pairs(self._eventDispatcher) do
        if(k.e==event_name) then
            k.f(...)
            if v then
                gc[#gc+1] = k
            end
        end
    end
    for _,v in ipairs(gc) do
        self:removeEventListener(v)
    end 
end

-------------------------------------------
--从事件分发器中删除监听器o(1)
--@param listener 监听器
-------------------------------------------
function Dispatcher:removeEventListener(listener)
    self._eventDispatcher[listener] = nil 
end

--[[
事件队列池,采用hash算法
MAX_DISPATCHER 表示当前的事件队列最大条数。
]]--
local DispatcherUtils = {}
local MAX_DISPATCHER = 10

local function hashCode(s)
    local h = 0
    if(h==0 and #s>0then
        for i=1,#s do
            h = 31*h + string.byte(s,i,i)
        end
    end
    return h
end 

local function getIndex(s)
    return math.mod(hashCode(s),MAX_DISPATCHER) + 1 
end

local function getDispatcherByEvent(event_name)
    local index =  getIndex(event_name)
    DispatcherUtils[index] = DispatcherUtils[index] or Dispatcher.new()
    return DispatcherUtils[index]
end
-------------------------------------------
--订阅某个事件的常驻监听,该监听不会自动删除,适用于长监听
--@param event_name 事件名称
--@param func 监听函数
--@return listener 监听器
-------------------------------------------
function DispatcherUtils.addEventListener(event_name,func)
    return getDispatcherByEvent(event_name):addEventListener(event_name,func)
end

-------------------------------------------
--安全的订阅某个事件的常驻监听,并且会做安全检查,防止相同的监听添加,该监听不会自动删除,适用于长监听
--@param event_name 事件名称
--@param func 监听函数
--@return listener 监听器
-------------------------------------------
function DispatcherUtils.addEventListenerSafe(event_name,func)
    return getDispatcherByEvent(event_name):addEventListenerSafe(event_name,func)
end

-------------------------------------------
--订阅某个事件的自动监听,该种监听在收到一次后会自动将自己删除,适用于一次性监听
--@param event_name 事件名称
--@param func 监听函数
-------------------------------------------
function DispatcherUtils.addAutoEventListener(event_name,func)
    getDispatcherByEvent(event_name):addAutoEventListener(event_name,func)
end

-------------------------------------------
--触发某个事件
--@param event_name 事件名称
--@param ... 触发事件带出的参数
-------------------------------------------
function DispatcherUtils.dispatchEvent(event_name,...)
    getDispatcherByEvent(event_name):dispatchEvent(event_name,...) 
end

-------------------------------------------
--从事件分发器中删除监听器
--@param listener 监听器
-------------------------------------------
function DispatcherUtils.removeEventListener(listener)
    getDispatcherByEvent(listener.e):removeEventListener(listener) 
end

wolf.DispatcherUtils = DispatcherUtils
0 0
原创粉丝点击