-- GameEvent.lua 文件用于定义游戏事件相关的函数和数据结构 -- 定义 GameEvent 表 GameEvent = {} -- 存储事件监听器的表 local _listeners = {} -- 添加事件监听器 -- @param eventName 事件名称 -- @param func 监听器函数 -- @param tag 监听器标签 -- @param priority 优先级 function GameEvent.add(eventName, func, tag, priority) assert(tag, "Tag must not be nil") -- 如果事件名称对应的监听器表不存在,则创建一个新的表 if not _listeners[eventName] then _listeners[eventName] = {} end local eventListeners = _listeners[eventName] local eventListenerSize = #eventListeners for i = 1, eventListenerSize do -- 如果标签已存在,则直接返回 if tag == eventListeners[i][2] then return end end -- 根据优先级插入监听器 if priority and eventListenerSize >= priority then table.insert(eventListeners, priority, {func, tag}) else table.insert(eventListeners, {func, tag}) end end -- 移除事件监听器 -- @param func 监听器函数 function GameEvent.remove(func) 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 事件名称 -- @param tag 监听器标签 function GameEvent.removeByNameAndTag(eventName, tag) assert(tag, "Tag must not be nil") 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 监听器标签 function GameEvent.removeByTag(tag) assert(tag, "Tag must not be nil") for eventName, eventListeners in pairs(_listeners) do self.removeListenerByNameAndTag(eventName, tag) end end -- 移除所有事件监听器 function GameEvent.removeAll() _listeners = {} end -- 触发事件 -- @param eventName 事件名称 -- @param ... 传递给监听器的参数 function GameEvent.push(eventName, ...) local eventListeners = _listeners[eventName] if not eventListeners then return end for index, listeners in ipairs(eventListeners) do local result, stop = pcall(listeners[1], ...) if result then if stop then break end else local tag = listeners[2] local tarid = tag.ID or 0 local err = "派发事件发生错误:事件名="..eventName.." 模块ID="..tarid.." " release_print(err, stop) end end end -- 返回 GameEvent 表 return GameEvent