# -*- coding: utf-8 -*- """ Action 工厂注册表 ───────────────────────────────────────────────────────────────── 将 ActionType → handler 函数的映射集中管理 支持: - 内置 handler 自动注册 - 运行时动态注册/覆盖 handler - 通过 create() 工厂方法快速创建 Action 实例 ───────────────────────────────────────────────────────────────── """ from __future__ import annotations import logging import threading from typing import Callable, Dict, List, Optional, Union from uas.action.action_model import Action, make_action from uas.action.action_type import ActionType logger = logging.getLogger(__name__) class ActionFactory: """ Action 工厂(单例) ───────────────────────────────────────────────────────────── 使用方式: factory = ActionFactory.instance() # 注册自定义 handler factory.register(ActionType.CAPTURE_PHOTO, my_photo_handler) # 创建 Action 实例(自动绑定 handler) action = factory.create( ActionType.CAPTURE_PHOTO, source = "camera-01", resolution = "4K", format = "jpg", ) ───────────────────────────────────────────────────────────── """ _instance = None _lock = threading.Lock() @classmethod def instance(cls) -> "ActionFactory": if cls._instance is None: cls._instance = cls() return cls._instance def __init__(self): # { type_key: handler_fn } self._handlers: Dict[str, Callable] = {} self._init_builtin() def _init_builtin(self): """自动注册所有内置 handler""" from uas.action.actions.builtin_actions import BUILTIN_HANDLERS for action_type, handler in BUILTIN_HANDLERS.items(): self.register(action_type, handler) logger.info(f"✅ ActionFactory 初始化,内置 handler={len(self._handlers)}") # ── 注册 ────────────────────────────────────────────────────── def register( self, action_type: Union[ActionType, str], handler: Callable, override: bool = True, ) -> None: """ 注册 Action 处理函数 :param action_type: ActionType 枚举 或 自定义字符串 :param handler: fn(action: Action, ctx: ActionContext) -> Any :param override: True=允许覆盖已有 handler """ key = action_type.value if isinstance(action_type, ActionType) else str(action_type) with self._lock: if key in self._handlers and not override: logger.warning(f"handler 已存在且 override=False,跳过: {key}") return self._handlers[key] = handler logger.info(f"注册 handler: {key} -> {handler.__name__}") def unregister(self, action_type: Union[ActionType, str]) -> bool: """注销 handler""" key = action_type.value if isinstance(action_type, ActionType) else str(action_type) with self._lock: if key in self._handlers: del self._handlers[key] logger.info(f"注销 handler: {key}") return True return False def get_handler(self, action_type: Union[ActionType, str]) -> Optional[Callable]: """获取指定类型的 handler""" key = action_type.value if isinstance(action_type, ActionType) else str(action_type) return self._handlers.get(key) def has_handler(self, action_type: Union[ActionType, str]) -> bool: key = action_type.value if isinstance(action_type, ActionType) else str(action_type) return key in self._handlers def registered_types(self) -> List[str]: return list(self._handlers.keys()) # ── 工厂创建 ────────────────────────────────────────────────── def create( self, action_type: Union[ActionType, str], source: str = "system", priority: int = 0, handler: Optional[Callable] = None, **params ) -> Action: """ 工厂方法:创建并自动绑定 handler 的 Action 实例 :param action_type: 行为类型 :param source: 触发来源 :param priority: 执行优先级 :param handler: 若指定则覆盖注册表中的 handler :param params: 传递给 Action 的业务参数 :return: Action 实例 """ resolved_handler = handler or self.get_handler(action_type) if resolved_handler is None: logger.warning(f"未找到 handler: {action_type},将使用空处理器") resolved_handler = _noop_handler action = make_action( action_type = action_type, handler = resolved_handler, source = source, priority = priority, **params, ) logger.debug(f"创建 Action: {action}") return action def create_batch(self, specs: List[dict]) -> List[Action]: """ 批量创建 Action :param specs: [{"action_type": ..., "source": ..., **params}, ...] """ return [self.create(**spec) for spec in specs] def _noop_handler(action, ctx): """空处理器(未注册 handler 时的占位)""" logger.warning(f"[noop] Action [{action.type_key}] 无处理器,跳过执行") return None # 全局工厂实例 action_factory = ActionFactory.instance()