# ICommandEndpoint ## 基本信息 - **类型**: UINTERFACE + C++ interface - **父类**: UInterface - **源文件**: Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h - **模块**: CharacterControl ## 功能概述 Central abstraction for all nodes in command routing graph. Pure virtual methods: GetEndpointState, GetStateChangedDelegate, GetCommandOutputDelegate, ReceiveCommand. BlueprintNativeEvents: ReceiveCommand_BP, GetEndpointDispatcher_BP. Default C++ implementations route through dispatcher for Blueprint subclasses, while C++ subclasses override directly. ## 设计用意 Uniform interface enabling heterogeneous routing graph. Routers manage collections of ICommandEndpoint without knowing concrete types. Dispatcher pattern solves UE limitation that BlueprintNativeEvent can't return delegate references directly. ## 职责范围 Defines contract for command routing participants. All routers, endpoint components, and input components implement this. Single ReceiveCommand entry point for all command types. ## 项目内依赖 | 依赖项 | 关系 | 源文件 | |--------|------|--------| | FEndpointState | 返回类型 (GetEndpointState) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h | | FCommandPacket | 参数类型 (ReceiveCommand) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h | | UEndpointDispatcher | 返回类型 (GetEndpointDispatcher_BP) | Plugins/CharacterControl/Source/CharacterControl/Public/CommandEndpoint.h | ## 对外接口 ICommandEndpoint 是命令路由图中所有参与者的统一抽象接口。任何希望接收或产出命令的对象都需要实现此接口。接口包含四个 C++ 纯虚方法和两个 BlueprintNativeEvent。 **C++ 纯虚方法**(C++ 子类直接重写): - **GetEndpointState()** -> const FEndpointState&: 返回端点的身份和配置状态。UCommandRouter::RegisterEndpoint 以此获取 GUID 和 InterestedTags - **GetStateChangedDelegate()** -> FOnEndpointStateChanged&: 返回状态变更委托引用。Router 通过 BindDynamic 订阅,当端点状态变化时触发标签聚合更新 - **GetCommandOutputDelegate()** -> FOnCommandOutput&: 返回命令输出委托引用。Router 订阅以接收端点产出的命令,转发给其他端点 - **ReceiveCommand(const FCommandPacket&)**: 接收命令的统一入口。Router 调用此方法向匹配的端点投递命令 **BlueprintNativeEvent**(蓝图子类重写): - **ReceiveCommand_BP(const FCommandPacket&)**: 蓝图端点的命令接收入口。C++ 默认实现通过调度器桥接调用此事件 - **GetEndpointDispatcher_BP()** -> UEndpointDispatcher*: 蓝图端点返回调度器实例。C++ 默认实现通过此方法获取委托引用 **默认实现策略**:C++ 默认实现(CommandEndpoint.cpp:8-26)全部通过 Execute_GetEndpointDispatcher_BP 获取 UEndpointDispatcher,然后委托执行。这意味着蓝图类(如 UEndpointComponent_BP 子类)必须重写 GetEndpointDispatcher_BP 并返回有效调度器。C++ 类(UCommandRouter、UCommandRouterComponent、UEndpointComponent)则直接重写纯虚函数,不使用调度器。 ## 使用方法 ICommandEndpoint 是接口而非具体类,通过 TScriptInterface 在多处使用: - **路由器注册**: `Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouter.h:37` -- RegisterEndpoint 接受 `TScriptInterface`,从接口获取端点状态、委托并完成注册 - **路由器实现**: `Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouter.h:14` -- UCommandRouter 实现此接口,作为端点参与上级路由器的路由 - **组件实现**: `Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouterComponent.h:14` -- UCommandRouterComponent 实现此接口,委托给 InternalRouter - **端点组件实现**: `Plugins/CharacterControl/Source/CharacterControl/Public/EndpointComponent.h:13` -- UEndpointComponent 实现此接口,作为蓝图端点的基类 - **默认 C++ 实现**: `Plugins/CharacterControl/Source/CharacterControl/Private/CommandEndpoint.cpp:8-26` -- 所有纯虚函数的默认实现,通过调度器桥接蓝图 ## 用例 - **Router 实现端点的 ReceiveCommand**: `Plugins/CharacterControl/Source/CharacterControl/Public/CommandRouter.h:22-25` -- UCommandRouter 直接重写 ReceiveCommand、GetEndpointState、GetStateChangedDelegate、GetCommandOutputDelegate,不使用调度器桥接 - **EndpointComponent 实现端点的 ReceiveCommand**: `Plugins/CharacterControl/Source/CharacterControl/Public/EndpointComponent.h:30-33` -- UEndpointComponent 直接重写纯虚方法,ReceiveCommand 转调 BlueprintImplementableEvent OnCommandReceived - **端点注册入口**: `Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouter.cpp:45-84` -- RegisterEndpoint 通过 TScriptInterface 获取端点的 EndpointGuid、委托,绑定状态变更和命令输出回调,执行标签聚合 - **自动发现注册**: `Plugins/CharacterControl/Source/CharacterControl/Private/CommandRouterComponent.cpp:37-41` -- AutoRegisterEndpoints 遍历 Actor 组件,通过 `Implements()` 检查并注册所有实现接口的兄弟组件 - **蓝图桥接**: `Plugins/CharacterControl/Source/CharacterControl/Private/CommandEndpoint.cpp:23-26` -- 蓝图类没有重写 ReceiveCommand 时,C++ 默认实现调用 Execute_ReceiveCommand_BP,由蓝图元数据系统查找蓝图重写