refactor(plugin): 重构插件系统架构,统一类型导入路径 (#296)
* refactor(plugin): 重构插件系统架构,统一类型导入路径 ## 主要更改 ### 新增 @esengine/plugin-types 包 - 提供打破循环依赖的最小类型定义 - 包含 ServiceToken, createServiceToken, PluginServiceRegistry, IEditorModuleBase ### engine-core 类型统一 - IPlugin<T> 泛型参数改为 T = unknown - 所有运行时类型(IRuntimeModule, ModuleManifest, SystemContext)在此定义 - 新增 PluginServiceRegistry.ts 导出服务令牌相关类型 ### editor-core 类型优化 - 重命名 IPluginLoader.ts 为 EditorModule.ts - 新增 IEditorPlugin = IPlugin<IEditorModuleLoader> 类型别名 - 移除弃用别名 IPluginLoader, IRuntimeModuleLoader ### 编辑器插件更新 - 所有 9 个编辑器插件使用 IEditorPlugin 类型 - 统一从 editor-core 导入编辑器类型 ### 服务令牌规范 - 各模块在 tokens.ts 中定义自己的服务接口和令牌 - 遵循"谁定义接口,谁导出 Token"原则 ## 导入规范 | 场景 | 导入来源 | |------|---------| | 运行时模块 | @esengine/engine-core | | 编辑器插件 | @esengine/editor-core | | 服务令牌 | @esengine/engine-core | * refactor(plugin): 完善服务令牌规范,统一运行时模块 ## 更改内容 ### 运行时模块优化 - particle: 使用 PluginServiceRegistry 获取依赖服务 - physics-rapier2d: 通过服务令牌注册/获取物理查询接口 - tilemap: 使用服务令牌获取物理系统依赖 - sprite: 导出服务令牌 - ui: 导出服务令牌 - behavior-tree: 使用服务令牌系统 ### 资产系统增强 - IAssetManager 接口扩展 - 加载器使用服务令牌获取依赖 ### 运行时核心 - GameRuntime 使用 PluginServiceRegistry - 导出服务令牌相关类型 ### 编辑器服务 - EngineService 适配新的服务令牌系统 - AssetRegistryService 优化 * fix: 修复 editor-app 和 behavior-tree-editor 中的类型引用 - editor-app/PluginLoader.ts: 使用 IPlugin 替代 IPluginLoader - behavior-tree-editor: 使用 IEditorPlugin 替代 IPluginLoader * fix(ui): 添加缺失的 ecs-engine-bindgen 依赖 UIRuntimeModule 使用 EngineBridgeToken,需要声明对 ecs-engine-bindgen 的依赖 * fix(type): 解决 ServiceToken 跨包类型兼容性问题 - 在 engine-core 中直接定义 ServiceToken 和 PluginServiceRegistry 而不是从 plugin-types 重新导出,确保 tsup 生成的类型声明 以 engine-core 作为类型来源 - 移除 RuntimeResolver.ts 中的硬编码模块 ID 检查, 改用 module.json 中的 name 配置 - 修复 pnpm-lock.yaml 中的依赖记录 * refactor(arch): 改进架构设计,移除硬编码 - 统一类型导出:editor-core 从 engine-core 导入 IEditorModuleBase - RuntimeResolver: 将硬编码路径改为配置常量和搜索路径列表 - 添加跨平台安装路径支持(Windows/macOS/Linux) - 使用 ENGINE_WASM_CONFIG 配置引擎 WASM 文件信息 - IBundlePackOptions 添加 preloadBundles 配置项 * fix(particle): 添加缺失的 ecs-engine-bindgen 依赖 ParticleRuntimeModule 导入了 @esengine/ecs-engine-bindgen 的 tokens, 但 package.json 中未声明该依赖,导致 CI 构建失败。 * fix(physics-rapier2d): 移除不存在的 PhysicsSystemContext 导出 PhysicsRuntimeModule 中不存在该类型,导致 type-check 失败
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
"@esengine/asset-system": "workspace:*",
|
||||
"@esengine/asset-system-editor": "workspace:*",
|
||||
"@esengine/engine-core": "workspace:*",
|
||||
"@esengine/plugin-types": "workspace:*",
|
||||
"@tauri-apps/api": "^2.2.0",
|
||||
"@babel/core": "^7.28.3",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
*
|
||||
* 定义编辑器专用的模块接口和 UI 描述符类型。
|
||||
* Define editor-specific module interfaces and UI descriptor types.
|
||||
*
|
||||
* IEditorModuleLoader 扩展自 engine-core 的 IEditorModuleBase。
|
||||
* IEditorModuleLoader extends IEditorModuleBase from engine-core.
|
||||
*/
|
||||
|
||||
import type { ServiceContainer } from '@esengine/ecs-framework';
|
||||
|
||||
// 从 PluginDescriptor 重新导出(来源于 engine-core)
|
||||
// 统一从 engine-core 导入所有类型,避免直接依赖 plugin-types
|
||||
export type {
|
||||
LoadingPhase,
|
||||
SystemContext,
|
||||
@@ -17,7 +19,8 @@ export type {
|
||||
ModuleManifest,
|
||||
ModuleCategory,
|
||||
ModulePlatform,
|
||||
ModuleExports
|
||||
ModuleExports,
|
||||
IEditorModuleBase
|
||||
} from './PluginDescriptor';
|
||||
|
||||
// ============================================================================
|
||||
@@ -219,23 +222,23 @@ export interface FileCreationTemplate {
|
||||
// 编辑器模块接口 | Editor Module Interface
|
||||
// ============================================================================
|
||||
|
||||
import type { IEditorModuleBase } from './PluginDescriptor';
|
||||
|
||||
/**
|
||||
* 编辑器模块加载器
|
||||
* Editor module loader
|
||||
*
|
||||
* 扩展 IEditorModuleBase 并添加编辑器特定的 UI 描述符方法。
|
||||
* Extends IEditorModuleBase and adds editor-specific UI descriptor methods.
|
||||
*
|
||||
* 生命周期方法继承自 IEditorModuleBase:
|
||||
* Lifecycle methods inherited from IEditorModuleBase:
|
||||
* - install(services) / uninstall()
|
||||
* - onEditorReady() / onProjectOpen() / onProjectClose()
|
||||
* - onSceneLoaded() / onSceneSaving()
|
||||
* - setLocale()
|
||||
*/
|
||||
export interface IEditorModuleLoader {
|
||||
/**
|
||||
* 安装编辑器模块
|
||||
* Install editor module
|
||||
*/
|
||||
install(services: ServiceContainer): Promise<void>;
|
||||
|
||||
/**
|
||||
* 卸载编辑器模块
|
||||
* Uninstall editor module
|
||||
*/
|
||||
uninstall?(): Promise<void>;
|
||||
|
||||
export interface IEditorModuleLoader extends IEditorModuleBase {
|
||||
/**
|
||||
* 返回面板描述列表
|
||||
* Get panel descriptors
|
||||
@@ -289,44 +292,38 @@ export interface IEditorModuleLoader {
|
||||
* Get file creation templates
|
||||
*/
|
||||
getFileCreationTemplates?(): FileCreationTemplate[];
|
||||
|
||||
// ===== 生命周期钩子 | Lifecycle hooks =====
|
||||
|
||||
/** 编辑器就绪 | Editor ready */
|
||||
onEditorReady?(): void | Promise<void>;
|
||||
|
||||
/** 项目打开 | Project open */
|
||||
onProjectOpen?(projectPath: string): void | Promise<void>;
|
||||
|
||||
/** 项目关闭 | Project close */
|
||||
onProjectClose?(): void | Promise<void>;
|
||||
|
||||
/** 场景加载 | Scene loaded */
|
||||
onSceneLoaded?(scenePath: string): void;
|
||||
|
||||
/** 场景保存前 | Before scene save */
|
||||
onSceneSaving?(scenePath: string): boolean | void;
|
||||
|
||||
/** 设置语言 | Set locale */
|
||||
setLocale?(locale: string): void;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 类型别名(向后兼容)| Type Aliases (backward compatibility)
|
||||
// 编辑器插件类型 | Editor Plugin Type
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* IPluginLoader 类型别名
|
||||
*
|
||||
* @deprecated 使用 IPlugin 代替。IPluginLoader 只是 IPlugin 的别名。
|
||||
* @deprecated Use IPlugin instead. IPluginLoader is just an alias for IPlugin.
|
||||
*/
|
||||
export type { IPlugin as IPluginLoader } from './PluginDescriptor';
|
||||
import type { IPlugin } from './PluginDescriptor';
|
||||
|
||||
/**
|
||||
* IRuntimeModuleLoader 类型别名
|
||||
* 编辑器插件类型
|
||||
* Editor plugin type
|
||||
*
|
||||
* @deprecated 使用 IRuntimeModule 代替。
|
||||
* @deprecated Use IRuntimeModule instead.
|
||||
* 这是开发编辑器插件时应使用的类型。
|
||||
* 它是 IPlugin 的特化版本,editorModule 类型为 IEditorModuleLoader。
|
||||
*
|
||||
* This is the type to use when developing editor plugins.
|
||||
* It's a specialized version of IPlugin with editorModule typed as IEditorModuleLoader.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { IEditorPlugin, IEditorModuleLoader } from '@esengine/editor-core';
|
||||
*
|
||||
* class MyEditorModule implements IEditorModuleLoader {
|
||||
* async install(services) { ... }
|
||||
* getPanels() { return [...]; }
|
||||
* }
|
||||
*
|
||||
* export const MyPlugin: IEditorPlugin = {
|
||||
* manifest,
|
||||
* runtimeModule: new MyRuntimeModule(),
|
||||
* editorModule: new MyEditorModule()
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
export type { IRuntimeModule as IRuntimeModuleLoader } from './PluginDescriptor';
|
||||
export type IEditorPlugin = IPlugin<IEditorModuleLoader>;
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
// 从 engine-core 重新导出所有类型
|
||||
// 包括 IEditorModuleBase(原来在 plugin-types 中定义,现在统一从 engine-core 导出)
|
||||
export type {
|
||||
LoadingPhase,
|
||||
SystemContext,
|
||||
@@ -15,7 +16,8 @@ export type {
|
||||
ModuleManifest,
|
||||
ModuleCategory,
|
||||
ModulePlatform,
|
||||
ModuleExports
|
||||
ModuleExports,
|
||||
IEditorModuleBase
|
||||
} from '@esengine/engine-core';
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ import type {
|
||||
import type {
|
||||
SystemContext,
|
||||
IEditorModuleLoader
|
||||
} from './IPluginLoader';
|
||||
} from './EditorModule';
|
||||
import { EntityCreationRegistry } from '../Services/EntityCreationRegistry';
|
||||
import { ComponentActionRegistry } from '../Services/ComponentActionRegistry';
|
||||
import { FileActionRegistry } from '../Services/FileActionRegistry';
|
||||
@@ -821,22 +821,18 @@ export class PluginManager implements IService {
|
||||
this.currentContext = context;
|
||||
|
||||
logger.info('Creating systems for scene...');
|
||||
console.log('[PluginManager] createSystemsForScene called, context.assetManager:', context.assetManager ? 'exists' : 'null');
|
||||
|
||||
const sortedPlugins = this.sortByLoadingPhase('runtime');
|
||||
console.log('[PluginManager] Sorted plugins for runtime:', sortedPlugins);
|
||||
|
||||
// 第一阶段:创建所有系统
|
||||
// Phase 1: Create all systems
|
||||
for (const pluginId of sortedPlugins) {
|
||||
const plugin = this.plugins.get(pluginId);
|
||||
console.log(`[PluginManager] Plugin ${pluginId}: enabled=${plugin?.enabled}, state=${plugin?.state}, hasRuntimeModule=${!!plugin?.plugin.runtimeModule}`);
|
||||
if (!plugin?.enabled || plugin.state === 'error') continue;
|
||||
|
||||
const runtimeModule = plugin.plugin.runtimeModule;
|
||||
if (runtimeModule?.createSystems) {
|
||||
try {
|
||||
console.log(`[PluginManager] Calling createSystems for: ${pluginId}`);
|
||||
runtimeModule.createSystems(scene, context);
|
||||
logger.debug(`Systems created for: ${pluginId}`);
|
||||
} catch (e) {
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
*/
|
||||
|
||||
export * from './PluginDescriptor';
|
||||
export * from './IPluginLoader';
|
||||
export * from './EditorModule';
|
||||
export * from './PluginManager';
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* Uses .meta files to persistently store each asset's GUID.
|
||||
*/
|
||||
|
||||
import { Core, createLogger, PlatformDetector } from '@esengine/ecs-framework';
|
||||
import { Core, createLogger, PlatformDetector, type IService } from '@esengine/ecs-framework';
|
||||
import { MessageHub } from './MessageHub';
|
||||
import {
|
||||
AssetMetaManager,
|
||||
@@ -219,8 +219,12 @@ class SimpleAssetDatabase {
|
||||
|
||||
/**
|
||||
* Asset Registry Service
|
||||
* 资产注册表服务
|
||||
*
|
||||
* 实现 IService 接口以便与 ServiceContainer 集成
|
||||
* Implements IService interface for ServiceContainer integration
|
||||
*/
|
||||
export class AssetRegistryService {
|
||||
export class AssetRegistryService implements IService {
|
||||
private _database: SimpleAssetDatabase;
|
||||
private _projectPath: string | null = null;
|
||||
private _manifest: AssetManifest | null = null;
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
import { injectable } from 'tsyringe';
|
||||
import type { IService } from '@esengine/ecs-framework';
|
||||
import type { ComponentAction } from '../Plugin/IPluginLoader';
|
||||
import type { ComponentAction } from '../Plugin/EditorModule';
|
||||
// Re-export ComponentAction type from Plugin system
|
||||
export type { ComponentAction } from '../Plugin/IPluginLoader';
|
||||
export type { ComponentAction } from '../Plugin/EditorModule';
|
||||
|
||||
@injectable()
|
||||
export class ComponentActionRegistry implements IService {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { IService } from '@esengine/ecs-framework';
|
||||
import type { FileActionHandler, FileCreationTemplate } from '../Plugin/IPluginLoader';
|
||||
import type { FileActionHandler, FileCreationTemplate } from '../Plugin/EditorModule';
|
||||
|
||||
// Re-export for backwards compatibility
|
||||
export type { FileCreationTemplate } from '../Plugin/IPluginLoader';
|
||||
export type { FileCreationTemplate } from '../Plugin/EditorModule';
|
||||
|
||||
/**
|
||||
* 资产创建消息映射
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { IService } from '@esengine/ecs-framework';
|
||||
import { Injectable } from '@esengine/ecs-framework';
|
||||
import { createLogger } from '@esengine/ecs-framework';
|
||||
import type { ISerializer } from '../Plugin/IPluginLoader';
|
||||
import type { ISerializer } from '../Plugin/EditorModule';
|
||||
|
||||
const logger = createLogger('SerializerRegistry');
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ export interface ToolbarItem {
|
||||
}
|
||||
|
||||
// Re-export PanelPosition and PanelDescriptor from Plugin system
|
||||
export { PanelPosition, type PanelDescriptor } from '../Plugin/IPluginLoader';
|
||||
export { PanelPosition, type PanelDescriptor } from '../Plugin/EditorModule';
|
||||
|
||||
/**
|
||||
* UI 扩展点类型
|
||||
@@ -103,4 +103,4 @@ export enum UIExtensionType {
|
||||
}
|
||||
|
||||
// Re-export EntityCreationTemplate from Plugin system
|
||||
export type { EntityCreationTemplate } from '../Plugin/IPluginLoader';
|
||||
export type { EntityCreationTemplate } from '../Plugin/EditorModule';
|
||||
|
||||
Reference in New Issue
Block a user