extends Node # ============================================================================ # EventSystem.gd - 全局事件系统 # ============================================================================ # 全局单例管理器,提供解耦的事件通信机制 # # 核心职责: # - 事件监听器注册和管理 # - 事件发送和分发 # - 自动清理无效监听器 # - 支持带参数的事件通信 # # 使用方式: # EventSystem.connect_event("player_moved", _on_player_moved) # EventSystem.emit_event("player_moved", {"position": Vector2(100, 200)}) # # 注意事项: # - 作为自动加载单例,全局可访问 # - 监听器会自动检查目标节点的有效性 # - 建议使用EventNames类中定义的事件名称常量 # ============================================================================ # ============ 成员变量 ============ # 事件监听器存储 # 结构: {event_name: [{"callback": Callable, "target": Node}, ...]} var event_listeners: Dictionary = {} # ============ 生命周期方法 ============ # 初始化事件系统 # 在节点准备就绪时调用 func _ready(): print("EventSystem 初始化完成") # ============ 事件监听器管理 ============ # 注册事件监听器 # # 参数: # event_name: String - 事件名称(建议使用EventNames中的常量) # callback: Callable - 回调函数 # target: Node - 目标节点(可选,用于自动清理) # # 功能: # - 将回调函数注册到指定事件 # - 支持同一事件多个监听器 # - 自动管理监听器生命周期 # # 使用示例: # EventSystem.connect_event(EventNames.PLAYER_MOVED, _on_player_moved, self) # # 注意事项: # - 如果提供target参数,当target节点被销毁时会自动清理监听器 # - 同一个callback可以监听多个事件 func connect_event(event_name: String, callback: Callable, target: Node = null): # 初始化事件监听器数组 if not event_listeners.has(event_name): event_listeners[event_name] = [] # 创建监听器信息 var listener_info = { "callback": callback, "target": target } # 添加到监听器列表 event_listeners[event_name].append(listener_info) print("注册事件监听器: ", event_name, " -> ", callback) # 移除事件监听器 # # 参数: # event_name: String - 事件名称 # callback: Callable - 要移除的回调函数 # target: Node - 目标节点(可选,用于精确匹配) # # 功能: # - 从指定事件中移除特定的监听器 # - 支持精确匹配(callback + target) # # 使用示例: # EventSystem.disconnect_event(EventNames.PLAYER_MOVED, _on_player_moved, self) func disconnect_event(event_name: String, callback: Callable, target: Node = null): if not event_listeners.has(event_name): return var listeners = event_listeners[event_name] # 从后往前遍历,避免删除元素时索引问题 for i in range(listeners.size() - 1, -1, -1): var listener = listeners[i] # 匹配callback和target if listener.callback == callback and listener.target == target: listeners.remove_at(i) print("移除事件监听器: ", event_name, " -> ", callback) break # ============ 事件发送 ============ # 发送事件 # # 参数: # event_name: String - 事件名称 # data: Variant - 事件数据(可选) # # 功能: # - 向所有注册的监听器发送事件 # - 自动跳过无效的监听器 # - 支持任意类型的事件数据 # # 使用示例: # EventSystem.emit_event(EventNames.PLAYER_MOVED, {"position": Vector2(100, 200)}) # EventSystem.emit_event(EventNames.GAME_PAUSED) # 无数据事件 # # 注意事项: # - 事件发送是同步的,所有监听器会立即执行 # - 如果监听器执行出错,不会影响其他监听器 func emit_event(event_name: String, data: Variant = null): print("发送事件: ", event_name, " 数据: ", data) # 检查是否有监听器 if not event_listeners.has(event_name): return var listeners = event_listeners[event_name] for listener_info in listeners: var target = listener_info.target var callback = listener_info.callback # 检查目标节点是否仍然有效 if target != null and not is_instance_valid(target): continue # 调用回调函数 if data != null: callback.call(data) else: callback.call() # ============ 维护方法 ============ # 清理无效的监听器 # # 功能: # - 遍历所有监听器,移除已销毁节点的监听器 # - 防止内存泄漏 # - 建议定期调用或在场景切换时调用 # # 使用场景: # - 场景切换时清理 # - 定期维护(如每分钟一次) # - 内存优化时调用 func cleanup_invalid_listeners(): for event_name in event_listeners.keys(): var listeners = event_listeners[event_name] # 从后往前遍历,避免删除元素时索引问题 for i in range(listeners.size() - 1, -1, -1): var listener = listeners[i] var target = listener.target # 如果目标节点无效,移除监听器 if target != null and not is_instance_valid(target): listeners.remove_at(i) print("清理无效监听器: ", event_name) # ============ 查询方法 ============ # 获取事件监听器数量 # # 参数: # event_name: String - 事件名称 # # 返回值: # int - 监听器数量 # # 使用场景: # - 调试时检查监听器数量 # - 性能分析 func get_listener_count(event_name: String) -> int: if not event_listeners.has(event_name): return 0 return event_listeners[event_name].size() # 清空所有事件监听器 # # 功能: # - 移除所有已注册的事件监听器 # - 通常在游戏重置或退出时使用 # # 警告: # - 这是一个危险操作,会影响所有模块 # - 使用前请确保所有模块都能正确处理监听器丢失 func clear_all_listeners(): event_listeners.clear() print("清空所有事件监听器")