/** * 池管理器 */ import { ECSMask } from '../component/ECSMask'; import { ECSDynamicPool } from './ECSDynamicPool'; import type { IECSPoolMetrics } from './IECSPoolMetrics'; import type { ECSEntity } from '../entity/ECSEntity'; import type { ecs } from '../ECS'; import { type CompCtor, type EntityCtor } from '../registry/ECSTypes'; import { registry } from '../registry/ECSTypeRegistry'; /** 池对象类型 - 实体或组件 */ type ECSPoolObject = ECSEntity | ecs.IComp; /** 池类型名称 - 实体名或组件名 */ type ECSPoolTypeName = string; /** * 池管理器 —— 统一管理实体 / 组件动态对象池,并作为 `ecs.pool` 对外暴露。 */ export class ECSPoolManager { /** 所有对象池的映射 */ private pools: Map> = new Map(); /** * 从构造函数获取池类型名称 * @param ctor 实体或组件的构造函数 * @returns 池类型名称 */ private getTypeNameFromCtor(ctor: EntityCtor): string { // 检查是否是组件构造函数(有 compName 属性) const ctorAny = ctor as unknown as { compName?: string }; if (typeof ctorAny.compName === 'string') { return ctorAny.compName; } // 检查是否是实体构造函数(从 registry.entityCtors 查找) const entityName = registry.entityCtors.get(ctor as EntityCtor); if (entityName) { return entityName; } // 如果都找不到,使用构造函数名 return ctor.name; } /** * 获取或创建池 * @param typeName 池类型名称(实体名如 "Account"、"RedDot",或组件名如 "M_Equip_Model") * @param factory 对象工厂函数 * @returns 动态对象池实例 */ getPool(typeName: ECSPoolTypeName, factory: () => T): ECSDynamicPool { if (!this.pools.has(typeName)) { const pool = new ECSDynamicPool(factory); this.pools.set(typeName, pool); } return this.pools.get(typeName)! as ECSDynamicPool; } /** * 删除指定池(清空对象并从管理中移除) * @param typeNameOrCtor 池类型名称(实体名或组件名)或构造函数 * @returns 是否成功删除 */ removePool(typeNameOrCtor: ECSPoolTypeName | EntityCtor | CompCtor): boolean { let typeName: string; if (typeof typeNameOrCtor === 'string') { typeName = typeNameOrCtor; } else { typeName = this.getTypeNameFromCtor(typeNameOrCtor as EntityCtor); } const pool = this.pools.get(typeName); if (pool) { pool.clear(); this.pools.delete(typeName); return true; } return false; } /** * 清空所有池 */ clearAll(): void { this.pools.forEach(pool => pool.clear()); this.pools.clear(); } /** * 清理所有对象池缓存 —— 仅释放「已回收待复用」的空闲对象,不触碰存活数据。 * * 清理范围:Mask 位掩码池 + 实体 / 组件动态对象池。 * 不清理 SoA 列存储;整体重置请用 `ecs.world.clear()`。 */ clearPools(): void { ECSMask.clearPool(); this.clearAll(); } /** * 获取所有池的统计信息 * @returns 类型名称到统计指标的映射 */ getAllMetrics(): Map { const result = new Map(); this.pools.forEach((pool, typeName) => { result.set(typeName, pool.getMetrics()); }); return result; } /** * 获取指定类型的池 * @param typeName 池类型名称(实体名或组件名) * @returns 池实例,如果不存在则返回undefined */ getPoolByName(typeName: ECSPoolTypeName): ECSDynamicPool | undefined { return this.pools.get(typeName) as ECSDynamicPool | undefined; } /** * 获取所有池的名称 * @returns 池名称数组(实体名或组件名数组) */ getPoolNames(): ECSPoolTypeName[] { return Array.from(this.pools.keys()); } /** * 清空指定池中的对象 * @param typeName 池类型名称(实体名或组件名) */ clearPool(typeName: ECSPoolTypeName): void { const pool = this.pools.get(typeName); if (pool) { pool.clear(); } } /** * 获取指定池的统计信息 * @param typeName 池类型名称(实体名或组件名) * @returns 统计指标对象,如果池不存在则返回undefined */ getPoolMetrics(typeName: ECSPoolTypeName): IECSPoolMetrics | undefined { const pool = this.pools.get(typeName); return pool ? pool.getMetrics() : undefined; } } /** 全局池管理器实例(`ecs.pool` 即此对象) */ export const ecsPoolCoordinator = new ECSPoolManager();