2025-06-09 14:51:26 +08:00
|
|
|
|
import { Entity } from './Entity';
|
|
|
|
|
|
import { EntityList } from './Utils/EntityList';
|
|
|
|
|
|
import { EntityProcessorList } from './Utils/EntityProcessorList';
|
|
|
|
|
|
import { IdentifierPool } from './Utils/IdentifierPool';
|
|
|
|
|
|
import { EntitySystem } from './Systems/EntitySystem';
|
|
|
|
|
|
import { ComponentStorageManager } from './Core/ComponentStorage';
|
|
|
|
|
|
import { QuerySystem } from './Core/QuerySystem';
|
2025-08-06 09:39:08 +08:00
|
|
|
|
import { TypeSafeEventSystem } from './Core/EventSystem';
|
2025-07-28 17:14:10 +08:00
|
|
|
|
import { EventBus } from './Core/EventBus';
|
2025-08-12 09:39:07 +08:00
|
|
|
|
import { IScene, ISceneConfig } from './IScene';
|
2025-08-14 18:35:03 +08:00
|
|
|
|
import { getComponentInstanceTypeName, getSystemInstanceTypeName } from './Decorators';
|
2025-10-08 13:13:23 +08:00
|
|
|
|
import { TypedQueryBuilder } from './Core/Query/TypedQuery';
|
2025-10-08 18:34:15 +08:00
|
|
|
|
import { SceneSerializer, SceneSerializationOptions, SceneDeserializationOptions } from './Serialization/SceneSerializer';
|
2025-06-09 14:51:26 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2025-08-12 09:39:07 +08:00
|
|
|
|
* 游戏场景默认实现类
|
2025-06-09 14:51:26 +08:00
|
|
|
|
*
|
2025-08-12 09:39:07 +08:00
|
|
|
|
* 实现IScene接口,提供场景的基础功能。
|
|
|
|
|
|
* 推荐使用组合而非继承的方式来构建自定义场景。
|
2025-06-09 14:51:26 +08:00
|
|
|
|
*/
|
2025-08-12 09:39:07 +08:00
|
|
|
|
export class Scene implements IScene {
|
2025-06-09 14:51:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 场景名称
|
2025-10-08 18:34:15 +08:00
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* 用于标识和调试的友好名称。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public name: string = "";
|
|
|
|
|
|
|
2025-10-08 18:34:15 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 场景自定义数据
|
|
|
|
|
|
*
|
|
|
|
|
|
* 用于存储场景级别的配置和状态数据。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly sceneData: Map<string, any> = new Map();
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 场景中的实体集合
|
2025-10-08 18:34:15 +08:00
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* 管理场景内所有实体的生命周期。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly entities: EntityList;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 实体系统处理器集合
|
|
|
|
|
|
*
|
|
|
|
|
|
* 管理场景内所有实体系统的执行。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly entityProcessors: EntityProcessorList;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 实体ID池
|
|
|
|
|
|
*
|
|
|
|
|
|
* 用于分配和回收实体的唯一标识符。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly identifierPool: IdentifierPool;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 组件存储管理器
|
|
|
|
|
|
*
|
|
|
|
|
|
* 高性能的组件存储和查询系统。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly componentStorageManager: ComponentStorageManager;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询系统
|
|
|
|
|
|
*
|
|
|
|
|
|
* 基于位掩码的高性能实体查询系统。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly querySystem: QuerySystem;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 事件系统
|
|
|
|
|
|
*
|
|
|
|
|
|
* 类型安全的事件系统。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly eventSystem: TypeSafeEventSystem;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 场景是否已开始运行
|
|
|
|
|
|
*/
|
|
|
|
|
|
private _didSceneBegin: boolean = false;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取系统列表(兼容性属性)
|
|
|
|
|
|
*/
|
|
|
|
|
|
public get systems(): EntitySystem[] {
|
|
|
|
|
|
return this.entityProcessors.processors;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-12 09:39:07 +08:00
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 创建场景实例
|
|
|
|
|
|
*/
|
2025-08-12 09:39:07 +08:00
|
|
|
|
constructor(config?: ISceneConfig) {
|
2025-06-09 14:51:26 +08:00
|
|
|
|
this.entities = new EntityList(this);
|
|
|
|
|
|
this.entityProcessors = new EntityProcessorList();
|
|
|
|
|
|
this.identifierPool = new IdentifierPool();
|
|
|
|
|
|
this.componentStorageManager = new ComponentStorageManager();
|
|
|
|
|
|
this.querySystem = new QuerySystem();
|
|
|
|
|
|
this.eventSystem = new TypeSafeEventSystem();
|
|
|
|
|
|
|
2025-08-12 09:39:07 +08:00
|
|
|
|
// 应用配置
|
|
|
|
|
|
if (config?.name) {
|
|
|
|
|
|
this.name = config.name;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-28 17:14:10 +08:00
|
|
|
|
if (!Entity.eventBus) {
|
|
|
|
|
|
Entity.eventBus = new EventBus(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Entity.eventBus) {
|
2025-08-12 09:39:07 +08:00
|
|
|
|
Entity.eventBus.onComponentAdded((data: unknown) => {
|
2025-07-28 17:14:10 +08:00
|
|
|
|
this.eventSystem.emitSync('component:added', data);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-06-09 14:51:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 初始化场景
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在场景创建时调用,子类可以重写此方法来设置初始实体和组件。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public initialize(): void {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 场景开始运行时的回调
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在场景开始运行时调用,可以在此方法中执行场景启动逻辑。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public onStart(): void {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 场景卸载时的回调
|
|
|
|
|
|
*
|
|
|
|
|
|
* 在场景被销毁时调用,可以在此方法中执行清理工作。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public unload(): void {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 开始场景,启动实体处理器等
|
|
|
|
|
|
*
|
|
|
|
|
|
* 这个方法会启动场景。它将启动实体处理器等,并调用onStart方法。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public begin() {
|
|
|
|
|
|
// 启动实体处理器
|
|
|
|
|
|
if (this.entityProcessors != null)
|
|
|
|
|
|
this.entityProcessors.begin();
|
|
|
|
|
|
|
|
|
|
|
|
// 标记场景已开始运行并调用onStart方法
|
|
|
|
|
|
this._didSceneBegin = true;
|
|
|
|
|
|
this.onStart();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 结束场景,清除实体、实体处理器等
|
|
|
|
|
|
*
|
|
|
|
|
|
* 这个方法会结束场景。它将移除所有实体,结束实体处理器等,并调用unload方法。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public end() {
|
|
|
|
|
|
// 标记场景已结束运行
|
|
|
|
|
|
this._didSceneBegin = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 移除所有实体
|
|
|
|
|
|
this.entities.removeAllEntities();
|
|
|
|
|
|
|
2025-08-06 09:39:08 +08:00
|
|
|
|
// 清理查询系统中的实体引用和缓存
|
|
|
|
|
|
this.querySystem.setEntities([]);
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
// 清空组件存储
|
|
|
|
|
|
this.componentStorageManager.clear();
|
|
|
|
|
|
|
|
|
|
|
|
// 结束实体处理器
|
|
|
|
|
|
if (this.entityProcessors)
|
|
|
|
|
|
this.entityProcessors.end();
|
|
|
|
|
|
|
|
|
|
|
|
// 调用卸载方法
|
|
|
|
|
|
this.unload();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-09-26 09:38:51 +08:00
|
|
|
|
* 更新场景
|
2025-06-09 14:51:26 +08:00
|
|
|
|
*/
|
|
|
|
|
|
public update() {
|
2025-09-30 22:26:44 +08:00
|
|
|
|
// 更新实体列表(处理延迟操作)
|
2025-06-09 14:51:26 +08:00
|
|
|
|
this.entities.updateLists();
|
|
|
|
|
|
|
|
|
|
|
|
// 更新实体处理器
|
|
|
|
|
|
if (this.entityProcessors != null)
|
|
|
|
|
|
this.entityProcessors.update();
|
|
|
|
|
|
|
2025-09-26 09:38:51 +08:00
|
|
|
|
// 更新实体处理器后处理
|
2025-06-09 14:51:26 +08:00
|
|
|
|
if (this.entityProcessors != null)
|
|
|
|
|
|
this.entityProcessors.lateUpdate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将实体添加到此场景,并返回它
|
|
|
|
|
|
* @param name 实体名称
|
|
|
|
|
|
*/
|
|
|
|
|
|
public createEntity(name: string) {
|
|
|
|
|
|
let entity = new Entity(name, this.identifierPool.checkOut());
|
2025-07-28 17:14:10 +08:00
|
|
|
|
|
|
|
|
|
|
this.eventSystem.emitSync('entity:created', { entityName: name, entity, scene: this });
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
return this.addEntity(entity);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-26 10:50:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 清除所有EntitySystem的实体缓存
|
|
|
|
|
|
* 当实体或组件发生变化时调用
|
|
|
|
|
|
*/
|
|
|
|
|
|
public clearSystemEntityCaches(): void {
|
|
|
|
|
|
for (const system of this.entityProcessors.processors) {
|
|
|
|
|
|
system.clearEntityCache();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 在场景的实体列表中添加一个实体
|
|
|
|
|
|
* @param entity 要添加的实体
|
|
|
|
|
|
* @param deferCacheClear 是否延迟缓存清理(用于批量操作)
|
|
|
|
|
|
*/
|
|
|
|
|
|
public addEntity(entity: Entity, deferCacheClear: boolean = false) {
|
|
|
|
|
|
this.entities.add(entity);
|
|
|
|
|
|
entity.scene = this;
|
2025-09-26 10:50:31 +08:00
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
// 将实体添加到查询系统(可延迟缓存清理)
|
|
|
|
|
|
this.querySystem.addEntity(entity, deferCacheClear);
|
2025-09-26 10:50:31 +08:00
|
|
|
|
|
|
|
|
|
|
// 清除系统缓存以确保系统能及时发现新实体
|
|
|
|
|
|
if (!deferCacheClear) {
|
|
|
|
|
|
this.clearSystemEntityCaches();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
// 触发实体添加事件
|
|
|
|
|
|
this.eventSystem.emitSync('entity:added', { entity, scene: this });
|
2025-09-26 10:50:31 +08:00
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
return entity;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 批量创建实体(高性能版本)
|
|
|
|
|
|
* @param count 要创建的实体数量
|
|
|
|
|
|
* @param namePrefix 实体名称前缀
|
|
|
|
|
|
* @returns 创建的实体列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
public createEntities(count: number, namePrefix: string = "Entity"): Entity[] {
|
|
|
|
|
|
const entities: Entity[] = [];
|
|
|
|
|
|
|
|
|
|
|
|
// 批量创建实体对象,不立即添加到系统
|
|
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
|
|
|
|
const entity = new Entity(`${namePrefix}_${i}`, this.identifierPool.checkOut());
|
|
|
|
|
|
entity.scene = this;
|
|
|
|
|
|
entities.push(entity);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 批量添加到实体列表
|
|
|
|
|
|
for (const entity of entities) {
|
|
|
|
|
|
this.entities.add(entity);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 批量添加到查询系统(无重复检查,性能最优)
|
|
|
|
|
|
this.querySystem.addEntitiesUnchecked(entities);
|
|
|
|
|
|
|
|
|
|
|
|
// 批量触发事件(可选,减少事件开销)
|
|
|
|
|
|
this.eventSystem.emitSync('entities:batch_added', { entities, scene: this, count });
|
|
|
|
|
|
|
|
|
|
|
|
return entities;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 从场景中删除所有实体
|
|
|
|
|
|
*/
|
|
|
|
|
|
public destroyAllEntities() {
|
2025-07-28 17:14:10 +08:00
|
|
|
|
this.entities.removeAllEntities();
|
2025-08-06 09:39:08 +08:00
|
|
|
|
|
|
|
|
|
|
// 清理查询系统中的实体引用和缓存
|
|
|
|
|
|
this.querySystem.setEntities([]);
|
2025-06-09 14:51:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 搜索并返回第一个具有名称的实体
|
|
|
|
|
|
* @param name 实体名称
|
|
|
|
|
|
*/
|
|
|
|
|
|
public findEntity(name: string): Entity | null {
|
|
|
|
|
|
return this.entities.findEntity(name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据ID查找实体
|
|
|
|
|
|
* @param id 实体ID
|
|
|
|
|
|
*/
|
|
|
|
|
|
public findEntityById(id: number): Entity | null {
|
|
|
|
|
|
return this.entities.findEntityById(id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据标签查找实体
|
|
|
|
|
|
* @param tag 实体标签
|
|
|
|
|
|
*/
|
|
|
|
|
|
public findEntitiesByTag(tag: number): Entity[] {
|
|
|
|
|
|
const result: Entity[] = [];
|
|
|
|
|
|
for (const entity of this.entities.buffer) {
|
|
|
|
|
|
if (entity.tag === tag) {
|
|
|
|
|
|
result.push(entity);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据名称查找实体(别名方法)
|
|
|
|
|
|
* @param name 实体名称
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getEntityByName(name: string): Entity | null {
|
|
|
|
|
|
return this.findEntity(name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据标签查找实体(别名方法)
|
|
|
|
|
|
* @param tag 实体标签
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getEntitiesByTag(tag: number): Entity[] {
|
|
|
|
|
|
return this.findEntitiesByTag(tag);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-08 13:13:23 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 查询拥有所有指定组件的实体
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param componentTypes - 组件类型数组
|
|
|
|
|
|
* @returns 查询结果
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* const result = scene.queryAll(Position, Velocity);
|
|
|
|
|
|
* for (const entity of result.entities) {
|
|
|
|
|
|
* const pos = entity.getComponent(Position);
|
|
|
|
|
|
* const vel = entity.getComponent(Velocity);
|
|
|
|
|
|
* }
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
public queryAll(...componentTypes: any[]): { entities: readonly Entity[] } {
|
|
|
|
|
|
return this.querySystem.queryAll(...componentTypes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询拥有任意一个指定组件的实体
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param componentTypes - 组件类型数组
|
|
|
|
|
|
* @returns 查询结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
public queryAny(...componentTypes: any[]): { entities: readonly Entity[] } {
|
|
|
|
|
|
return this.querySystem.queryAny(...componentTypes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 查询不包含指定组件的实体
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param componentTypes - 组件类型数组
|
|
|
|
|
|
* @returns 查询结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
public queryNone(...componentTypes: any[]): { entities: readonly Entity[] } {
|
|
|
|
|
|
return this.querySystem.queryNone(...componentTypes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 创建类型安全的查询构建器
|
|
|
|
|
|
*
|
|
|
|
|
|
* @returns 查询构建器,支持链式调用
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* // 使用查询构建器
|
|
|
|
|
|
* const matcher = scene.query()
|
|
|
|
|
|
* .withAll(Position, Velocity)
|
|
|
|
|
|
* .withNone(Disabled)
|
|
|
|
|
|
* .buildMatcher();
|
|
|
|
|
|
*
|
|
|
|
|
|
* // 在System中使用
|
|
|
|
|
|
* class MovementSystem extends EntitySystem {
|
|
|
|
|
|
* constructor() {
|
|
|
|
|
|
* super(matcher);
|
|
|
|
|
|
* }
|
|
|
|
|
|
* }
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
public query(): TypedQueryBuilder {
|
|
|
|
|
|
return new TypedQueryBuilder();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 在场景中添加一个EntitySystem处理器
|
|
|
|
|
|
* @param processor 处理器
|
|
|
|
|
|
*/
|
|
|
|
|
|
public addEntityProcessor(processor: EntitySystem) {
|
2025-07-28 17:14:10 +08:00
|
|
|
|
if (this.entityProcessors.processors.includes(processor)) {
|
|
|
|
|
|
return processor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
processor.scene = this;
|
|
|
|
|
|
this.entityProcessors.add(processor);
|
2025-07-30 15:42:19 +08:00
|
|
|
|
processor.initialize();
|
2025-06-09 14:51:26 +08:00
|
|
|
|
processor.setUpdateOrder(this.entityProcessors.count - 1);
|
|
|
|
|
|
return processor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 添加系统到场景(addEntityProcessor的别名)
|
|
|
|
|
|
* @param system 系统
|
|
|
|
|
|
*/
|
|
|
|
|
|
public addSystem(system: EntitySystem) {
|
|
|
|
|
|
return this.addEntityProcessor(system);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 从场景中删除EntitySystem处理器
|
|
|
|
|
|
* @param processor 要删除的处理器
|
|
|
|
|
|
*/
|
|
|
|
|
|
public removeEntityProcessor(processor: EntitySystem) {
|
|
|
|
|
|
this.entityProcessors.remove(processor);
|
2025-07-30 15:42:19 +08:00
|
|
|
|
processor.reset();
|
2025-09-24 18:14:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 从场景中删除系统(removeEntityProcessor的别名)
|
|
|
|
|
|
* @param system 系统
|
|
|
|
|
|
*/
|
|
|
|
|
|
public removeSystem(system: EntitySystem) {
|
|
|
|
|
|
this.removeEntityProcessor(system);
|
2025-06-09 14:51:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取指定类型的EntitySystem处理器
|
|
|
|
|
|
* @param type 处理器类型
|
|
|
|
|
|
*/
|
2025-07-31 11:56:04 +08:00
|
|
|
|
public getEntityProcessor<T extends EntitySystem>(type: new (...args: unknown[]) => T): T | null {
|
2025-06-09 14:51:26 +08:00
|
|
|
|
return this.entityProcessors.getProcessor(type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取场景统计信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getStats(): {
|
|
|
|
|
|
entityCount: number;
|
|
|
|
|
|
processorCount: number;
|
|
|
|
|
|
componentStorageStats: Map<string, any>;
|
|
|
|
|
|
} {
|
|
|
|
|
|
return {
|
|
|
|
|
|
entityCount: this.entities.count,
|
|
|
|
|
|
processorCount: this.entityProcessors.count,
|
|
|
|
|
|
componentStorageStats: this.componentStorageManager.getAllStats()
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取场景的调试信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
public getDebugInfo(): {
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
entityCount: number;
|
|
|
|
|
|
processorCount: number;
|
|
|
|
|
|
isRunning: boolean;
|
|
|
|
|
|
entities: Array<{
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
id: number;
|
|
|
|
|
|
componentCount: number;
|
|
|
|
|
|
componentTypes: string[];
|
|
|
|
|
|
}>;
|
|
|
|
|
|
processors: Array<{
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
updateOrder: number;
|
|
|
|
|
|
entityCount: number;
|
|
|
|
|
|
}>;
|
|
|
|
|
|
componentStats: Map<string, any>;
|
|
|
|
|
|
} {
|
|
|
|
|
|
return {
|
2025-08-14 18:35:03 +08:00
|
|
|
|
name: this.name || this.constructor.name,
|
2025-06-09 14:51:26 +08:00
|
|
|
|
entityCount: this.entities.count,
|
|
|
|
|
|
processorCount: this.entityProcessors.count,
|
|
|
|
|
|
isRunning: this._didSceneBegin,
|
|
|
|
|
|
entities: this.entities.buffer.map(entity => ({
|
|
|
|
|
|
name: entity.name,
|
|
|
|
|
|
id: entity.id,
|
|
|
|
|
|
componentCount: entity.components.length,
|
2025-08-14 18:35:03 +08:00
|
|
|
|
componentTypes: entity.components.map(c => getComponentInstanceTypeName(c))
|
2025-06-09 14:51:26 +08:00
|
|
|
|
})),
|
|
|
|
|
|
processors: this.entityProcessors.processors.map(processor => ({
|
2025-08-14 18:35:03 +08:00
|
|
|
|
name: getSystemInstanceTypeName(processor),
|
2025-06-09 14:51:26 +08:00
|
|
|
|
updateOrder: processor.updateOrder,
|
|
|
|
|
|
entityCount: (processor as any)._entities?.length || 0
|
|
|
|
|
|
})),
|
|
|
|
|
|
componentStats: this.componentStorageManager.getAllStats()
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2025-10-08 18:34:15 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 序列化场景
|
|
|
|
|
|
*
|
2025-10-08 20:42:55 +08:00
|
|
|
|
* 将场景及其所有实体、组件序列化为JSON字符串或二进制Buffer
|
2025-10-08 18:34:15 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @param options 序列化选项
|
2025-10-08 20:42:55 +08:00
|
|
|
|
* @returns 序列化后的数据(JSON字符串或二进制Buffer)
|
2025-10-08 18:34:15 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
2025-10-08 20:42:55 +08:00
|
|
|
|
* // JSON格式
|
|
|
|
|
|
* const jsonData = scene.serialize({
|
2025-10-08 18:34:15 +08:00
|
|
|
|
* format: 'json',
|
|
|
|
|
|
* pretty: true
|
|
|
|
|
|
* });
|
2025-10-08 20:42:55 +08:00
|
|
|
|
*
|
|
|
|
|
|
* // 二进制格式(更小、更快)
|
|
|
|
|
|
* const binaryData = scene.serialize({
|
|
|
|
|
|
* format: 'binary'
|
|
|
|
|
|
* });
|
2025-10-08 18:34:15 +08:00
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
2025-10-08 20:42:55 +08:00
|
|
|
|
public serialize(options?: SceneSerializationOptions): string | Buffer {
|
2025-10-08 18:34:15 +08:00
|
|
|
|
return SceneSerializer.serialize(this, options);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 反序列化场景
|
|
|
|
|
|
*
|
|
|
|
|
|
* 从序列化数据恢复场景状态
|
|
|
|
|
|
*
|
2025-10-08 20:42:55 +08:00
|
|
|
|
* @param saveData 序列化的数据(JSON字符串或二进制Buffer)
|
2025-10-08 18:34:15 +08:00
|
|
|
|
* @param options 反序列化选项
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* ```typescript
|
2025-10-08 20:42:55 +08:00
|
|
|
|
* // 从JSON恢复(自动从ComponentRegistry获取组件类型)
|
|
|
|
|
|
* scene.deserialize(jsonData, {
|
|
|
|
|
|
* strategy: 'replace'
|
|
|
|
|
|
* });
|
|
|
|
|
|
*
|
|
|
|
|
|
* // 从二进制恢复
|
|
|
|
|
|
* scene.deserialize(binaryData, {
|
|
|
|
|
|
* strategy: 'replace'
|
2025-10-08 18:34:15 +08:00
|
|
|
|
* });
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
2025-10-08 20:42:55 +08:00
|
|
|
|
public deserialize(saveData: string | Buffer, options?: SceneDeserializationOptions): void {
|
2025-10-08 18:34:15 +08:00
|
|
|
|
SceneSerializer.deserialize(this, saveData, options);
|
|
|
|
|
|
}
|
2020-06-08 11:49:45 +08:00
|
|
|
|
}
|