refactor(core): 优化 PlatformWorkerPool 和 IncrementalSerializer 代码规范 (#335)
PlatformWorkerPool: - 添加 IWorkerPoolStatus 导出接口 - 添加便捷 getter: isDestroyed, workerCount, isReady, hasPendingTasks - 提取 createTask/completeTask 方法减少重复代码 - 添加 ERROR_POOL_DESTROYED 常量 - 添加代码段分隔符和双语注释 IncrementalSerializer: - 所有公共 API 添加 @zh/@en 双语注释 - 类型改用 interface 并添加 readonly - SceneDataChange.value 从 any 改为 unknown - 导出 SceneSnapshot, IIncrementalStats 接口 - 提取 DEFAULT_OPTIONS 常量 - 优化 getIncrementalStats 从 6 次 filter 改为 2 次循环
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* 增量序列化器
|
* @zh 增量序列化器
|
||||||
|
* @en Incremental Serializer
|
||||||
*
|
*
|
||||||
* 提供高性能的增量序列化支持,只序列化变更的数据
|
* @zh 提供高性能的增量序列化支持,只序列化变更的数据。
|
||||||
* 适用于网络同步、大场景存档、时间回溯等场景
|
* 适用于网络同步、大场景存档、时间回溯等场景。
|
||||||
|
* @en Provides high-performance incremental serialization, serializing only changed data.
|
||||||
|
* Suitable for network sync, large scene archiving, and time rewind scenarios.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { IScene } from '../IScene';
|
import type { IScene } from '../IScene';
|
||||||
@@ -14,177 +17,263 @@ import { BinarySerializer } from '../../Utils/BinarySerializer';
|
|||||||
import { HierarchyComponent } from '../Components/HierarchyComponent';
|
import { HierarchyComponent } from '../Components/HierarchyComponent';
|
||||||
import { HierarchySystem } from '../Systems/HierarchySystem';
|
import { HierarchySystem } from '../Systems/HierarchySystem';
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// 枚举 | Enums
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 变更操作类型
|
* @zh 变更操作类型
|
||||||
|
* @en Change operation type
|
||||||
*/
|
*/
|
||||||
export enum ChangeOperation {
|
export enum ChangeOperation {
|
||||||
/** 添加新实体 */
|
/** @zh 添加新实体 @en Entity added */
|
||||||
EntityAdded = 'entity_added',
|
EntityAdded = 'entity_added',
|
||||||
/** 删除实体 */
|
/** @zh 删除实体 @en Entity removed */
|
||||||
EntityRemoved = 'entity_removed',
|
EntityRemoved = 'entity_removed',
|
||||||
/** 实体属性更新 */
|
/** @zh 实体属性更新 @en Entity updated */
|
||||||
EntityUpdated = 'entity_updated',
|
EntityUpdated = 'entity_updated',
|
||||||
/** 添加组件 */
|
/** @zh 添加组件 @en Component added */
|
||||||
ComponentAdded = 'component_added',
|
ComponentAdded = 'component_added',
|
||||||
/** 删除组件 */
|
/** @zh 删除组件 @en Component removed */
|
||||||
ComponentRemoved = 'component_removed',
|
ComponentRemoved = 'component_removed',
|
||||||
/** 组件数据更新 */
|
/** @zh 组件数据更新 @en Component updated */
|
||||||
ComponentUpdated = 'component_updated',
|
ComponentUpdated = 'component_updated',
|
||||||
/** 场景数据更新 */
|
/** @zh 场景数据更新 @en Scene data updated */
|
||||||
SceneDataUpdated = 'scene_data_updated'
|
SceneDataUpdated = 'scene_data_updated'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// 类型定义 | Type Definitions
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实体变更记录
|
* @zh 实体变更记录
|
||||||
|
* @en Entity change record
|
||||||
*/
|
*/
|
||||||
export type EntityChange = {
|
export interface EntityChange {
|
||||||
/** 操作类型 */
|
/** @zh 操作类型 @en Operation type */
|
||||||
operation: ChangeOperation;
|
readonly operation: ChangeOperation;
|
||||||
/** 实体ID */
|
/** @zh 实体ID @en Entity ID */
|
||||||
entityId: number;
|
readonly entityId: number;
|
||||||
/** 实体名称(用于Added操作) */
|
/** @zh 实体名称(用于Added操作)@en Entity name (for Added operation) */
|
||||||
entityName?: string;
|
readonly entityName?: string;
|
||||||
/** 实体数据(用于Added/Updated操作) */
|
/** @zh 实体数据(用于Added/Updated操作)@en Entity data (for Added/Updated operation) */
|
||||||
entityData?: Partial<SerializedEntity>;
|
readonly entityData?: Partial<SerializedEntity>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组件变更记录
|
* @zh 组件变更记录
|
||||||
|
* @en Component change record
|
||||||
*/
|
*/
|
||||||
export type ComponentChange = {
|
export interface ComponentChange {
|
||||||
/** 操作类型 */
|
/** @zh 操作类型 @en Operation type */
|
||||||
operation: ChangeOperation;
|
readonly operation: ChangeOperation;
|
||||||
/** 实体ID */
|
/** @zh 实体ID @en Entity ID */
|
||||||
entityId: number;
|
readonly entityId: number;
|
||||||
/** 组件类型名称 */
|
/** @zh 组件类型名称 @en Component type name */
|
||||||
componentType: string;
|
readonly componentType: string;
|
||||||
/** 组件数据(用于Added/Updated操作) */
|
/** @zh 组件数据(用于Added/Updated操作)@en Component data (for Added/Updated operation) */
|
||||||
componentData?: SerializedComponent;
|
readonly componentData?: SerializedComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景数据变更记录
|
* @zh 场景数据变更记录
|
||||||
|
* @en Scene data change record
|
||||||
*/
|
*/
|
||||||
export type SceneDataChange = {
|
export interface SceneDataChange {
|
||||||
/** 操作类型 */
|
/** @zh 操作类型 @en Operation type */
|
||||||
operation: ChangeOperation;
|
readonly operation: ChangeOperation;
|
||||||
/** 变更的键 */
|
/** @zh 变更的键 @en Changed key */
|
||||||
key: string;
|
readonly key: string;
|
||||||
/** 新值 */
|
/** @zh 新值 @en New value */
|
||||||
value: any;
|
readonly value: unknown;
|
||||||
/** 是否删除 */
|
/** @zh 是否删除 @en Whether deleted */
|
||||||
deleted?: boolean;
|
readonly deleted?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增量序列化数据
|
* @zh 增量序列化数据
|
||||||
|
* @en Incremental snapshot data
|
||||||
*/
|
*/
|
||||||
export type IncrementalSnapshot = {
|
export interface IncrementalSnapshot {
|
||||||
/** 快照版本号 */
|
/** @zh 快照版本号 @en Snapshot version */
|
||||||
version: number;
|
readonly version: number;
|
||||||
/** 时间戳 */
|
/** @zh 时间戳 @en Timestamp */
|
||||||
timestamp: number;
|
readonly timestamp: number;
|
||||||
/** 场景名称 */
|
/** @zh 场景名称 @en Scene name */
|
||||||
sceneName: string;
|
readonly sceneName: string;
|
||||||
/** 基础版本号(相对于哪个快照的增量) */
|
/** @zh 基础版本号(相对于哪个快照的增量)@en Base version (incremental from which snapshot) */
|
||||||
baseVersion: number;
|
readonly baseVersion: number;
|
||||||
/** 实体变更列表 */
|
/** @zh 实体变更列表 @en Entity changes list */
|
||||||
entityChanges: EntityChange[];
|
readonly entityChanges: EntityChange[];
|
||||||
/** 组件变更列表 */
|
/** @zh 组件变更列表 @en Component changes list */
|
||||||
componentChanges: ComponentChange[];
|
readonly componentChanges: ComponentChange[];
|
||||||
/** 场景数据变更列表 */
|
/** @zh 场景数据变更列表 @en Scene data changes list */
|
||||||
sceneDataChanges: SceneDataChange[];
|
readonly sceneDataChanges: SceneDataChange[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 场景快照(用于对比)
|
* @zh 实体快照数据
|
||||||
|
* @en Entity snapshot data
|
||||||
*/
|
*/
|
||||||
interface SceneSnapshot {
|
interface EntitySnapshotData {
|
||||||
/** 快照版本号 */
|
readonly name: string;
|
||||||
version: number;
|
readonly tag: number;
|
||||||
/** 实体ID集合 */
|
readonly active: boolean;
|
||||||
entityIds: Set<number>;
|
readonly enabled: boolean;
|
||||||
/** 实体数据映射 */
|
readonly updateOrder: number;
|
||||||
entities: Map<number, {
|
readonly parentId?: number;
|
||||||
name: string;
|
|
||||||
tag: number;
|
|
||||||
active: boolean;
|
|
||||||
enabled: boolean;
|
|
||||||
updateOrder: number;
|
|
||||||
parentId?: number;
|
|
||||||
}>;
|
|
||||||
/** 组件数据映射 (entityId -> componentType -> serializedData) */
|
|
||||||
components: Map<number, Map<string, string>>; // 使用JSON字符串存储组件数据
|
|
||||||
/** 场景自定义数据 */
|
|
||||||
sceneData: Map<string, string>; // 使用JSON字符串存储场景数据
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增量序列化格式
|
* @zh 场景快照(用于对比)
|
||||||
|
* @en Scene snapshot (for comparison)
|
||||||
|
*/
|
||||||
|
export interface SceneSnapshot {
|
||||||
|
/** @zh 快照版本号 @en Snapshot version */
|
||||||
|
readonly version: number;
|
||||||
|
/** @zh 实体ID集合 @en Entity ID set */
|
||||||
|
readonly entityIds: Set<number>;
|
||||||
|
/** @zh 实体数据映射 @en Entity data map */
|
||||||
|
readonly entities: Map<number, EntitySnapshotData>;
|
||||||
|
/** @zh 组件数据映射 (entityId -> componentType -> serializedData JSON) @en Component data map */
|
||||||
|
readonly components: Map<number, Map<string, string>>;
|
||||||
|
/** @zh 场景自定义数据 @en Scene custom data */
|
||||||
|
readonly sceneData: Map<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 增量序列化格式
|
||||||
|
* @en Incremental serialization format
|
||||||
*/
|
*/
|
||||||
export type IncrementalSerializationFormat = 'json' | 'binary';
|
export type IncrementalSerializationFormat = 'json' | 'binary';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增量序列化选项
|
* @zh 增量快照统计信息
|
||||||
|
* @en Incremental snapshot statistics
|
||||||
*/
|
*/
|
||||||
export type IncrementalSerializationOptions = {
|
export interface IIncrementalStats {
|
||||||
|
/** @zh 总变更数 @en Total changes */
|
||||||
|
readonly totalChanges: number;
|
||||||
|
/** @zh 实体变更数 @en Entity changes count */
|
||||||
|
readonly entityChanges: number;
|
||||||
|
/** @zh 组件变更数 @en Component changes count */
|
||||||
|
readonly componentChanges: number;
|
||||||
|
/** @zh 场景数据变更数 @en Scene data changes count */
|
||||||
|
readonly sceneDataChanges: number;
|
||||||
|
/** @zh 新增实体数 @en Added entities count */
|
||||||
|
readonly addedEntities: number;
|
||||||
|
/** @zh 删除实体数 @en Removed entities count */
|
||||||
|
readonly removedEntities: number;
|
||||||
|
/** @zh 更新实体数 @en Updated entities count */
|
||||||
|
readonly updatedEntities: number;
|
||||||
|
/** @zh 新增组件数 @en Added components count */
|
||||||
|
readonly addedComponents: number;
|
||||||
|
/** @zh 删除组件数 @en Removed components count */
|
||||||
|
readonly removedComponents: number;
|
||||||
|
/** @zh 更新组件数 @en Updated components count */
|
||||||
|
readonly updatedComponents: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否包含组件数据的深度对比
|
* @zh 增量序列化选项
|
||||||
* 默认true,设为false可提升性能但可能漏掉组件内部字段变更
|
* @en Incremental serialization options
|
||||||
|
*/
|
||||||
|
export interface IncrementalSerializationOptions {
|
||||||
|
/**
|
||||||
|
* @zh 实体过滤器 - 只快照符合条件的实体
|
||||||
|
* @en Entity filter - only snapshot entities that match the condition
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* // 只快照玩家实体
|
||||||
|
* const snapshot = IncrementalSerializer.createSnapshot(scene, {
|
||||||
|
* entityFilter: (entity) => entity.tag === PLAYER_TAG
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // 只快照有特定组件的实体
|
||||||
|
* const snapshot = IncrementalSerializer.createSnapshot(scene, {
|
||||||
|
* entityFilter: (entity) => entity.hasComponent(PlayerMarker)
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
entityFilter?: (entity: Entity) => boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 是否包含组件数据的深度对比,默认true
|
||||||
|
* @en Whether to deep compare component data, default true
|
||||||
*/
|
*/
|
||||||
deepComponentComparison?: boolean;
|
deepComponentComparison?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否跟踪场景数据变更
|
* @zh 是否跟踪场景数据变更,默认true
|
||||||
* 默认true
|
* @en Whether to track scene data changes, default true
|
||||||
*/
|
*/
|
||||||
trackSceneData?: boolean;
|
trackSceneData?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否压缩快照(使用JSON序列化)
|
* @zh 是否压缩快照,默认false
|
||||||
* 默认false,设为true可减少内存占用但增加CPU开销
|
* @en Whether to compress snapshot, default false
|
||||||
*/
|
*/
|
||||||
compressSnapshot?: boolean;
|
compressSnapshot?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化格式
|
* @zh 序列化格式,默认 'json'
|
||||||
* - 'json': JSON格式
|
* @en Serialization format, default 'json'
|
||||||
* - 'binary': 二进制格式
|
|
||||||
* 默认 'json'
|
|
||||||
*/
|
*/
|
||||||
format?: IncrementalSerializationFormat;
|
format?: IncrementalSerializationFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否美化JSON输出(仅在format='json'时有效)
|
* @zh 是否美化JSON输出(仅在format='json'时有效),默认false
|
||||||
* 默认false
|
* @en Whether to prettify JSON output (only for format='json'), default false
|
||||||
*/
|
*/
|
||||||
pretty?: boolean;
|
pretty?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// =============================================================================
|
||||||
* 增量序列化器类
|
// 常量 | Constants
|
||||||
*/
|
// =============================================================================
|
||||||
export class IncrementalSerializer {
|
|
||||||
/** 当前快照版本号 */
|
const DEFAULT_OPTIONS: Required<Omit<IncrementalSerializationOptions, 'entityFilter'>> = {
|
||||||
private static snapshotVersion = 0;
|
deepComponentComparison: true,
|
||||||
|
trackSceneData: true,
|
||||||
|
compressSnapshot: false,
|
||||||
|
format: 'json',
|
||||||
|
pretty: false
|
||||||
|
};
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// IncrementalSerializer
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建场景快照
|
* @zh 增量序列化器类
|
||||||
|
* @en Incremental serializer class
|
||||||
*
|
*
|
||||||
* @param scene 要快照的场景
|
* @zh 提供场景快照创建、增量计算、应用和序列化功能
|
||||||
* @param options 序列化选项
|
* @en Provides scene snapshot creation, incremental computation, application and serialization
|
||||||
* @returns 场景快照对象
|
*/
|
||||||
|
export class IncrementalSerializer {
|
||||||
|
/** @zh 当前快照版本号 @en Current snapshot version */
|
||||||
|
private static snapshotVersion = 0;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 快照创建 | Snapshot Creation
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 创建场景快照
|
||||||
|
* @en Create scene snapshot
|
||||||
|
*
|
||||||
|
* @param scene - @zh 要快照的场景 @en Scene to snapshot
|
||||||
|
* @param options - @zh 序列化选项 @en Serialization options
|
||||||
|
* @returns @zh 场景快照对象 @en Scene snapshot object
|
||||||
*/
|
*/
|
||||||
public static createSnapshot(
|
public static createSnapshot(
|
||||||
scene: IScene,
|
scene: IScene,
|
||||||
options?: IncrementalSerializationOptions
|
options?: IncrementalSerializationOptions
|
||||||
): SceneSnapshot {
|
): SceneSnapshot {
|
||||||
const opts = {
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
||||||
deepComponentComparison: true,
|
|
||||||
trackSceneData: true,
|
|
||||||
compressSnapshot: false,
|
|
||||||
...options
|
|
||||||
};
|
|
||||||
|
|
||||||
const snapshot: SceneSnapshot = {
|
const snapshot: SceneSnapshot = {
|
||||||
version: ++this.snapshotVersion,
|
version: ++this.snapshotVersion,
|
||||||
@@ -194,8 +283,13 @@ export class IncrementalSerializer {
|
|||||||
sceneData: new Map()
|
sceneData: new Map()
|
||||||
};
|
};
|
||||||
|
|
||||||
// 快照所有实体
|
// 快照实体(支持过滤)
|
||||||
for (const entity of scene.entities.buffer) {
|
for (const entity of scene.entities.buffer) {
|
||||||
|
// 应用实体过滤器
|
||||||
|
if (opts.entityFilter && !opts.entityFilter(entity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
snapshot.entityIds.add(entity.id);
|
snapshot.entityIds.add(entity.id);
|
||||||
|
|
||||||
// 获取层级信息
|
// 获取层级信息
|
||||||
@@ -243,24 +337,25 @@ export class IncrementalSerializer {
|
|||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 增量计算 | Incremental Computation
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算增量变更
|
* @zh 计算增量变更
|
||||||
|
* @en Compute incremental changes
|
||||||
*
|
*
|
||||||
* @param scene 当前场景
|
* @param scene - @zh 当前场景 @en Current scene
|
||||||
* @param baseSnapshot 基础快照
|
* @param baseSnapshot - @zh 基础快照 @en Base snapshot
|
||||||
* @param options 序列化选项
|
* @param options - @zh 序列化选项 @en Serialization options
|
||||||
* @returns 增量快照
|
* @returns @zh 增量快照 @en Incremental snapshot
|
||||||
*/
|
*/
|
||||||
public static computeIncremental(
|
public static computeIncremental(
|
||||||
scene: IScene,
|
scene: IScene,
|
||||||
baseSnapshot: SceneSnapshot,
|
baseSnapshot: SceneSnapshot,
|
||||||
options?: IncrementalSerializationOptions
|
options?: IncrementalSerializationOptions
|
||||||
): IncrementalSnapshot {
|
): IncrementalSnapshot {
|
||||||
const opts = {
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
||||||
deepComponentComparison: true,
|
|
||||||
trackSceneData: true,
|
|
||||||
...options
|
|
||||||
};
|
|
||||||
|
|
||||||
const incremental: IncrementalSnapshot = {
|
const incremental: IncrementalSnapshot = {
|
||||||
version: ++this.snapshotVersion,
|
version: ++this.snapshotVersion,
|
||||||
@@ -274,8 +369,13 @@ export class IncrementalSerializer {
|
|||||||
|
|
||||||
const currentEntityIds = new Set<number>();
|
const currentEntityIds = new Set<number>();
|
||||||
|
|
||||||
// 检测实体变更
|
// 检测实体变更(支持过滤)
|
||||||
for (const entity of scene.entities.buffer) {
|
for (const entity of scene.entities.buffer) {
|
||||||
|
// 应用实体过滤器
|
||||||
|
if (opts.entityFilter && !opts.entityFilter(entity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
currentEntityIds.add(entity.id);
|
currentEntityIds.add(entity.id);
|
||||||
|
|
||||||
// 获取层级信息
|
// 获取层级信息
|
||||||
@@ -372,8 +472,13 @@ export class IncrementalSerializer {
|
|||||||
return incremental;
|
return incremental;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 私有方法 - 变更检测 | Private Methods - Change Detection
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测组件变更
|
* @zh 检测组件变更
|
||||||
|
* @en Detect component changes
|
||||||
*/
|
*/
|
||||||
private static detectComponentChanges(
|
private static detectComponentChanges(
|
||||||
entity: Entity,
|
entity: Entity,
|
||||||
@@ -429,7 +534,8 @@ export class IncrementalSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测场景数据变更
|
* @zh 检测场景数据变更
|
||||||
|
* @en Detect scene data changes
|
||||||
*/
|
*/
|
||||||
private static detectSceneDataChanges(
|
private static detectSceneDataChanges(
|
||||||
scene: IScene,
|
scene: IScene,
|
||||||
@@ -466,12 +572,17 @@ export class IncrementalSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 增量应用 | Incremental Application
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用增量变更到场景
|
* @zh 应用增量变更到场景
|
||||||
|
* @en Apply incremental changes to scene
|
||||||
*
|
*
|
||||||
* @param scene 目标场景
|
* @param scene - @zh 目标场景 @en Target scene
|
||||||
* @param incremental 增量快照
|
* @param incremental - @zh 增量快照 @en Incremental snapshot
|
||||||
* @param componentRegistry 组件类型注册表
|
* @param componentRegistry - @zh 组件类型注册表 @en Component type registry
|
||||||
*/
|
*/
|
||||||
public static applyIncremental(
|
public static applyIncremental(
|
||||||
scene: IScene,
|
scene: IScene,
|
||||||
@@ -617,12 +728,17 @@ export class IncrementalSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 序列化与反序列化 | Serialization & Deserialization
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化增量快照
|
* @zh 序列化增量快照
|
||||||
|
* @en Serialize incremental snapshot
|
||||||
*
|
*
|
||||||
* @param incremental 增量快照
|
* @param incremental - @zh 增量快照 @en Incremental snapshot
|
||||||
* @param options 序列化选项
|
* @param options - @zh 序列化选项 @en Serialization options
|
||||||
* @returns 序列化后的数据(JSON字符串或二进制Uint8Array)
|
* @returns @zh 序列化后的数据 @en Serialized data
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
@@ -633,74 +749,62 @@ export class IncrementalSerializer {
|
|||||||
* const binaryData = IncrementalSerializer.serializeIncremental(snapshot, {
|
* const binaryData = IncrementalSerializer.serializeIncremental(snapshot, {
|
||||||
* format: 'binary'
|
* format: 'binary'
|
||||||
* });
|
* });
|
||||||
*
|
|
||||||
* // 美化JSON
|
|
||||||
* const prettyJson = IncrementalSerializer.serializeIncremental(snapshot, {
|
|
||||||
* format: 'json',
|
|
||||||
* pretty: true
|
|
||||||
* });
|
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public static serializeIncremental(
|
public static serializeIncremental(
|
||||||
incremental: IncrementalSnapshot,
|
incremental: IncrementalSnapshot,
|
||||||
options?: { format?: IncrementalSerializationFormat; pretty?: boolean }
|
options?: { format?: IncrementalSerializationFormat; pretty?: boolean }
|
||||||
): string | Uint8Array {
|
): string | Uint8Array {
|
||||||
const opts = {
|
const format = options?.format ?? 'json';
|
||||||
format: 'json' as IncrementalSerializationFormat,
|
const pretty = options?.pretty ?? false;
|
||||||
pretty: false,
|
|
||||||
...options
|
|
||||||
};
|
|
||||||
|
|
||||||
if (opts.format === 'binary') {
|
if (format === 'binary') {
|
||||||
return BinarySerializer.encode(incremental);
|
return BinarySerializer.encode(incremental);
|
||||||
} else {
|
|
||||||
return opts.pretty
|
|
||||||
? JSON.stringify(incremental, null, 2)
|
|
||||||
: JSON.stringify(incremental);
|
|
||||||
}
|
}
|
||||||
|
return pretty ? JSON.stringify(incremental, null, 2) : JSON.stringify(incremental);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反序列化增量快照
|
* @zh 反序列化增量快照
|
||||||
|
* @en Deserialize incremental snapshot
|
||||||
*
|
*
|
||||||
* @param data 序列化的数据(JSON字符串或二进制Uint8Array)
|
* @param data - @zh 序列化的数据 @en Serialized data
|
||||||
* @returns 增量快照
|
* @returns @zh 增量快照 @en Incremental snapshot
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```typescript
|
|
||||||
* // 从JSON反序列化
|
|
||||||
* const snapshot = IncrementalSerializer.deserializeIncremental(jsonString);
|
|
||||||
*
|
|
||||||
* // 从二进制反序列化
|
|
||||||
* const snapshot = IncrementalSerializer.deserializeIncremental(buffer);
|
|
||||||
* ```
|
|
||||||
*/
|
*/
|
||||||
public static deserializeIncremental(data: string | Uint8Array): IncrementalSnapshot {
|
public static deserializeIncremental(data: string | Uint8Array): IncrementalSnapshot {
|
||||||
if (typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
return JSON.parse(data);
|
return JSON.parse(data);
|
||||||
} else {
|
}
|
||||||
return BinarySerializer.decode(data) as IncrementalSnapshot;
|
return BinarySerializer.decode(data) as IncrementalSnapshot;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// =========================================================================
|
||||||
|
// 统计与工具 | Statistics & Utilities
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取增量快照的统计信息
|
* @zh 获取增量快照的统计信息
|
||||||
|
* @en Get incremental snapshot statistics
|
||||||
*
|
*
|
||||||
* @param incremental 增量快照
|
* @param incremental - @zh 增量快照 @en Incremental snapshot
|
||||||
* @returns 统计信息
|
* @returns @zh 统计信息 @en Statistics
|
||||||
*/
|
*/
|
||||||
public static getIncrementalStats(incremental: IncrementalSnapshot): {
|
public static getIncrementalStats(incremental: IncrementalSnapshot): IIncrementalStats {
|
||||||
totalChanges: number;
|
const entityStats = { added: 0, removed: 0, updated: 0 };
|
||||||
entityChanges: number;
|
const componentStats = { added: 0, removed: 0, updated: 0 };
|
||||||
componentChanges: number;
|
|
||||||
sceneDataChanges: number;
|
for (const change of incremental.entityChanges) {
|
||||||
addedEntities: number;
|
if (change.operation === ChangeOperation.EntityAdded) entityStats.added++;
|
||||||
removedEntities: number;
|
else if (change.operation === ChangeOperation.EntityRemoved) entityStats.removed++;
|
||||||
updatedEntities: number;
|
else if (change.operation === ChangeOperation.EntityUpdated) entityStats.updated++;
|
||||||
addedComponents: number;
|
}
|
||||||
removedComponents: number;
|
|
||||||
updatedComponents: number;
|
for (const change of incremental.componentChanges) {
|
||||||
} {
|
if (change.operation === ChangeOperation.ComponentAdded) componentStats.added++;
|
||||||
|
else if (change.operation === ChangeOperation.ComponentRemoved) componentStats.removed++;
|
||||||
|
else if (change.operation === ChangeOperation.ComponentUpdated) componentStats.updated++;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalChanges:
|
totalChanges:
|
||||||
incremental.entityChanges.length +
|
incremental.entityChanges.length +
|
||||||
@@ -709,29 +813,18 @@ export class IncrementalSerializer {
|
|||||||
entityChanges: incremental.entityChanges.length,
|
entityChanges: incremental.entityChanges.length,
|
||||||
componentChanges: incremental.componentChanges.length,
|
componentChanges: incremental.componentChanges.length,
|
||||||
sceneDataChanges: incremental.sceneDataChanges.length,
|
sceneDataChanges: incremental.sceneDataChanges.length,
|
||||||
addedEntities: incremental.entityChanges.filter(
|
addedEntities: entityStats.added,
|
||||||
(c) => c.operation === ChangeOperation.EntityAdded
|
removedEntities: entityStats.removed,
|
||||||
).length,
|
updatedEntities: entityStats.updated,
|
||||||
removedEntities: incremental.entityChanges.filter(
|
addedComponents: componentStats.added,
|
||||||
(c) => c.operation === ChangeOperation.EntityRemoved
|
removedComponents: componentStats.removed,
|
||||||
).length,
|
updatedComponents: componentStats.updated
|
||||||
updatedEntities: incremental.entityChanges.filter(
|
|
||||||
(c) => c.operation === ChangeOperation.EntityUpdated
|
|
||||||
).length,
|
|
||||||
addedComponents: incremental.componentChanges.filter(
|
|
||||||
(c) => c.operation === ChangeOperation.ComponentAdded
|
|
||||||
).length,
|
|
||||||
removedComponents: incremental.componentChanges.filter(
|
|
||||||
(c) => c.operation === ChangeOperation.ComponentRemoved
|
|
||||||
).length,
|
|
||||||
updatedComponents: incremental.componentChanges.filter(
|
|
||||||
(c) => c.operation === ChangeOperation.ComponentUpdated
|
|
||||||
).length
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置快照版本号(用于测试)
|
* @zh 重置快照版本号(用于测试)
|
||||||
|
* @en Reset snapshot version (for testing)
|
||||||
*/
|
*/
|
||||||
public static resetVersion(): void {
|
public static resetVersion(): void {
|
||||||
this.snapshotVersion = 0;
|
this.snapshotVersion = 0;
|
||||||
|
|||||||
@@ -5,6 +5,12 @@
|
|||||||
|
|
||||||
import type { PlatformWorker } from '../../Platform/IPlatformAdapter';
|
import type { PlatformWorker } from '../../Platform/IPlatformAdapter';
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// 常量 | Constants
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
const ERROR_POOL_DESTROYED = 'Worker pool has been destroyed';
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// 类型定义 | Type Definitions
|
// 类型定义 | Type Definitions
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -37,8 +43,25 @@ interface IWorkerMessageData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @zh Worker 状态
|
* @zh Worker 池状态接口
|
||||||
* @en Worker state
|
* @en Worker pool status interface
|
||||||
|
*/
|
||||||
|
export interface IWorkerPoolStatus {
|
||||||
|
/** @zh Worker 总数 @en Total number of workers */
|
||||||
|
readonly total: number;
|
||||||
|
/** @zh 空闲 Worker 数量 @en Number of idle workers */
|
||||||
|
readonly idle: number;
|
||||||
|
/** @zh 忙碌 Worker 数量 @en Number of busy workers */
|
||||||
|
readonly busy: number;
|
||||||
|
/** @zh 初始化中的 Worker 数量 @en Number of initializing workers */
|
||||||
|
readonly initializing: number;
|
||||||
|
/** @zh 队列中等待的任务数 @en Number of queued tasks */
|
||||||
|
readonly queuedTasks: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh Worker 状态枚举
|
||||||
|
* @en Worker state enum
|
||||||
*/
|
*/
|
||||||
const enum WorkerState {
|
const enum WorkerState {
|
||||||
/** @zh 初始化中 @en Initializing */
|
/** @zh 初始化中 @en Initializing */
|
||||||
@@ -66,7 +89,11 @@ export class PlatformWorkerPool {
|
|||||||
private readonly pendingTasks: Map<number, IWorkerTask> = new Map();
|
private readonly pendingTasks: Map<number, IWorkerTask> = new Map();
|
||||||
private readonly taskQueue: IWorkerTask[] = [];
|
private readonly taskQueue: IWorkerTask[] = [];
|
||||||
private taskCounter = 0;
|
private taskCounter = 0;
|
||||||
private isDestroyed = false;
|
private _isDestroyed = false;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 构造函数 | Constructor
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @zh 创建 Worker 池
|
* @zh 创建 Worker 池
|
||||||
@@ -83,6 +110,136 @@ export class PlatformWorkerPool {
|
|||||||
this.initializeWorkers(sharedBuffer);
|
this.initializeWorkers(sharedBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 公共属性 | Public Properties
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 池是否已销毁
|
||||||
|
* @en Whether the pool has been destroyed
|
||||||
|
*/
|
||||||
|
get isDestroyed(): boolean {
|
||||||
|
return this._isDestroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh Worker 数量
|
||||||
|
* @en Number of workers in the pool
|
||||||
|
*/
|
||||||
|
get workerCount(): number {
|
||||||
|
return this.workers.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 所有 Worker 是否已就绪(无初始化中的 Worker)
|
||||||
|
* @en Whether all workers are ready (no initializing workers)
|
||||||
|
*/
|
||||||
|
get isReady(): boolean {
|
||||||
|
if (this._isDestroyed) return false;
|
||||||
|
for (const state of this.workerStates.values()) {
|
||||||
|
if (state === WorkerState.Initializing) return false;
|
||||||
|
}
|
||||||
|
return this.workers.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 是否有待处理的任务(队列中或执行中)
|
||||||
|
* @en Whether there are pending tasks (queued or executing)
|
||||||
|
*/
|
||||||
|
get hasPendingTasks(): boolean {
|
||||||
|
return this.taskQueue.length > 0 || this.pendingTasks.size > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 公共方法 | Public Methods
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 执行 SharedArrayBuffer 任务
|
||||||
|
* @en Execute SharedArrayBuffer task
|
||||||
|
*
|
||||||
|
* @param data - @zh 任务数据 @en Task data
|
||||||
|
* @returns @zh 任务完成的 Promise @en Promise that resolves when task completes
|
||||||
|
*/
|
||||||
|
executeSharedBuffer(data: Record<string, unknown>): Promise<void> {
|
||||||
|
return this.createTask<void>(
|
||||||
|
`shared-${++this.taskCounter}`,
|
||||||
|
{ ...data, type: 'shared' },
|
||||||
|
() => undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 执行普通任务
|
||||||
|
* @en Execute normal task
|
||||||
|
*
|
||||||
|
* @param data - @zh 任务数据 @en Task data
|
||||||
|
* @returns @zh 包含任务结果的 Promise @en Promise with task result
|
||||||
|
*/
|
||||||
|
execute<TResult = unknown>(data: Record<string, unknown>): Promise<TResult> {
|
||||||
|
return this.createTask<TResult>(
|
||||||
|
`task-${++this.taskCounter}`,
|
||||||
|
data,
|
||||||
|
(result) => result as TResult
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 获取 Worker 池状态
|
||||||
|
* @en Get Worker pool status
|
||||||
|
*
|
||||||
|
* @returns @zh 池状态对象 @en Pool status object
|
||||||
|
*/
|
||||||
|
getStatus(): IWorkerPoolStatus {
|
||||||
|
const status = { idle: 0, busy: 0, initializing: 0 };
|
||||||
|
|
||||||
|
for (const state of this.workerStates.values()) {
|
||||||
|
if (state === WorkerState.Idle) status.idle++;
|
||||||
|
else if (state === WorkerState.Busy) status.busy++;
|
||||||
|
else if (state === WorkerState.Initializing) status.initializing++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: this.workers.length,
|
||||||
|
...status,
|
||||||
|
queuedTasks: this.taskQueue.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 销毁 Worker 池,释放所有资源
|
||||||
|
* @en Destroy Worker pool and release all resources
|
||||||
|
*/
|
||||||
|
destroy(): void {
|
||||||
|
if (this._isDestroyed) return;
|
||||||
|
this._isDestroyed = true;
|
||||||
|
|
||||||
|
const destroyError = new Error(ERROR_POOL_DESTROYED);
|
||||||
|
|
||||||
|
// Reject all pending and queued tasks
|
||||||
|
for (const task of this.pendingTasks.values()) {
|
||||||
|
task.reject(destroyError);
|
||||||
|
}
|
||||||
|
for (const task of this.taskQueue) {
|
||||||
|
task.reject(destroyError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate all workers
|
||||||
|
for (const worker of this.workers) {
|
||||||
|
worker.terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear state
|
||||||
|
this.workers.length = 0;
|
||||||
|
this.taskQueue.length = 0;
|
||||||
|
this.pendingTasks.clear();
|
||||||
|
this.workerStates.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// 私有方法 | Private Methods
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @zh 初始化所有 Worker
|
* @zh 初始化所有 Worker
|
||||||
* @en Initialize all Workers
|
* @en Initialize all Workers
|
||||||
@@ -92,14 +249,10 @@ export class PlatformWorkerPool {
|
|||||||
const worker = this.workers[i];
|
const worker = this.workers[i];
|
||||||
if (!worker) continue;
|
if (!worker) continue;
|
||||||
|
|
||||||
// Set initial state
|
|
||||||
this.workerStates.set(i, sharedBuffer ? WorkerState.Initializing : WorkerState.Idle);
|
this.workerStates.set(i, sharedBuffer ? WorkerState.Initializing : WorkerState.Idle);
|
||||||
|
|
||||||
// Bind message and error handlers
|
|
||||||
worker.onMessage((event) => this.handleMessage(i, event.data));
|
worker.onMessage((event) => this.handleMessage(i, event.data));
|
||||||
worker.onError((error) => this.handleError(i, error));
|
worker.onError((error) => this.handleError(i, error));
|
||||||
|
|
||||||
// Initialize SharedArrayBuffer if provided
|
|
||||||
if (sharedBuffer) {
|
if (sharedBuffer) {
|
||||||
worker.postMessage({ type: 'init', sharedBuffer });
|
worker.postMessage({ type: 'init', sharedBuffer });
|
||||||
}
|
}
|
||||||
@@ -107,46 +260,26 @@ export class PlatformWorkerPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @zh 执行 SharedArrayBuffer 任务
|
* @zh 创建并入队任务
|
||||||
* @en Execute SharedArrayBuffer task
|
* @en Create and enqueue task
|
||||||
*/
|
*/
|
||||||
executeSharedBuffer(data: Record<string, unknown>): Promise<void> {
|
private createTask<T>(
|
||||||
|
id: string,
|
||||||
|
data: Record<string, unknown>,
|
||||||
|
transform: (result: unknown) => T
|
||||||
|
): Promise<T> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.isDestroyed) {
|
if (this._isDestroyed) {
|
||||||
reject(new Error('Worker pool has been destroyed'));
|
reject(new Error(ERROR_POOL_DESTROYED));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const task: IWorkerTask = {
|
this.enqueueTask({
|
||||||
id: `shared-${++this.taskCounter}`,
|
id,
|
||||||
data: { ...data, type: 'shared' },
|
|
||||||
resolve: () => resolve(),
|
|
||||||
reject
|
|
||||||
};
|
|
||||||
|
|
||||||
this.enqueueTask(task);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @zh 执行普通任务
|
|
||||||
* @en Execute normal task
|
|
||||||
*/
|
|
||||||
execute<TResult = unknown>(data: Record<string, unknown>): Promise<TResult> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (this.isDestroyed) {
|
|
||||||
reject(new Error('Worker pool has been destroyed'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const task: IWorkerTask = {
|
|
||||||
id: `task-${++this.taskCounter}`,
|
|
||||||
data,
|
data,
|
||||||
resolve: (result) => resolve(result as TResult),
|
resolve: (result) => resolve(transform(result)),
|
||||||
reject
|
reject
|
||||||
};
|
});
|
||||||
|
|
||||||
this.enqueueTask(task);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,27 +341,17 @@ export class PlatformWorkerPool {
|
|||||||
* @en Handle Worker message
|
* @en Handle Worker message
|
||||||
*/
|
*/
|
||||||
private handleMessage(workerIndex: number, data: IWorkerMessageData): void {
|
private handleMessage(workerIndex: number, data: IWorkerMessageData): void {
|
||||||
// Handle initialization response
|
|
||||||
if (data.type === 'init') {
|
if (data.type === 'init') {
|
||||||
this.workerStates.set(workerIndex, WorkerState.Idle);
|
this.workerStates.set(workerIndex, WorkerState.Idle);
|
||||||
this.dispatchTasks();
|
this.dispatchTasks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle task response
|
|
||||||
const task = this.pendingTasks.get(workerIndex);
|
|
||||||
if (!task) return;
|
|
||||||
|
|
||||||
this.pendingTasks.delete(workerIndex);
|
|
||||||
this.workerStates.set(workerIndex, WorkerState.Idle);
|
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
task.reject(new Error(data.error));
|
this.completeTask(workerIndex, new Error(data.error));
|
||||||
} else {
|
} else {
|
||||||
task.resolve(data.result);
|
this.completeTask(workerIndex, undefined, data.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dispatchTasks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,82 +359,26 @@ export class PlatformWorkerPool {
|
|||||||
* @en Handle Worker error
|
* @en Handle Worker error
|
||||||
*/
|
*/
|
||||||
private handleError(workerIndex: number, error: ErrorEvent): void {
|
private handleError(workerIndex: number, error: ErrorEvent): void {
|
||||||
const task = this.pendingTasks.get(workerIndex);
|
this.completeTask(workerIndex, new Error(error.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @zh 完成任务并释放 Worker
|
||||||
|
* @en Complete task and release Worker
|
||||||
|
*/
|
||||||
|
private completeTask(workerIndex: number, error?: Error, result?: unknown): void {
|
||||||
|
const task = this.pendingTasks.get(workerIndex);
|
||||||
|
if (!task) return;
|
||||||
|
|
||||||
if (task) {
|
|
||||||
this.pendingTasks.delete(workerIndex);
|
this.pendingTasks.delete(workerIndex);
|
||||||
this.workerStates.set(workerIndex, WorkerState.Idle);
|
this.workerStates.set(workerIndex, WorkerState.Idle);
|
||||||
task.reject(new Error(error.message));
|
|
||||||
|
if (error) {
|
||||||
|
task.reject(error);
|
||||||
|
} else {
|
||||||
|
task.resolve(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dispatchTasks();
|
this.dispatchTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @zh 获取 Worker 池状态
|
|
||||||
* @en Get Worker pool status
|
|
||||||
*/
|
|
||||||
getStatus(): {
|
|
||||||
total: number;
|
|
||||||
idle: number;
|
|
||||||
busy: number;
|
|
||||||
initializing: number;
|
|
||||||
queuedTasks: number;
|
|
||||||
} {
|
|
||||||
let idle = 0;
|
|
||||||
let busy = 0;
|
|
||||||
let initializing = 0;
|
|
||||||
|
|
||||||
for (const state of this.workerStates.values()) {
|
|
||||||
switch (state) {
|
|
||||||
case WorkerState.Idle:
|
|
||||||
idle++;
|
|
||||||
break;
|
|
||||||
case WorkerState.Busy:
|
|
||||||
busy++;
|
|
||||||
break;
|
|
||||||
case WorkerState.Initializing:
|
|
||||||
initializing++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
total: this.workers.length,
|
|
||||||
idle,
|
|
||||||
busy,
|
|
||||||
initializing,
|
|
||||||
queuedTasks: this.taskQueue.length
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @zh 销毁 Worker 池
|
|
||||||
* @en Destroy Worker pool
|
|
||||||
*/
|
|
||||||
destroy(): void {
|
|
||||||
if (this.isDestroyed) return;
|
|
||||||
this.isDestroyed = true;
|
|
||||||
|
|
||||||
// Reject all pending tasks
|
|
||||||
for (const task of this.pendingTasks.values()) {
|
|
||||||
task.reject(new Error('Worker pool destroyed'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reject all queued tasks
|
|
||||||
for (const task of this.taskQueue) {
|
|
||||||
task.reject(new Error('Worker pool destroyed'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate all workers
|
|
||||||
for (const worker of this.workers) {
|
|
||||||
worker.terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear state
|
|
||||||
this.workers.length = 0;
|
|
||||||
this.taskQueue.length = 0;
|
|
||||||
this.pendingTasks.clear();
|
|
||||||
this.workerStates.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export { IntervalSystem } from './IntervalSystem';
|
|||||||
export { WorkerEntitySystem } from './WorkerEntitySystem';
|
export { WorkerEntitySystem } from './WorkerEntitySystem';
|
||||||
export { HierarchySystem } from './HierarchySystem';
|
export { HierarchySystem } from './HierarchySystem';
|
||||||
export { PlatformWorkerPool } from './PlatformWorkerPool';
|
export { PlatformWorkerPool } from './PlatformWorkerPool';
|
||||||
|
export type { IWorkerPoolStatus } from './PlatformWorkerPool';
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Worker 系统类型导出 | Worker System Type Exports
|
// Worker 系统类型导出 | Worker System Type Exports
|
||||||
|
|||||||
Reference in New Issue
Block a user