--- 游戏事件管理器 local GameEvent = {} GameEvent._listeners = {} --- 添加事件监听器 ---@param eventName string 事件名称 ---@param func function 回调函数 ---@param tag any 标签 function GameEvent:add(eventName, func, tag) -- assert(tag, "添加【"..eventName.."】事件未传递tag") local listeners = self._listeners if not listeners[eventName] then listeners[eventName] = {} end local eventListeners = listeners[eventName] for i = 1, #eventListeners do if tag == eventListeners[i][2] then -- 避免重复为标签添加监听器 return end end table.insert(eventListeners, {func, tag}) end --- 移除事件监听器 ---@param func function 回调函数 function GameEvent:remove(func) local listeners = self._listeners for eventName, eventListeners in pairs(listeners) do for i = 1, #eventListeners do if eventListeners[i][1] == func then -- 移除监听器 table.remove(eventListeners, i) -- 清空表 if 0 == #listeners[eventName] then listeners[eventName] = nil end return end end end end --- 根据事件名称和标签移除事件监听器 ---@param eventName string 事件名称 ---@param tag any 标签 function GameEvent:removeByNameAndTag(eventName, tag) assert(tag, "Tag must not be nil") local listeners = self._listeners local eventListeners = listeners[eventName] if not eventListeners then return end for i = #eventListeners, 1, -1 do if eventListeners[i][2] == tag then -- 移除监听器 table.remove(eventListeners, i) break end end -- 清空表 if 0 == #eventListeners then listeners[eventName] = nil end end --- 根据标签移除事件监听器 ---@param tag any 标签 function GameEvent:removeByTag(tag) assert(tag, "Tag must not be nil") local listeners = self._listeners for eventName, eventListeners in pairs(listeners) do self.removeListenerByNameAndTag(eventName, tag) end end --- 移除所有事件监听器 function GameEvent:removeAll() self._listeners = {} end --- 触发事件 ---@param eventName string 事件名称 ---@vararg any 事件参数 function GameEvent:push(eventName, ...) local listeners = self._listeners or {} local eventListeners = listeners[eventName] if not eventListeners then return end local tmp = {} for index, listeners in ipairs(eventListeners) do tmp[index] = listeners end for _, listeners in ipairs(tmp) do listeners[1](...) end end return GameEvent