# -*- coding: utf-8 -*- """ 事件处理器基类与装饰器系统 ───────────────────────────────────────────────────────────────── 提供两种注册处理器的方式: 1. 继承 BaseEventHandler 类(面向对象风格) 2. 使用 @on_event 装饰器(函数式风格) ───────────────────────────────────────────────────────────────── """ from __future__ import annotations import functools import inspect import logging from abc import ABC, abstractmethod from typing import Callable, List, Optional, Union from uas.event.event_model import Event from uas.event.event_type import EventType logger = logging.getLogger(__name__) # ───────────────────────────────────────────────────────────────── # 处理器描述符 # ───────────────────────────────────────────────────────────────── class HandlerDescriptor: """ 处理器注册描述符 记录处理器函数与其绑定的事件类型、优先级、过滤条件 """ def __init__( self, fn: Callable, event_types: List[Union[EventType, str]], priority: int = 0, # 同类型处理器执行顺序(越小越先) condition: Optional[Callable[[Event], bool]] = None, once: bool = False, # 是否只执行一次 name: str = "", ): self.fn = fn self.event_types = [ t.value if isinstance(t, EventType) else t for t in event_types ] self.priority = priority self.condition = condition self.once = once self.name = name or fn.__name__ self.call_count = 0 self.is_async = inspect.iscoroutinefunction(fn) def matches(self, event: Event) -> bool: """检查事件是否匹配此处理器""" type_match = ( event.type_key in self.event_types or "*" in self.event_types # 通配符 ) if not type_match: return False if self.condition and not self.condition(event): return False return True def __repr__(self): return (f"Handler({self.name!r}, types={self.event_types}, " f"priority={self.priority}, async={self.is_async})") # ───────────────────────────────────────────────────────────────── # 抽象基类(面向对象风格) # ───────────────────────────────────────────────────────────────── class BaseEventHandler(ABC): """ 事件处理器抽象基类 子类实现 handle() 方法,并声明 event_types 属性 示例: class DeviceErrorHandler(BaseEventHandler): event_types = [EventType.DEVICE_ERROR] priority = 10 def handle(self, event: Event) -> Optional[dict]: print(f"处理设备错误: {event.params}") return {"action": "restart"} """ event_types: List[Union[EventType, str]] = [] priority: int = 0 condition: Optional[Callable] = None def __init__(self): self.logger = logging.getLogger(self.__class__.__name__) self._descriptor = HandlerDescriptor( fn = self.handle, event_types = self.event_types, priority = self.priority, condition = self.condition, name = self.__class__.__name__, ) @abstractmethod def handle(self, event: Event): """ 处理事件 :return: 可选的处理结果数据(写入 EventResult.data) """ ... @property def descriptor(self) -> HandlerDescriptor: return self._descriptor # ───────────────────────────────────────────────────────────────── # 装饰器(函数式风格) # ───────────────────────────────────────────────────────────────── # 全局装饰器注册表(供 EventBus 扫描) _decorator_handlers: List[HandlerDescriptor] = [] def on_event( *event_types: Union[EventType, str], priority: int = 0, condition: Optional[Callable[[Event], bool]] = None, once: bool = False, ): """ 事件处理器装饰器(函数式风格) 示例: @on_event(EventType.DEVICE_ERROR, EventType.DEVICE_WARNING) def handle_device_issue(event: Event): print(f"设备问题: {event.message}") @on_event(EventType.SYSTEM_HEARTBEAT, priority=-10) async def async_heartbeat(event: Event): await asyncio.sleep(0) print("心跳处理(异步)") # 带条件过滤 @on_event(EventType.DEVICE_ERROR, condition=lambda e: e.params.get("code") == "E001") def handle_e001(event: Event): print("仅处理 E001 错误") """ def decorator(fn: Callable) -> Callable: desc = HandlerDescriptor( fn = fn, event_types = list(event_types), priority = priority, condition = condition, once = once, name = fn.__name__, ) _decorator_handlers.append(desc) logger.debug(f"@on_event 注册: {desc}") @functools.wraps(fn) def wrapper(*args, **kwargs): return fn(*args, **kwargs) wrapper._handler_descriptor = desc return wrapper return decorator def get_decorator_handlers() -> List[HandlerDescriptor]: """获取所有通过 @on_event 注册的处理器描述符""" return list(_decorator_handlers)