Files
WechatHookBot/utils/event_manager.py
2025-12-03 15:48:44 +08:00

72 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
]