import copy from typing import Callable, Dict, List class EventManager: _handlers: Dict[str, List[tuple[Callable, object, int]]] = {} @classmethod def bind_instance(cls, instance: object): """将实例绑定到对应的事件处理函数""" from loguru import logger registered_count = 0 for method_name in dir(instance): method = getattr(instance, method_name) if hasattr(method, '_event_type'): event_type = getattr(method, '_event_type') priority = getattr(method, '_priority', 50) if event_type not in cls._handlers: cls._handlers[event_type] = [] cls._handlers[event_type].append((method, instance, priority)) # 按优先级排序,优先级高的在前 cls._handlers[event_type].sort(key=lambda x: x[2], reverse=True) registered_count += 1 logger.debug(f"[EventManager] 注册事件处理器: {instance.__class__.__name__}.{method_name} -> {event_type} (优先级={priority})") if registered_count > 0: logger.success(f"[EventManager] {instance.__class__.__name__} 注册了 {registered_count} 个事件处理器") @classmethod async def emit(cls, event_type: str, *args, **kwargs) -> None: """触发事件""" from loguru import logger if event_type not in cls._handlers: logger.debug(f"[EventManager] 事件 {event_type} 没有注册的处理器") return logger.debug(f"[EventManager] 触发事件: {event_type}, 处理器数量: {len(cls._handlers[event_type])}") api_client, message = args for handler, instance, priority in cls._handlers[event_type]: try: logger.debug(f"[EventManager] 调用处理器: {instance.__class__.__name__}.{handler.__name__}") # 不再深拷贝message,让所有处理器共享同一个消息对象 # 这样AutoReply设置的标记可以传递给AIChat handler_args = (api_client, message) new_kwargs = kwargs # kwargs也不需要深拷贝 result = await handler(*handler_args, **new_kwargs) if isinstance(result, bool): # True 继续执行 False 停止执行 if not result: break else: continue # 我也不知道你返回了个啥玩意,反正继续执行就是了 except Exception as e: import traceback logger.error(f"处理器 {handler.__name__} 执行失败: {e}") logger.error(f"详细错误: {traceback.format_exc()}") @classmethod def unbind_instance(cls, instance: object): """解绑实例的所有事件处理函数""" for event_type in cls._handlers: cls._handlers[event_type] = [ (handler, inst, priority) for handler, inst, priority in cls._handlers[event_type] if inst is not instance ]