高性能事件分發器,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
相關文章
相關標籤/搜索