feat(editor-app): 重构浏览器预览使用import maps

This commit is contained in:
yhh
2025-12-03 16:19:50 +08:00
parent 55f644a091
commit c2f8cb5272
50 changed files with 5995 additions and 1499 deletions

View File

@@ -13,6 +13,7 @@ interface DialogState {
showSettings: boolean;
showAbout: boolean;
showPluginGenerator: boolean;
showBuildSettings: boolean;
errorDialog: ErrorDialogData | null;
confirmDialog: ConfirmDialogData | null;
@@ -22,6 +23,7 @@ interface DialogState {
setShowSettings: (show: boolean) => void;
setShowAbout: (show: boolean) => void;
setShowPluginGenerator: (show: boolean) => void;
setShowBuildSettings: (show: boolean) => void;
setErrorDialog: (data: ErrorDialogData | null) => void;
setConfirmDialog: (data: ConfirmDialogData | null) => void;
closeAllDialogs: () => void;
@@ -34,6 +36,7 @@ export const useDialogStore = create<DialogState>((set) => ({
showSettings: false,
showAbout: false,
showPluginGenerator: false,
showBuildSettings: false,
errorDialog: null,
confirmDialog: null,
@@ -43,6 +46,7 @@ export const useDialogStore = create<DialogState>((set) => ({
setShowSettings: (show) => set({ showSettings: show }),
setShowAbout: (show) => set({ showAbout: show }),
setShowPluginGenerator: (show) => set({ showPluginGenerator: show }),
setShowBuildSettings: (show) => set({ showBuildSettings: show }),
setErrorDialog: (data) => set({ errorDialog: data }),
setConfirmDialog: (data) => set({ confirmDialog: data }),
@@ -53,6 +57,7 @@ export const useDialogStore = create<DialogState>((set) => ({
showSettings: false,
showAbout: false,
showPluginGenerator: false,
showBuildSettings: false,
errorDialog: null,
confirmDialog: null
})

View File

@@ -13,8 +13,8 @@ import { GizmoPlugin } from '../../plugins/builtin/GizmoPlugin';
import { SceneInspectorPlugin } from '../../plugins/builtin/SceneInspectorPlugin';
import { ProfilerPlugin } from '../../plugins/builtin/ProfilerPlugin';
import { EditorAppearancePlugin } from '../../plugins/builtin/EditorAppearancePlugin';
import { PluginConfigPlugin } from '../../plugins/builtin/PluginConfigPlugin';
import { ProjectSettingsPlugin } from '../../plugins/builtin/ProjectSettingsPlugin';
// Note: PluginConfigPlugin removed - module management is now unified in ProjectSettingsPlugin
// 统一模块插件(从编辑器包导入完整插件,包含 runtime + editor
import { BehaviorTreePlugin } from '@esengine/behavior-tree-editor';
@@ -22,6 +22,9 @@ import { Physics2DPlugin } from '@esengine/physics-rapier2d-editor';
import { TilemapPlugin } from '@esengine/tilemap-editor';
import { UIPlugin } from '@esengine/ui-editor';
import { BlueprintPlugin } from '@esengine/blueprint-editor';
import { MaterialPlugin } from '@esengine/material-editor';
import { SpritePlugin } from '@esengine/sprite-editor';
import { ShaderEditorPlugin } from '@esengine/shader-editor';
export class PluginInstaller {
/**
@@ -34,13 +37,12 @@ export class PluginInstaller {
{ name: 'SceneInspectorPlugin', plugin: SceneInspectorPlugin },
{ name: 'ProfilerPlugin', plugin: ProfilerPlugin },
{ name: 'EditorAppearancePlugin', plugin: EditorAppearancePlugin },
{ name: 'PluginConfigPlugin', plugin: PluginConfigPlugin },
{ name: 'ProjectSettingsPlugin', plugin: ProjectSettingsPlugin },
];
for (const { name, plugin } of builtinPlugins) {
if (!plugin || !plugin.descriptor) {
console.error(`[PluginInstaller] ${name} is invalid: missing descriptor`, plugin);
if (!plugin || !plugin.manifest) {
console.error(`[PluginInstaller] ${name} is invalid: missing manifest`, plugin);
continue;
}
try {
@@ -52,20 +54,23 @@ export class PluginInstaller {
// 统一模块插件runtime + editor
const modulePlugins = [
{ name: 'SpritePlugin', plugin: SpritePlugin },
{ name: 'TilemapPlugin', plugin: TilemapPlugin },
{ name: 'UIPlugin', plugin: UIPlugin },
{ name: 'BehaviorTreePlugin', plugin: BehaviorTreePlugin },
{ name: 'Physics2DPlugin', plugin: Physics2DPlugin },
{ name: 'BlueprintPlugin', plugin: BlueprintPlugin },
{ name: 'MaterialPlugin', plugin: MaterialPlugin },
{ name: 'ShaderEditorPlugin', plugin: ShaderEditorPlugin },
];
for (const { name, plugin } of modulePlugins) {
if (!plugin || !plugin.descriptor) {
console.error(`[PluginInstaller] ${name} is invalid: missing descriptor`, plugin);
if (!plugin || !plugin.manifest) {
console.error(`[PluginInstaller] ${name} is invalid: missing manifest`, plugin);
continue;
}
// 详细日志,检查 editorModule 是否存在
console.log(`[PluginInstaller] ${name}: descriptor.id=${plugin.descriptor.id}, hasRuntimeModule=${!!plugin.runtimeModule}, hasEditorModule=${!!plugin.editorModule}`);
console.log(`[PluginInstaller] ${name}: manifest.id=${plugin.manifest.id}, hasRuntimeModule=${!!plugin.runtimeModule}, hasEditorModule=${!!plugin.editorModule}`);
try {
pluginManager.register(plugin);
} catch (error) {

View File

@@ -1,4 +1,5 @@
import { Core, ComponentRegistry as CoreComponentRegistry } from '@esengine/ecs-framework';
import { invoke } from '@tauri-apps/api/core';
import {
UIRegistry,
MessageHub,
@@ -27,8 +28,18 @@ import {
IDialogService,
IFileSystemService,
CompilerRegistry,
ICompilerRegistry
ICompilerRegistry,
IViewportService_ID,
IPreviewSceneService,
IEditorViewportServiceIdentifier,
PreviewSceneService,
EditorViewportService,
BuildService,
WebBuildPipeline,
WeChatBuildPipeline,
moduleRegistry
} from '@esengine/editor-core';
import { ViewportService } from '../../services/ViewportService';
import { TransformComponent } from '@esengine/engine-core';
import { SpriteComponent, SpriteAnimatorComponent } from '@esengine/sprite';
import { CameraComponent } from '@esengine/camera';
@@ -65,6 +76,8 @@ import {
AnimationClipsFieldEditor
} from '../../infrastructure/field-editors';
import { TransformComponentInspector } from '../../components/inspectors/component-inspectors/TransformComponentInspector';
import { buildFileSystem } from '../../services/BuildFileSystemService';
import { TauriModuleFileSystem } from '../../services/TauriModuleFileSystem';
export interface EditorServices {
uiRegistry: UIRegistry;
@@ -90,6 +103,7 @@ export interface EditorServices {
inspectorRegistry: InspectorRegistry;
propertyRendererRegistry: PropertyRendererRegistry;
fieldEditorRegistry: FieldEditorRegistry;
buildService: BuildService;
}
export class ServiceRegistry {
@@ -172,6 +186,22 @@ export class ServiceRegistry {
Core.services.registerInstance(IDialogService, dialog);
Core.services.registerInstance(IFileSystemService, fileSystem);
// Register viewport service for editor panels
// 注册视口服务供编辑器面板使用
const viewportService = ViewportService.getInstance();
Core.services.registerInstance(IViewportService_ID, viewportService);
// Register preview scene service for isolated preview scenes
// 注册预览场景服务,用于隔离的预览场景
const previewSceneService = PreviewSceneService.getInstance();
Core.services.registerInstance(IPreviewSceneService, previewSceneService);
// Register editor viewport service for coordinating viewports with overlays
// 注册编辑器视口服务,协调带有覆盖层的视口
const editorViewportService = EditorViewportService.getInstance();
editorViewportService.setViewportService(viewportService);
Core.services.registerInstance(IEditorViewportServiceIdentifier, editorViewportService);
const inspectorRegistry = new InspectorRegistry();
Core.services.registerInstance(InspectorRegistry, inspectorRegistry);
Core.services.registerInstance(IInspectorRegistry, inspectorRegistry); // Symbol 注册用于跨包插件访问
@@ -204,6 +234,43 @@ export class ServiceRegistry {
// Register component inspectors
componentInspectorRegistry.register(new TransformComponentInspector());
// 注册构建服务
// Register build service
const buildService = new BuildService();
// Register Web build pipeline with file system service
// 注册 Web 构建管线并注入文件系统服务
const webPipeline = new WebBuildPipeline();
webPipeline.setFileSystem(buildFileSystem);
// Get engine modules path from Tauri backend
// 从 Tauri 后端获取引擎模块路径
invoke<string>('get_engine_modules_base_path').then(enginePath => {
console.log('[ServiceRegistry] Engine modules path:', enginePath);
webPipeline.setEngineModulesPath(enginePath);
}).catch(err => {
console.warn('[ServiceRegistry] Failed to get engine modules path:', err);
});
buildService.register(webPipeline);
// Register WeChat build pipeline
// 注册微信构建管线
const wechatPipeline = new WeChatBuildPipeline();
wechatPipeline.setFileSystem(buildFileSystem);
buildService.register(wechatPipeline);
Core.services.registerInstance(BuildService, buildService);
// Initialize ModuleRegistry with Tauri file system
// 使用 Tauri 文件系统初始化 ModuleRegistry
// Engine modules are read via Tauri commands from local file system
// 引擎模块通过 Tauri 命令从本地文件系统读取
const tauriModuleFs = new TauriModuleFileSystem();
moduleRegistry.initialize(tauriModuleFs, '/engine').catch(err => {
console.warn('[ServiceRegistry] Failed to initialize ModuleRegistry:', err);
});
// 注册默认场景模板 - 创建默认相机
// Register default scene template - creates default camera
this.registerDefaultSceneTemplate();
@@ -231,7 +298,8 @@ export class ServiceRegistry {
notification,
inspectorRegistry,
propertyRendererRegistry,
fieldEditorRegistry
fieldEditorRegistry,
buildService
};
}