refactor(arch): 改进 ServiceToken 设计,统一服务获取模式 (#300)

* refactor(arch): 移除全局变量,使用 ServiceToken 模式

- 创建 PluginServiceRegistry 类,提供类型安全的服务注册/获取
- 添加 ProfilerServiceToken 和 CollisionLayerConfigToken
- 重构所有 __PROFILER_SERVICE__ 全局变量访问为 getProfilerService()
- 重构 __PHYSICS_RAPIER2D__ 全局变量访问为 CollisionLayerConfigToken
- 在 Core 类添加 pluginServices 静态属性
- 添加 getService.ts 辅助模块简化服务获取

这是 ServiceToken 模式重构的第一阶段,移除了最常用的两个全局变量。
后续可继续应用到其他模块(Camera/Audio 等)。

* refactor(arch): 改进 ServiceToken 设计,移除重复常量

- tokens.ts: 从 engine-core 导入 createServiceToken(符合规范)
- tokens.ts: Token 使用接口 IProfilerService 而非具体类
- 移除 AssetPickerDialog 和 ContentBrowser 中重复的 MANAGED_ASSET_DIRECTORIES
- 统一从 editor-core 导入 MANAGED_ASSET_DIRECTORIES

* fix(type): 修复 IProfilerService 接口与实现类型不匹配

- 将 ProfilerData 等数据类型移到 tokens.ts 以避免循环依赖
- ProfilerService 显式实现 IProfilerService 接口
- 更新使用方使用 IProfilerService 接口类型而非具体类

* refactor(type): 移除类型重导出,改进类型安全

- 删除 ProfilerService.ts 中的类型重导出,消费方直接从 tokens.ts 导入
- PanelDescriptor 接口添加 titleZh 属性,移除 App.tsx 中的 as any
- 改进 useDynamicIcon.ts 的类型安全,使用正确的 Record 类型

* refactor(arch): 为模块添加 ServiceToken 支持

- Material System: 创建 tokens.ts,定义 IMaterialManager 接口和 MaterialManagerToken
- Audio: 创建预留 tokens.ts 文件,为未来 AudioManager 服务扩展做准备
- Camera: 创建预留 tokens.ts 文件,为未来 CameraManager 服务扩展做准备

遵循"谁定义接口,谁导出 Token"原则,统一服务访问模式
This commit is contained in:
YHH
2025-12-09 11:07:44 +08:00
committed by GitHub
parent c71a47f2b0
commit 995fa2d514
31 changed files with 1024 additions and 210 deletions

View File

@@ -0,0 +1,114 @@
/**
* 编辑器服务令牌
* Editor Service Tokens
*
* 遵循"谁定义接口,谁导出 Token"原则。
* 这些服务定义在 editor-app 中,所以 Token 也在这里定义。
*
* Following "who defines interface, who exports Token" principle.
* These services are defined in editor-app, so Tokens are also defined here.
*/
import { createServiceToken } from '@esengine/engine-core';
// ============================================================================
// Profiler Data Types (定义在这里以避免循环依赖)
// ============================================================================
export interface SystemPerformanceData {
name: string;
executionTime: number;
entityCount: number;
averageTime: number;
percentage: number;
}
export interface RemoteEntity {
id: number;
name: string;
enabled: boolean;
active: boolean;
activeInHierarchy: boolean;
componentCount: number;
componentTypes: string[];
parentId: number | null;
childIds: number[];
depth: number;
tag: number;
updateOrder: number;
}
export interface ProfilerData {
totalFrameTime: number;
systems: SystemPerformanceData[];
entityCount: number;
componentCount: number;
fps: number;
entities?: RemoteEntity[];
}
/**
* 高级性能数据结构(用于高级性能分析器)
* Advanced profiler data structure
*/
export interface AdvancedProfilerDataPayload {
advancedProfiler?: any;
performance?: any;
systems?: any;
}
// ============================================================================
// Profiler Service Token
// ============================================================================
/**
* ProfilerService 接口(用于类型检查)
* ProfilerService interface (for type checking)
*
* 提供远程性能分析功能,包括:
* - WebSocket 连接管理
* - 性能数据收集和分发
* - 远程日志接收
*
* Provides remote profiling capabilities including:
* - WebSocket connection management
* - Performance data collection and distribution
* - Remote log reception
*/
export interface IProfilerService {
/** 检查是否已连接 | Check if connected */
isConnected(): boolean;
/** 检查服务器是否运行 | Check if server is running */
isServerActive(): boolean;
/** 手动启动服务器 | Manually start server */
manualStartServer(): Promise<void>;
/** 手动停止服务器 | Manually stop server */
manualStopServer(): Promise<void>;
/** 订阅数据更新 | Subscribe to data updates */
subscribe(callback: (data: ProfilerData) => void): () => void;
/** 订阅高级数据更新 | Subscribe to advanced data updates */
subscribeAdvanced(callback: (data: AdvancedProfilerDataPayload) => void): () => void;
/** 请求实体详情 | Request entity details */
requestEntityDetails(entityId: number): void;
/** 请求高级性能分析数据 | Request advanced profiler data */
requestAdvancedProfilerData(): void;
/** 设置选中的函数 | Set selected function */
setProfilerSelectedFunction(functionName: string | null): void;
/** 销毁服务 | Destroy service */
destroy(): void;
}
/**
* ProfilerService 的服务令牌
* Service token for ProfilerService
*/
export const ProfilerServiceToken = createServiceToken<IProfilerService>('profilerService');