Files
esengine/packages/core/src/ECS/Serialization/EntitySerializer.ts

236 lines
6.3 KiB
TypeScript
Raw Normal View History

2025-10-08 18:34:15 +08:00
/**
*
*
*
*/
import { Entity } from '../Entity';
import { Component } from '../Component';
import { ComponentType } from '../Core/ComponentStorage';
import { ComponentSerializer, SerializedComponent } from './ComponentSerializer';
import { IScene } from '../IScene';
2025-10-08 18:34:15 +08:00
/**
*
*/
export interface SerializedEntity {
/**
* ID
*/
id: number;
/**
*
*/
name: string;
/**
*
*/
tag: number;
/**
*
*/
active: boolean;
/**
*
*/
enabled: boolean;
/**
*
*/
updateOrder: number;
/**
*
*/
components: SerializedComponent[];
/**
*
*/
children: SerializedEntity[];
/**
* ID
*/
parentId?: number;
}
/**
*
*/
export class EntitySerializer {
/**
*
*
* @param entity
* @param includeChildren true
* @returns
*/
public static serialize(entity: Entity, includeChildren: boolean = true): SerializedEntity {
const serializedComponents = ComponentSerializer.serializeComponents(
Array.from(entity.components)
);
const serializedEntity: SerializedEntity = {
id: entity.id,
name: entity.name,
tag: entity.tag,
active: entity.active,
enabled: entity.enabled,
updateOrder: entity.updateOrder,
components: serializedComponents,
children: []
};
// 序列化父实体引用
if (entity.parent) {
serializedEntity.parentId = entity.parent.id;
}
// 序列化子实体
if (includeChildren) {
for (const child of entity.children) {
serializedEntity.children.push(this.serialize(child, true));
}
}
return serializedEntity;
}
/**
*
*
* @param serializedEntity
* @param componentRegistry
* @param idGenerator ID生成器ID或保持原ID
* @param preserveIds IDfalse
* @param scene entity.scene以支持添加组件
2025-10-08 18:34:15 +08:00
* @returns
*/
public static deserialize(
serializedEntity: SerializedEntity,
componentRegistry: Map<string, ComponentType>,
idGenerator: () => number,
preserveIds: boolean = false,
scene?: IScene
2025-10-08 18:34:15 +08:00
): Entity {
// 创建实体使用原始ID或新生成的ID
const entityId = preserveIds ? serializedEntity.id : idGenerator();
const entity = new Entity(serializedEntity.name, entityId);
// 如果提供了scene先设置entity.scene以支持添加组件
if (scene) {
entity.scene = scene;
}
2025-10-08 18:34:15 +08:00
// 恢复实体属性
entity.tag = serializedEntity.tag;
entity.active = serializedEntity.active;
entity.enabled = serializedEntity.enabled;
entity.updateOrder = serializedEntity.updateOrder;
// 反序列化组件
const components = ComponentSerializer.deserializeComponents(
serializedEntity.components,
componentRegistry
);
for (const component of components) {
entity.addComponent(component);
}
// 反序列化子实体
for (const childData of serializedEntity.children) {
const childEntity = this.deserialize(
childData,
componentRegistry,
idGenerator,
preserveIds,
scene
2025-10-08 18:34:15 +08:00
);
entity.addChild(childEntity);
}
return entity;
}
/**
*
*
* @param entities
* @param includeChildren
* @returns
*/
public static serializeEntities(
entities: Entity[],
includeChildren: boolean = true
): SerializedEntity[] {
const result: SerializedEntity[] = [];
for (const entity of entities) {
// 只序列化顶层实体(没有父实体的实体)
// 子实体会在父实体序列化时一并处理
if (!entity.parent || !includeChildren) {
result.push(this.serialize(entity, includeChildren));
}
}
return result;
}
/**
*
*
* @param serializedEntities
* @param componentRegistry
* @param idGenerator ID生成器
* @param preserveIds ID
* @param scene entity.scene以支持添加组件
2025-10-08 18:34:15 +08:00
* @returns
*/
public static deserializeEntities(
serializedEntities: SerializedEntity[],
componentRegistry: Map<string, ComponentType>,
idGenerator: () => number,
preserveIds: boolean = false,
scene?: IScene
2025-10-08 18:34:15 +08:00
): Entity[] {
const result: Entity[] = [];
for (const serialized of serializedEntities) {
const entity = this.deserialize(
serialized,
componentRegistry,
idGenerator,
preserveIds,
scene
2025-10-08 18:34:15 +08:00
);
result.push(entity);
}
return result;
}
/**
*
*
* @param entity
* @param componentRegistry
* @param idGenerator ID生成器
* @returns
*/
public static clone(
entity: Entity,
componentRegistry: Map<string, ComponentType>,
idGenerator: () => number
): Entity {
const serialized = this.serialize(entity, true);
return this.deserialize(serialized, componentRegistry, idGenerator, false);
}
}