Files
esengine/packages/editor-core/src/Services/PreviewSceneService.ts

273 lines
6.7 KiB
TypeScript
Raw Normal View History

feat: 添加跨平台运行时、资产系统和UI适配功能 (#256) * feat(platform-common): 添加WASM加载器和环境检测API * feat(rapier2d): 新增Rapier2D WASM绑定包 * feat(physics-rapier2d): 添加跨平台WASM加载器 * feat(asset-system): 添加运行时资产目录和bundle格式 * feat(asset-system-editor): 新增编辑器资产管理包 * feat(editor-core): 添加构建系统和模块管理 * feat(editor-app): 重构浏览器预览使用import maps * feat(platform-web): 添加BrowserRuntime和资产读取 * feat(engine): 添加材质系统和着色器管理 * feat(material): 新增材质系统和着色器编辑器 * feat(tilemap): 增强tilemap编辑器和动画系统 * feat(modules): 添加module.json配置 * feat(core): 添加module.json和类型定义更新 * chore: 更新依赖和构建配置 * refactor(plugins): 更新插件模板使用ModuleManifest * chore: 添加第三方依赖库 * chore: 移除BehaviourTree-ai和ecs-astar子模块 * docs: 更新README和文档主题样式 * fix: 修复Rust文档测试和添加rapier2d WASM绑定 * fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题 * feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea) * fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖 * fix: 添加缺失的包依赖修复CI构建 * fix: 修复CodeQL检测到的代码问题 * fix: 修复构建错误和缺失依赖 * fix: 修复类型检查错误 * fix(material-system): 修复tsconfig配置支持TypeScript项目引用 * fix(editor-core): 修复Rollup构建配置添加tauri external * fix: 修复CodeQL检测到的代码问题 * fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00
/**
* Preview Scene Service
*
*
* Manages isolated preview scenes for editor tools (tilemap editor, material preview, etc.)
*
*/
import { Scene, EntitySystem, Entity } from '@esengine/ecs-framework';
feat: 添加跨平台运行时、资产系统和UI适配功能 (#256) * feat(platform-common): 添加WASM加载器和环境检测API * feat(rapier2d): 新增Rapier2D WASM绑定包 * feat(physics-rapier2d): 添加跨平台WASM加载器 * feat(asset-system): 添加运行时资产目录和bundle格式 * feat(asset-system-editor): 新增编辑器资产管理包 * feat(editor-core): 添加构建系统和模块管理 * feat(editor-app): 重构浏览器预览使用import maps * feat(platform-web): 添加BrowserRuntime和资产读取 * feat(engine): 添加材质系统和着色器管理 * feat(material): 新增材质系统和着色器编辑器 * feat(tilemap): 增强tilemap编辑器和动画系统 * feat(modules): 添加module.json配置 * feat(core): 添加module.json和类型定义更新 * chore: 更新依赖和构建配置 * refactor(plugins): 更新插件模板使用ModuleManifest * chore: 添加第三方依赖库 * chore: 移除BehaviourTree-ai和ecs-astar子模块 * docs: 更新README和文档主题样式 * fix: 修复Rust文档测试和添加rapier2d WASM绑定 * fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题 * feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea) * fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖 * fix: 添加缺失的包依赖修复CI构建 * fix: 修复CodeQL检测到的代码问题 * fix: 修复构建错误和缺失依赖 * fix: 修复类型检查错误 * fix(material-system): 修复tsconfig配置支持TypeScript项目引用 * fix(editor-core): 修复Rollup构建配置添加tauri external * fix: 修复CodeQL检测到的代码问题 * fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00
/**
* Configuration for creating a preview scene
*
*/
export interface PreviewSceneConfig {
/** Unique identifier for the preview scene | 预览场景的唯一标识符 */
id: string;
/** Scene name | 场景名称 */
name?: string;
/** Systems to add to the scene | 要添加到场景的系统 */
systems?: EntitySystem[];
/** Initial clear color | 初始清除颜色 */
clearColor?: { r: number; g: number; b: number; a: number };
}
/**
* Represents an isolated preview scene for editor tools
*
*/
export interface IPreviewScene {
/** Scene instance | 场景实例 */
readonly scene: Scene;
/** Unique identifier | 唯一标识符 */
readonly id: string;
/** Scene name | 场景名称 */
readonly name: string;
/** Clear color | 清除颜色 */
clearColor: { r: number; g: number; b: number; a: number };
/**
* Create a temporary entity (auto-cleaned on dispose)
* dispose
*/
createEntity(name: string): Entity;
/**
* Remove a temporary entity
*
*/
removeEntity(entity: Entity): void;
/**
* Get all entities in the scene
*
*/
getEntities(): readonly Entity[];
/**
* Clear all temporary entities
*
*/
clearEntities(): void;
/**
* Add a system to the scene
*
*/
addSystem(system: EntitySystem): void;
/**
* Remove a system from the scene
*
*/
removeSystem(system: EntitySystem): void;
/**
* Update the scene (process systems)
*
*/
update(deltaTime: number): void;
/**
* Dispose the preview scene
*
*/
dispose(): void;
}
/**
* Preview scene implementation
*
*/
class PreviewScene implements IPreviewScene {
readonly scene: Scene;
readonly id: string;
readonly name: string;
clearColor: { r: number; g: number; b: number; a: number };
private _entities: Set<Entity> = new Set();
private _disposed = false;
constructor(config: PreviewSceneConfig) {
this.id = config.id;
this.name = config.name ?? `PreviewScene_${config.id}`;
this.clearColor = config.clearColor ?? { r: 0.1, g: 0.1, b: 0.12, a: 1.0 };
// Create isolated scene
this.scene = new Scene({ name: this.name });
// Add configured systems
if (config.systems) {
for (const system of config.systems) {
this.scene.addSystem(system);
}
}
}
createEntity(name: string): Entity {
if (this._disposed) {
throw new Error(`PreviewScene ${this.id} is disposed`);
}
const entity = this.scene.createEntity(name);
this._entities.add(entity);
return entity;
}
removeEntity(entity: Entity): void {
if (this._disposed) return;
if (this._entities.has(entity)) {
this._entities.delete(entity);
this.scene.destroyEntities([entity]);
}
}
getEntities(): readonly Entity[] {
return Array.from(this._entities);
}
clearEntities(): void {
if (this._disposed) return;
const entities = Array.from(this._entities);
if (entities.length > 0) {
this.scene.destroyEntities(entities);
}
this._entities.clear();
}
addSystem(system: EntitySystem): void {
if (this._disposed) return;
this.scene.addSystem(system);
}
removeSystem(system: EntitySystem): void {
if (this._disposed) return;
this.scene.removeSystem(system);
}
update(_deltaTime: number): void {
if (this._disposed) return;
this.scene.update();
}
dispose(): void {
if (this._disposed) return;
this._disposed = true;
// Clear all entities
this.clearEntities();
// Scene cleanup is handled by GC
}
}
/**
* Preview Scene Service - manages all preview scenes
* -
*/
export class PreviewSceneService {
private static _instance: PreviewSceneService | null = null;
private _scenes: Map<string, PreviewScene> = new Map();
private constructor() {}
/**
* Get singleton instance
*
*/
static getInstance(): PreviewSceneService {
if (!PreviewSceneService._instance) {
PreviewSceneService._instance = new PreviewSceneService();
}
return PreviewSceneService._instance;
}
/**
* Create a new preview scene
*
*/
createScene(config: PreviewSceneConfig): IPreviewScene {
if (this._scenes.has(config.id)) {
throw new Error(`Preview scene with id "${config.id}" already exists`);
}
const scene = new PreviewScene(config);
this._scenes.set(config.id, scene);
return scene;
}
/**
* Get a preview scene by ID
* ID
*/
getScene(id: string): IPreviewScene | null {
return this._scenes.get(id) ?? null;
}
/**
* Check if a preview scene exists
*
*/
hasScene(id: string): boolean {
return this._scenes.has(id);
}
/**
* Dispose a preview scene
*
*/
disposeScene(id: string): void {
const scene = this._scenes.get(id);
if (scene) {
scene.dispose();
this._scenes.delete(id);
}
}
/**
* Get all preview scene IDs
* ID
*/
getSceneIds(): string[] {
return Array.from(this._scenes.keys());
}
/**
* Dispose all preview scenes
*
*/
disposeAll(): void {
for (const scene of this._scenes.values()) {
scene.dispose();
}
this._scenes.clear();
}
/**
* Dispose the service
*
*/
dispose(): void {
this.disposeAll();
}
}
/**
* Service identifier for dependency injection
*
*/
export const IPreviewSceneService = Symbol.for('IPreviewSceneService');