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检测到的代码问题
This commit is contained in:
YHH
2025-12-03 22:15:22 +08:00
committed by GitHub
parent caf7622aa0
commit 63f006ab62
496 changed files with 77601 additions and 4067 deletions

View File

@@ -0,0 +1,272 @@
/**
* Preview Scene Service
* 预览场景服务
*
* Manages isolated preview scenes for editor tools (tilemap editor, material preview, etc.)
* 管理编辑器工具的隔离预览场景(瓦片地图编辑器、材质预览等)
*/
import { Scene, EntitySystem, Entity } from '@esengine/ecs-framework';
/**
* 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');