高性能事件分发器,lua 版

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

你可能感兴趣的:(cocos2dx)