72 lines
3.1 KiB
Python
72 lines
3.1 KiB
Python
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
|
||
]
|