🐳 chore(工具): 增加 全局事件 和 事件对象基础类
parent
2ebfd2654c
commit
b7815395e8
@ -1,221 +0,0 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- https://github.com/simenkid/lua-events
|
||||
------------------------------------------------------------------------------
|
||||
local PFX = '__lsn_'
|
||||
local PFX_LEN = #PFX
|
||||
local Events = {
|
||||
defaultMaxListeners = 10,
|
||||
}
|
||||
|
||||
setmetatable(Events, {
|
||||
__call = function(_, ...)
|
||||
return Events:new(...)
|
||||
end,
|
||||
})
|
||||
|
||||
local function rmEntry(tbl, pred)
|
||||
local x, len = 0, #tbl
|
||||
for i = 1, len do
|
||||
local trusy, idx = false, (i - x)
|
||||
if (type(pred) == 'function') then
|
||||
trusy = pred(tbl[idx])
|
||||
else
|
||||
trusy = tbl[idx] == pred
|
||||
end
|
||||
|
||||
if (tbl[idx] ~= nil and trusy) then
|
||||
tbl[idx] = nil
|
||||
table.remove(tbl, idx)
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
function Events:new(obj)
|
||||
obj = obj or {}
|
||||
self.__index = self
|
||||
setmetatable(obj, self)
|
||||
obj._on = {}
|
||||
|
||||
return obj
|
||||
end
|
||||
|
||||
function Events:evTable(ev)
|
||||
if (type(self._on[ev]) ~= 'table') then
|
||||
self._on[ev] = {}
|
||||
end
|
||||
return self._on[ev]
|
||||
end
|
||||
|
||||
function Events:getEvTable(ev)
|
||||
return self._on[ev]
|
||||
end
|
||||
|
||||
-- ************************************************************************ --
|
||||
-- ** Public APIs * --
|
||||
-- ************************************************************************ --
|
||||
function Events:addListener(ev, listener)
|
||||
local pfx_ev = PFX .. tostring(ev)
|
||||
local evtbl = self:evTable(pfx_ev)
|
||||
local maxLsnNum = self.currentMaxListeners or self.defaultMaxListeners
|
||||
local lsnNum = self:listenerCount(ev)
|
||||
table.insert(evtbl, listener)
|
||||
|
||||
if (lsnNum > maxLsnNum) then
|
||||
print('WARN: Number of ' .. string.sub(pfx_ev, PFX_LEN + 1) .. " event listeners: " .. tostring(lsnNum))
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Events:emit(ev, ...)
|
||||
local pfx_ev = PFX .. tostring(ev)
|
||||
local evtbl = self:getEvTable(pfx_ev)
|
||||
if (evtbl ~= nil) then
|
||||
for _, lsn in ipairs(evtbl) do
|
||||
local status, err = pcall(lsn, ...)
|
||||
if not (status) then
|
||||
print(string.sub(_, PFX_LEN + 1) .. " emit error: " .. tostring(err))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- one-time listener
|
||||
pfx_ev = pfx_ev .. ':once'
|
||||
evtbl = self:getEvTable(pfx_ev)
|
||||
|
||||
if (evtbl ~= nil) then
|
||||
for _, lsn in ipairs(evtbl) do
|
||||
local status, err = pcall(lsn, ...)
|
||||
if not (status) then
|
||||
print(string.sub(_, PFX_LEN + 1) .. " emit error: " .. tostring(err))
|
||||
end
|
||||
end
|
||||
|
||||
rmEntry(evtbl, function(v)
|
||||
return v ~= nil
|
||||
end)
|
||||
self._on[pfx_ev] = nil
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Events:getMaxListeners()
|
||||
return self.currentMaxListeners or self.defaultMaxListeners
|
||||
end
|
||||
|
||||
function Events:listenerCount(ev)
|
||||
local totalNum = 0
|
||||
local pfx_ev = PFX .. tostring(ev)
|
||||
local evtbl = self:getEvTable(pfx_ev)
|
||||
|
||||
if (evtbl ~= nil) then
|
||||
totalNum = totalNum + #evtbl
|
||||
end
|
||||
|
||||
pfx_ev = pfx_ev .. ':once'
|
||||
evtbl = self:getEvTable(pfx_ev)
|
||||
|
||||
if (evtbl ~= nil) then
|
||||
totalNum = totalNum + #evtbl
|
||||
end
|
||||
|
||||
return totalNum
|
||||
end
|
||||
|
||||
function Events:listeners(ev)
|
||||
local pfx_ev = PFX .. tostring(ev)
|
||||
local evtbl = self:getEvTable(pfx_ev)
|
||||
local clone = {}
|
||||
|
||||
if (evtbl ~= nil) then
|
||||
for i, lsn in ipairs(evtbl) do
|
||||
table.insert(clone, lsn)
|
||||
end
|
||||
end
|
||||
|
||||
pfx_ev = pfx_ev .. ':once'
|
||||
evtbl = self:getEvTable(pfx_ev)
|
||||
|
||||
if (evtbl ~= nil) then
|
||||
for i, lsn in ipairs(evtbl) do
|
||||
table.insert(clone, lsn)
|
||||
end
|
||||
end
|
||||
|
||||
return clone
|
||||
end
|
||||
|
||||
Events.on = Events.addListener
|
||||
|
||||
function Events:once(ev, listener)
|
||||
local pfx_ev = PFX .. tostring(ev) .. ':once'
|
||||
local evtbl = self:evTable(pfx_ev)
|
||||
local maxLsnNum = self.currentMaxListeners or self.defaultMaxListeners
|
||||
local lsnNum = self:listenerCount(ev)
|
||||
if (lsnNum > maxLsnNum) then
|
||||
print('WARN: Number of ' .. ev .. " event listeners: " .. tostring(lsnNum))
|
||||
end
|
||||
|
||||
table.insert(evtbl, listener)
|
||||
return self
|
||||
end
|
||||
|
||||
function Events:removeAllListeners(ev)
|
||||
if ev ~= nil then
|
||||
local pfx_ev = PFX .. tostring(ev)
|
||||
local evtbl = self:evTable(pfx_ev)
|
||||
rmEntry(evtbl, function(v)
|
||||
return v ~= nil
|
||||
end)
|
||||
|
||||
pfx_ev = pfx_ev .. ':once'
|
||||
evtbl = self:evTable(pfx_ev)
|
||||
rmEntry(evtbl, function(v)
|
||||
return v ~= nil
|
||||
end)
|
||||
self._on[pfx_ev] = nil
|
||||
else
|
||||
for _pfx_ev, _t in pairs(self._on) do
|
||||
self:removeAllListeners(string.sub(_pfx_ev, PFX_LEN + 1))
|
||||
end
|
||||
end
|
||||
|
||||
for _pfx_ev, _t in pairs(self._on) do
|
||||
if (#_t == 0) then
|
||||
self._on[_pfx_ev] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Events:removeListener(ev, listener)
|
||||
local pfx_ev = PFX .. tostring(ev)
|
||||
local evtbl = self:evTable(pfx_ev)
|
||||
local lsnCount = 0
|
||||
assert(listener ~= nil, "listener is nil")
|
||||
-- normal listener
|
||||
rmEntry(evtbl, listener)
|
||||
|
||||
if (#evtbl == 0) then
|
||||
self._on[pfx_ev] = nil
|
||||
end
|
||||
|
||||
-- emit-once listener
|
||||
pfx_ev = pfx_ev .. ':once'
|
||||
evtbl = self:evTable(pfx_ev)
|
||||
rmEntry(evtbl, listener)
|
||||
|
||||
if (#evtbl == 0) then
|
||||
self._on[pfx_ev] = nil
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Events:setMaxListeners(n)
|
||||
self.currentMaxListeners = n
|
||||
return self
|
||||
end
|
||||
|
||||
return Events
|
||||
@ -0,0 +1,178 @@
|
||||
-- local skynet = require("skynet")
|
||||
-- local serviceAddress = require("serviceAddress")
|
||||
-- local serviceProxy = require("serviceProxy")
|
||||
-- local eventd
|
||||
-- local curlistenerHandleIndex = 1
|
||||
-- local string_format = string.format
|
||||
-- local table_insert = table.insert
|
||||
|
||||
-- local dispatch = {}
|
||||
|
||||
-- local crossEventClient = {}
|
||||
|
||||
-- function crossEventClient.addEventListener(crossEventType, eventId, objId, cb, obj)
|
||||
-- assert(objId == nil or (type(objId) == "number" and objId > 0) or (type(objId) == "string" and #objId > 0),
|
||||
-- string_format("[crossEventClient].addEventListener,objId"))
|
||||
-- local dispatchKey = string_format("%s-%s", crossEventType, eventId)
|
||||
-- local handle = curlistenerHandleIndex
|
||||
-- curlistenerHandleIndex = curlistenerHandleIndex + 1
|
||||
-- local listener = {cb, obj}
|
||||
-- local eventListener = dispatch[dispatchKey]
|
||||
-- if not eventListener then
|
||||
-- eventListener = {}
|
||||
-- dispatch[dispatchKey] = eventListener
|
||||
-- end
|
||||
-- local listeners
|
||||
-- if objId then
|
||||
-- eventListener.single = eventListener.single or {}
|
||||
-- listeners = eventListener.single[objId]
|
||||
-- if not listeners then
|
||||
-- listeners = {}
|
||||
-- eventListener.single[objId] = listeners
|
||||
-- end
|
||||
-- else
|
||||
-- eventListener.all = eventListener.all or {}
|
||||
-- listeners = eventListener.all
|
||||
-- end
|
||||
|
||||
-- if not next(listeners) then
|
||||
-- local addr = skynet.self()
|
||||
-- skynet.send(eventd, "lua", "addEventListener", dispatchKey, addr, objId)
|
||||
-- end
|
||||
-- listeners[handle] = listener
|
||||
-- return handle
|
||||
-- end
|
||||
|
||||
-- function crossEventClient.removeEventListener(handle)
|
||||
-- for dispatchKey, eventListener in pairs(dispatch) do
|
||||
-- local singleListener = eventListener.single
|
||||
-- if singleListener then
|
||||
-- for objId, listeners in pairs(singleListener) do
|
||||
-- for h, _ in pairs(listeners) do
|
||||
-- if h == handle then
|
||||
-- listeners[h] = nil
|
||||
-- if not next(singleListener) then
|
||||
-- eventListener.single = nil
|
||||
-- local addr = skynet.self()
|
||||
-- skynet.send(eventd, "lua", "removeEventListener", dispatchKey, addr, objId)
|
||||
-- end
|
||||
-- break
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- local allListener = eventListener.all
|
||||
-- if allListener then
|
||||
-- for h, _ in pairs(allListener) do
|
||||
-- if h == handle then
|
||||
-- allListener[h] = nil
|
||||
-- if not next(allListener) then
|
||||
-- eventListener.all = nil
|
||||
-- local addr = skynet.self()
|
||||
-- skynet.send(eventd, "lua", "removeEventListener", dispatchKey, addr)
|
||||
-- end
|
||||
-- break
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- function crossEventClient.dispatchEventBySend(crossEventType, eventId, objId, event)
|
||||
-- assert(objId == nil or (type(objId) == "number" and objId > 0) or (type(objId) == "string" and #objId > 0),
|
||||
-- string_format("[crossEventClient].addEventListener,objId"))
|
||||
-- local dispatchKey = string_format("%s-%s", crossEventType, eventId)
|
||||
-- event.dispatchKey = dispatchKey
|
||||
-- event.dispatchObjId = objId
|
||||
-- local strEvent = skynet.tostring(skynet.pack(event))
|
||||
-- skynet.send(eventd, "lua", "dispatchEventBySend", dispatchKey, strEvent, objId)
|
||||
-- end
|
||||
|
||||
-- function crossEventClient.dispatchEventByCall(crossEventType, eventId, objId, event)
|
||||
-- assert(objId == nil or (type(objId) == "number" and objId > 0) or (type(objId) == "string" and #objId > 0),
|
||||
-- string_format("[crossEventClient].addEventListener,objId"))
|
||||
-- local dispatchKey = string_format("%s-%s", crossEventType, eventId)
|
||||
-- event.dispatchKey = dispatchKey
|
||||
-- event.dispatchObjId = objId
|
||||
-- local strEvent = skynet.tostring(skynet.pack(event))
|
||||
-- skynet.call(eventd, "lua", "dispatchEventByCall", dispatchKey, strEvent, objId)
|
||||
-- end
|
||||
|
||||
-- function crossEventClient.dispatchEventComposeBySend(crossEventType, eventId, objId, event, amongSvr, amongCluster,
|
||||
-- nodeNames)
|
||||
-- assert(objId == nil or (type(objId) == "number" and objId > 0) or (type(objId) == "string" and #objId > 0),
|
||||
-- string_format("[crossEventClient].addEventListener,objId"))
|
||||
-- local dispatchKey = string_format("%s-%s", crossEventType, eventId)
|
||||
-- event.dispatchKey = dispatchKey
|
||||
-- event.dispatchObjId = objId
|
||||
-- local strEvent = skynet.tostring(skynet.pack(event))
|
||||
-- if amongSvr then
|
||||
-- skynet.send(eventd, "lua", "dispatchEventBySend", dispatchKey, strEvent, objId)
|
||||
-- end
|
||||
-- if amongCluster then
|
||||
-- for _, nodeName in pairs(nodeNames) do
|
||||
-- local crossEventServerProxy = serviceProxy.remote(nodeName, "crossEvent")
|
||||
-- crossEventServerProxy.remotePost.dispatchEventBySend(nodeName, dispatchKey, strEvent, objId)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- local function dispatchEvent(session, _, strEvent)
|
||||
-- local event = skynet.unpack(strEvent)
|
||||
-- local dispatchKey = event.dispatchKey
|
||||
-- local objId = event.dispatchObjId
|
||||
-- local eventListener = dispatch[dispatchKey]
|
||||
-- if not eventListener then
|
||||
-- return
|
||||
-- end
|
||||
|
||||
-- local tmpListeners = {}
|
||||
-- if objId then
|
||||
-- local singleListener = eventListener.single
|
||||
-- if singleListener then
|
||||
-- local listeners = singleListener[objId]
|
||||
-- if listeners then
|
||||
-- for _, listener in pairs(listeners) do
|
||||
-- table_insert(tmpListeners, listener)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- local allListener = eventListener.all
|
||||
-- if allListener then
|
||||
-- for _, listener in pairs(allListener) do
|
||||
-- table_insert(tmpListeners, listener)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- for _, listener in pairs(tmpListeners) do
|
||||
-- local cb = listener[1]
|
||||
-- local obj = listener[2]
|
||||
-- if obj then
|
||||
-- cb(obj, event)
|
||||
-- else
|
||||
-- cb(event)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if session > 0 then
|
||||
-- skynet.ret(skynet.pack(true))
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- local function init()
|
||||
-- eventd = serviceAddress.crossEvent()
|
||||
-- log.debug("[crossEventClient].init,eventd=%s", eventd)
|
||||
-- skynet.register_protocol {
|
||||
-- name = "crossevent",
|
||||
-- id = skynet.PTYPE_TEXT,
|
||||
-- unpack = skynet.tostring,
|
||||
-- dispatch = dispatchEvent,
|
||||
-- }
|
||||
-- end
|
||||
|
||||
-- init()
|
||||
|
||||
-- return crossEventClient
|
||||
@ -0,0 +1,28 @@
|
||||
-- local crossEventType = require("crossEvent.crossEventType")
|
||||
-- local PlayerEventEnum = gEnum("PlayerEventEnum")
|
||||
-- local PlayerEventId = PlayerEventEnum.PlayerEventId
|
||||
-- local ClusterEnum = gEnum("ClusterEnum")
|
||||
-- local ClusterEventId = ClusterEnum.ClusterEventId
|
||||
|
||||
|
||||
-- local eventRouteConfig = {
|
||||
-- amongService = {
|
||||
-- [crossEventType.CLUSTER] = {
|
||||
-- [ClusterEventId.NODE_STATUS_CHANGE] = true,
|
||||
-- },
|
||||
-- [crossEventType.PLAYER] = {
|
||||
-- [PlayerEventId.ONLINE] = true,
|
||||
-- [PlayerEventId.OFFLINE] = true,
|
||||
-- },
|
||||
-- },
|
||||
-- amongCluster = {
|
||||
-- [crossEventType.CLUSTER] = {
|
||||
-- [ClusterEventId.NODE_STATUS_CHANGE] = {
|
||||
-- "login",
|
||||
-- "game",
|
||||
-- },
|
||||
-- }
|
||||
-- }
|
||||
-- }
|
||||
|
||||
-- return eventRouteConfig
|
||||
@ -0,0 +1,8 @@
|
||||
-- 跨服务 事件类型
|
||||
local crossEventType = {
|
||||
CLUSTER = 1, -- 集群
|
||||
PLAYER = 2, -- 玩家
|
||||
ALLIANCE = 3, -- 联盟
|
||||
}
|
||||
|
||||
return crossEventType
|
||||
@ -0,0 +1,270 @@
|
||||
--[[--
|
||||
Provides custom event broadcaster / listener mechanism to regular Lua objects.
|
||||
|
||||
All listeners receive the following fields in the parameter event table:
|
||||
|
||||
<code>event.name</code> (name of the event)
|
||||
|
||||
<code>event.target</code> (the listener itself)
|
||||
|
||||
<code>event.source</code> (the dispatcher)
|
||||
|
||||
Latest code: https://github.com/daveyang/EventDispatcher
|
||||
|
||||
@module EventDispatcher
|
||||
@usage
|
||||
local EvtD = require "EventDispatcher"
|
||||
|
||||
local dispatcher = EvtD()
|
||||
|
||||
-- listener as table
|
||||
local listener = {
|
||||
eventName = function(event, ...)
|
||||
print(event.name, event.target, event.source)
|
||||
end
|
||||
}
|
||||
|
||||
-- listener as function
|
||||
local function listener(event, ...)
|
||||
print(event.name, event.target, event.source)
|
||||
end
|
||||
|
||||
dispatcher:addEventListener( "eventName", listener ) -- or
|
||||
dispatcher:on( "eventName", listener )
|
||||
|
||||
dispatcher:once( "eventName", listener )
|
||||
|
||||
dispatcher:hasEventListener( "eventName", listener )
|
||||
|
||||
dispatcher:dispatchEvent( { name="eventName" } ) -- or
|
||||
dispatcher:dispatchEvent( "eventName" ) -- or
|
||||
dispatcher:emit( { name="eventName" } ) -- or
|
||||
dispatcher:emit( "eventName" )
|
||||
|
||||
dispatcher:removeEventListener( "eventName", listener )
|
||||
|
||||
dispatcher:removeAllListeners( "eventName" ) -- or
|
||||
dispatcher:removeAllListeners()
|
||||
|
||||
dispatcher:printListeners()
|
||||
]]
|
||||
|
||||
|
||||
local EventDispatcher = {}
|
||||
|
||||
-- Initializes an object (this is automatically invoked and is considered a private method)
|
||||
-- @param o table object to become event dispatcher
|
||||
-- @return a table
|
||||
function EventDispatcher:init(o)
|
||||
o = o or {}
|
||||
o._listeners = {}
|
||||
self.__index = self
|
||||
return setmetatable(o, self)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
--- Checks if the event dispatcher has registered listener for the event eventName.
|
||||
-- @param eventName event name (string)
|
||||
-- @param listener object (table or function)
|
||||
-- @return found status (boolean); if found also returns the index of listener object.
|
||||
function EventDispatcher:hasEventListener(eventName, listener)
|
||||
if eventName == nil or #eventName == 0 or listener == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
local a = self._listeners
|
||||
if a == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
for i, o in next, a do
|
||||
if o ~= nil and o.evt == eventName and o.obj == listener then
|
||||
return true, i
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
--- Adds a listener for the event eventName. Optional runs once flag.
|
||||
-- @param eventName event name (string)
|
||||
-- @param listener object (table or function)
|
||||
-- @param isOnce flag to specify the listener only runs once (boolean)
|
||||
-- @return success/fail status (boolean); position of listener is also returned if false; position=0 if failed.
|
||||
-- @see on
|
||||
-- @see once
|
||||
function EventDispatcher:addEventListener(eventName, listener, isOnce)
|
||||
if not isOnce then
|
||||
local found, pos = self:hasEventListener(eventName, listener)
|
||||
if found then
|
||||
return false, pos
|
||||
end
|
||||
end
|
||||
|
||||
local a = self._listeners
|
||||
if a == nil then
|
||||
return false, 0
|
||||
end
|
||||
|
||||
a[#a + 1] = {
|
||||
evt = eventName,
|
||||
obj = listener,
|
||||
isOnce = isOnce,
|
||||
}
|
||||
return true
|
||||
end
|
||||
|
||||
--- 'on' is an alias of 'addEventListener'
|
||||
EventDispatcher.on = EventDispatcher.addEventListener
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
--- Adds a one-time listener for the event eventName. Once the event is dispatched, the listener is removed.
|
||||
-- @param eventName event name (string)
|
||||
-- @param listener object (table or function)
|
||||
-- @return success/fail status (boolean); position of listener is also returned if false; position=0 if failed.
|
||||
-- @see addEventListener
|
||||
-- @see on
|
||||
function EventDispatcher:once(eventName, listener)
|
||||
return self:addEventListener(eventName, listener, true)
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
--- Dispatches an event, with optional extra parameters.
|
||||
-- @param event the event (table, must have a 'name' key; e.g. { name="eventName" }, or as string)
|
||||
-- @param ... optional extra parameters
|
||||
-- @return dispatch status (boolean).
|
||||
-- @see emit
|
||||
function EventDispatcher:dispatchEvent(event, ...)
|
||||
if event == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
if type(event) == "table" then
|
||||
if event.name == nil or type(event.name) ~= "string" or #event.name == 0 then
|
||||
return false
|
||||
end
|
||||
elseif type(event) == "string" then
|
||||
if #event == 0 then
|
||||
return false
|
||||
end
|
||||
event = {
|
||||
name = event,
|
||||
}
|
||||
end
|
||||
|
||||
local a = self._listeners
|
||||
if a == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
local dispatched = false
|
||||
for _, o in next, a do
|
||||
if o ~= nil and o.obj ~= nil and o.evt == event.name then
|
||||
event.target = o.obj
|
||||
event.source = self
|
||||
|
||||
if type(o.obj) == "function" then
|
||||
o.obj(event, ...)
|
||||
if o.isOnce then
|
||||
self:removeEventListener(event.name, o.obj, true)
|
||||
end
|
||||
dispatched = true
|
||||
elseif type(o.obj) == "table" then
|
||||
local f = o.obj[event.name]
|
||||
if f ~= nil then
|
||||
f(event, ...)
|
||||
if o.isOnce then
|
||||
self:removeEventListener(event.name, o.obj, true)
|
||||
end
|
||||
dispatched = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return dispatched
|
||||
end
|
||||
|
||||
--- 'emit' is an alias of 'dispatchEvent'
|
||||
EventDispatcher.emit = EventDispatcher.dispatchEvent
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
--- Removes listener with the eventName event from the event dispatcher.
|
||||
-- @param eventName event name (string)
|
||||
-- @param listener object (table or function)
|
||||
-- @return removal status (boolean).
|
||||
-- @see removeAllListeners
|
||||
function EventDispatcher:removeEventListener(eventName, listener)
|
||||
local found, pos = self:hasEventListener(eventName, listener)
|
||||
if found then
|
||||
table.remove(self._listeners, pos)
|
||||
end
|
||||
return found
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
--- Removes all listeners with the eventName event from the event dispatcher.
|
||||
--- If the optional eventName is nil, all listeners are removed from the event dispatcher.
|
||||
-- @param eventName event name (string)
|
||||
-- @return removal status (boolean), with the number of listeners removed.
|
||||
-- @see removeEventListener
|
||||
function EventDispatcher:removeAllListeners(eventName)
|
||||
local a = self._listeners
|
||||
if a == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
if eventName == nil then
|
||||
local n = #self._listeners
|
||||
self._listeners = {}
|
||||
return true, n
|
||||
else
|
||||
local found = false
|
||||
local i = #a
|
||||
local n = 0
|
||||
|
||||
while i > 0 do
|
||||
local o = a[i]
|
||||
if o ~= nil and o.evt == eventName then
|
||||
table.remove(a, i)
|
||||
found = true
|
||||
n = n + 1
|
||||
end
|
||||
i = i - 1
|
||||
end
|
||||
return found, n
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
--- Prints the content of the _listeners array (for debugging).
|
||||
-- Format: index, eventName, listener, isOnce.
|
||||
function EventDispatcher:printListeners()
|
||||
local a = self._listeners
|
||||
if a == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
for i, o in next, a do
|
||||
if o ~= nil then
|
||||
print(i, o.evt, o.obj, o.isOnce)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
-- Create syntactic sugar to automatically call init().
|
||||
setmetatable(EventDispatcher, {
|
||||
__call = function(_, ...)
|
||||
return EventDispatcher:init(...)
|
||||
end,
|
||||
})
|
||||
|
||||
return EventDispatcher
|
||||
@ -0,0 +1,125 @@
|
||||
local eventRouteConfig = require("crossEvent.cross_event_router")
|
||||
local crossEventClient = require("events.cross.cross_event_client")
|
||||
|
||||
------------------------------------------------
|
||||
local EventDispatcher = class("EventDispatcher")
|
||||
|
||||
function EventDispatcher:initialize(crossEventType)
|
||||
self.crossEventType = crossEventType
|
||||
self.beforeListeners = {}
|
||||
self.listeners = {}
|
||||
self.nextListenerHandleIndex = 0
|
||||
|
||||
self.eventAmongService = eventRouteConfig.amongService[self.crossEventType]
|
||||
self.eventAmongCluster = eventRouteConfig.amongCluster[self.crossEventType]
|
||||
end
|
||||
|
||||
function EventDispatcher:addEventListener(eventId, listener, obj)
|
||||
assert(type(eventId) == "number" and eventId ~= "", "EventDispatcher:addEventListener() - invalid eventId")
|
||||
if self.listeners[eventId] == nil then
|
||||
self.listeners[eventId] = {}
|
||||
end
|
||||
|
||||
self.nextListenerHandleIndex = self.nextListenerHandleIndex + 1
|
||||
local handle = self.nextListenerHandleIndex
|
||||
self.listeners[eventId][handle] = {listener, obj}
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
function EventDispatcher:addBeforeEventListener(eventId, listener, obj)
|
||||
assert(type(eventId) == "number" or type(eventId) == "string" and eventId,
|
||||
"EventDispatcher:addBeforeEventListener() - invalid eventId")
|
||||
if self.beforeListeners[eventId] == nil then
|
||||
self.beforeListeners[eventId] = {}
|
||||
end
|
||||
|
||||
self.nextListenerHandleIndex = self.nextListenerHandleIndex + 1
|
||||
local handle = self.nextListenerHandleIndex
|
||||
self.beforeListeners[eventId][handle] = {listener, obj}
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
local function execListeners(listeners, event)
|
||||
local listenerlist = {}
|
||||
for _, listener in pairs(listeners) do
|
||||
table.insert(listenerlist, listener)
|
||||
end
|
||||
|
||||
for _, listener in ipairs(listenerlist) do
|
||||
if listener[2] then
|
||||
listener[1](listener[2], event)
|
||||
else
|
||||
listener[1](event)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EventDispatcher:dispatchEvent(eventId, event)
|
||||
local beforeListeners = self.beforeListeners[eventId]
|
||||
if beforeListeners then
|
||||
event.eventId = eventId
|
||||
execListeners(beforeListeners, event)
|
||||
end
|
||||
|
||||
local listeners = self.listeners[eventId]
|
||||
if listeners then
|
||||
event.eventId = eventId
|
||||
execListeners(listeners, event)
|
||||
end
|
||||
|
||||
local amongSvr = self.eventAmongService and self.eventAmongService[eventId]
|
||||
local amongCluster = self.eventAmongCluster and self.eventAmongCluster[eventId]
|
||||
local nodeNames
|
||||
|
||||
if amongCluster then
|
||||
nodeNames = {}
|
||||
for _, nodeTypeName in pairs(self.eventAmongCluster[eventId]) do
|
||||
local tmpNodeNames = self:getNodeNames(nodeTypeName)
|
||||
for _, nodeName in pairs(tmpNodeNames) do
|
||||
table.insert(nodeNames, nodeName)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if amongSvr or amongCluster then
|
||||
local eventType = self.crossEventType
|
||||
local objId = self:getOwnerId()
|
||||
ZLog.debug("[EventDispatcher].dispatchEvent,cross,eventType=%s,objId=%s", eventType, objId)
|
||||
crossEventClient.dispatchEventDispatcheroseBySend(eventType, eventId, objId, event, amongSvr, amongCluster,
|
||||
nodeNames)
|
||||
end
|
||||
end
|
||||
|
||||
function EventDispatcher:removeEventListener(handleToRemove)
|
||||
for _, listenersForEvent in pairs(self.beforeListeners) do
|
||||
local isRemoved = false
|
||||
for handle, _ in pairs(listenersForEvent) do
|
||||
if handle == handleToRemove then
|
||||
listenersForEvent[handle] = nil
|
||||
isRemoved = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if isRemoved then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for _, listenersForEvent in pairs(self.listeners) do
|
||||
local isRemoved = false
|
||||
for handle, _ in pairs(listenersForEvent) do
|
||||
if handle == handleToRemove then
|
||||
listenersForEvent[handle] = nil
|
||||
isRemoved = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if isRemoved then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return EventDispatcher
|
||||
@ -0,0 +1 @@
|
||||
本服务事件定义
|
||||
Loading…
Reference in New Issue