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

@@ -11,6 +11,7 @@ import { SceneManager } from './ECS/SceneManager';
import { IScene } from './ECS/IScene';
import { ServiceContainer } from './Core/ServiceContainer';
import { PluginManager } from './Core/PluginManager';
import { PluginServiceRegistry } from './Core/PluginServiceRegistry';
import { IPlugin } from './Core/Plugin';
import { WorldManager } from './ECS/WorldManager';
import { DebugConfigService } from './Utils/Debug/DebugConfigService';
@@ -109,6 +110,14 @@ export class Core {
*/
private _pluginManager: PluginManager;
/**
* 插件服务注册表
*
* 基于 ServiceToken 的类型安全服务注册表。
* Type-safe service registry based on ServiceToken.
*/
private _pluginServiceRegistry: PluginServiceRegistry;
/**
* Core配置
*/
@@ -168,6 +177,11 @@ export class Core {
this._pluginManager.initialize(this, this._serviceContainer);
this._serviceContainer.registerInstance(PluginManager, this._pluginManager);
// 初始化插件服务注册表
// Initialize plugin service registry
this._pluginServiceRegistry = new PluginServiceRegistry();
this._serviceContainer.registerInstance(PluginServiceRegistry, this._pluginServiceRegistry);
this.debug = this._config.debug ?? true;
// 初始化调试管理器
@@ -220,6 +234,39 @@ export class Core {
return this._instance._serviceContainer;
}
/**
* 获取插件服务注册表
*
* 用于基于 ServiceToken 的类型安全服务注册和获取。
* For type-safe service registration and retrieval based on ServiceToken.
*
* @returns PluginServiceRegistry 实例
* @throws 如果 Core 实例未创建
*
* @example
* ```typescript
* import { createServiceToken } from '@esengine/ecs-framework';
*
* // 定义服务令牌
* const MyServiceToken = createServiceToken<IMyService>('myService');
*
* // 注册服务
* Core.pluginServices.register(MyServiceToken, myServiceInstance);
*
* // 获取服务(可选)
* const service = Core.pluginServices.get(MyServiceToken);
*
* // 获取服务(必需,不存在则抛异常)
* const service = Core.pluginServices.require(MyServiceToken);
* ```
*/
public static get pluginServices(): PluginServiceRegistry {
if (!this._instance) {
throw new Error('Core实例未创建请先调用Core.create()');
}
return this._instance._pluginServiceRegistry;
}
/**
* 获取World管理器
*