diff --git a/packages/core/src/Core.ts b/packages/core/src/Core.ts index 968f9ca1..858547ca 100644 --- a/packages/core/src/Core.ts +++ b/packages/core/src/Core.ts @@ -329,8 +329,8 @@ export class Core { */ public static setScene(scene: T): T { if (!this._instance) { - Core._logger.warn("Core实例未创建,请先调用Core.create()"); - throw new Error("Core实例未创建"); + Core._logger.warn('Core实例未创建,请先调用Core.create()'); + throw new Error('Core实例未创建'); } return this._instance._sceneManager.setScene(scene); @@ -387,7 +387,7 @@ export class Core { */ public static loadScene(scene: T): void { if (!this._instance) { - Core._logger.warn("Core实例未创建,请先调用Core.create()"); + Core._logger.warn('Core实例未创建,请先调用Core.create()'); return; } @@ -422,7 +422,7 @@ export class Core { */ public static update(deltaTime: number): void { if (!this._instance) { - Core._logger.warn("Core实例未创建,请先调用Core.create()"); + Core._logger.warn('Core实例未创建,请先调用Core.create()'); return; } @@ -472,7 +472,7 @@ export class Core { */ public static enableDebug(config: IECSDebugConfig): void { if (!this._instance) { - Core._logger.warn("Core实例未创建,请先调用Core.create()"); + Core._logger.warn('Core实例未创建,请先调用Core.create()'); return; } diff --git a/packages/core/src/Core/DI/Decorators.ts b/packages/core/src/Core/DI/Decorators.ts index 2f266e62..e25d8703 100644 --- a/packages/core/src/Core/DI/Decorators.ts +++ b/packages/core/src/Core/DI/Decorators.ts @@ -123,7 +123,7 @@ export function Updatable(priority: number = 0): ClassDecorator { if (!prototype || typeof prototype.update !== 'function') { throw new Error( `@Updatable() decorator requires class ${target.name} to implement IUpdatable interface with update() method. ` + - `Please add 'implements IUpdatable' and define update(deltaTime?: number): void method.` + 'Please add \'implements IUpdatable\' and define update(deltaTime?: number): void method.' ); } @@ -249,7 +249,7 @@ export function createInstance( if (typeof serviceType === 'string' || typeof serviceType === 'symbol') { // 字符串或Symbol类型的服务标识 throw new Error( - `String and Symbol service identifiers are not yet supported in constructor injection. ` + + 'String and Symbol service identifiers are not yet supported in constructor injection. ' + `Please use class types for ${constructor.name} parameter ${i}` ); } else { @@ -338,7 +338,7 @@ export function registerInjectable( if (!isInjectable(serviceType)) { throw new Error( `${serviceType.name} is not marked as @Injectable(). ` + - `Please add @Injectable() decorator to the class.` + 'Please add @Injectable() decorator to the class.' ); } diff --git a/packages/core/src/Core/ServiceContainer.ts b/packages/core/src/Core/ServiceContainer.ts index 50e34069..9833deb0 100644 --- a/packages/core/src/Core/ServiceContainer.ts +++ b/packages/core/src/Core/ServiceContainer.ts @@ -240,7 +240,7 @@ export class ServiceContainer { // 检测循环依赖 if (this._resolving.has(type as ServiceType)) { - const chain = Array.from(this._resolving).map(t => t.name).join(' -> '); + const chain = Array.from(this._resolving).map((t) => t.name).join(' -> '); throw new Error(`Circular dependency detected: ${chain} -> ${type.name}`); } @@ -337,7 +337,7 @@ export class ServiceContainer { // 如果有单例实例,调用 dispose if (registration.instance) { // 从可更新列表中移除 - const index = this._updatableServices.findIndex(item => item.instance === registration.instance); + const index = this._updatableServices.findIndex((item) => item.instance === registration.instance); if (index !== -1) { this._updatableServices.splice(index, 1); } diff --git a/packages/core/src/ECS/Core/ArchetypeSystem.ts b/packages/core/src/ECS/Core/ArchetypeSystem.ts index b56cddb6..c1ea5727 100644 --- a/packages/core/src/ECS/Core/ArchetypeSystem.ts +++ b/packages/core/src/ECS/Core/ArchetypeSystem.ts @@ -1,7 +1,7 @@ import { Entity } from '../Entity'; import { ComponentType, ComponentRegistry } from './ComponentStorage'; -import { BitMask64Data, BitMask64Utils } from "../Utils"; -import { BitMaskHashMap } from "../Utils/BitMaskHashMap"; +import { BitMask64Data, BitMask64Utils } from '../Utils'; +import { BitMaskHashMap } from '../Utils/BitMaskHashMap'; /** * 原型标识符 @@ -32,7 +32,7 @@ export interface ArchetypeQueryResult { /** * Archetype系统 - * + * * 根据实体的组件组合将实体分组到不同的原型中,提供高效的查询性能。 */ export class ArchetypeSystem { @@ -50,7 +50,7 @@ export class ArchetypeSystem { /** 所有原型 */ private _allArchetypes: Archetype[] = []; - + /** * 添加实体到原型系统 */ @@ -66,7 +66,7 @@ export class ArchetypeSystem { archetype.entities.add(entity); this._entityToArchetype.set(entity, archetype); } - + /** * 从原型系统中移除实体 */ @@ -118,7 +118,7 @@ export class ArchetypeSystem { this._entityToArchetype.set(entity, newArchetype); } - + /** * 查询包含指定组件组合的原型 * @@ -198,14 +198,14 @@ export class ArchetypeSystem { totalEntities }; } - + /** * 获取实体所属的原型 */ public getEntityArchetype(entity: Entity): Archetype | undefined { return this._entityToArchetype.get(entity); } - + /** * 获取所有原型 */ @@ -247,7 +247,7 @@ export class ArchetypeSystem { */ private updateAllArchetypeArrays(): void { this._allArchetypes = []; - for (let archetype of this._archetypes.values()) { + for (const archetype of this._archetypes.values()) { this._allArchetypes.push(archetype); } } @@ -258,18 +258,18 @@ export class ArchetypeSystem { private getEntityComponentTypes(entity: Entity): ComponentType[] { let componentTypes = this._entityComponentTypesCache.get(entity); if (!componentTypes) { - componentTypes = entity.components.map(component => component.constructor as ComponentType); + componentTypes = entity.components.map((component) => component.constructor as ComponentType); this._entityComponentTypesCache.set(entity, componentTypes); } return componentTypes; } - + /** * 生成原型ID * 使用ComponentRegistry确保与Entity.componentMask使用相同的bitIndex */ private generateArchetypeId(componentTypes: ComponentType[]): ArchetypeId { - let mask = BitMask64Utils.clone(BitMask64Utils.ZERO); + const mask = BitMask64Utils.clone(BitMask64Utils.ZERO); for (const type of componentTypes) { if (!ComponentRegistry.isRegistered(type)) { ComponentRegistry.register(type); @@ -279,7 +279,7 @@ export class ArchetypeSystem { } return mask; } - + /** * 创建新原型 */ diff --git a/packages/core/src/ECS/Core/ComponentPool.ts b/packages/core/src/ECS/Core/ComponentPool.ts index fedf8ed5..c8e07763 100644 --- a/packages/core/src/ECS/Core/ComponentPool.ts +++ b/packages/core/src/ECS/Core/ComponentPool.ts @@ -356,4 +356,4 @@ export class ComponentPoolManager { return maxSize > 0 ? (used / maxSize * 100) : 0; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/ComponentStorage.ts b/packages/core/src/ECS/Core/ComponentStorage.ts index f2b6f1fa..e425c665 100644 --- a/packages/core/src/ECS/Core/ComponentStorage.ts +++ b/packages/core/src/ECS/Core/ComponentStorage.ts @@ -9,7 +9,6 @@ import { ComponentRegistry, ComponentType } from './ComponentStorage/ComponentRe export { ComponentRegistry, ComponentType }; - /** * 高性能组件存储器 */ @@ -21,7 +20,7 @@ export class ComponentStorage { constructor(componentType: ComponentType) { this.componentType = componentType; - + // 确保组件类型已注册 if (!ComponentRegistry.isRegistered(componentType)) { ComponentRegistry.register(componentType); @@ -152,7 +151,7 @@ export class ComponentStorage { usedSlots: number; freeSlots: number; fragmentation: number; - } { + } { const totalSlots = this.dense.length; const usedSlots = this.dense.length; const freeSlots = 0; // 永远无空洞 @@ -342,15 +341,15 @@ export class ComponentStorageManager { * @returns 组件位掩码 */ public getComponentMask(entityId: number): BitMask64Data { - let mask = BitMask64Utils.clone(BitMask64Utils.ZERO); - + const mask = BitMask64Utils.clone(BitMask64Utils.ZERO); + for (const [componentType, storage] of this.storages.entries()) { if (storage.hasComponent(entityId)) { const componentMask = ComponentRegistry.getBitMask(componentType as ComponentType); BitMask64Utils.orInPlace(mask, componentMask); } } - + return mask; } @@ -360,12 +359,12 @@ export class ComponentStorageManager { */ public getAllStats(): Map { const stats = new Map(); - + for (const [componentType, storage] of this.storages.entries()) { const typeName = getComponentTypeName(componentType as ComponentType); stats.set(typeName, storage.getStats()); } - + return stats; } @@ -378,4 +377,4 @@ export class ComponentStorageManager { } this.storages.clear(); } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts b/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts index 6bd38eb7..bf1ec8cd 100644 --- a/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts +++ b/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts @@ -153,7 +153,7 @@ export class ComponentRegistry { */ public static createSingleComponentMask(componentName: string): BitMask64Data { const cacheKey = `single:${componentName}`; - + if (this.maskCache.has(cacheKey)) { return this.maskCache.get(cacheKey)!; } @@ -176,12 +176,12 @@ export class ComponentRegistry { public static createComponentMask(componentNames: string[]): BitMask64Data { const sortedNames = [...componentNames].sort(); const cacheKey = `multi:${sortedNames.join(',')}`; - + if (this.maskCache.has(cacheKey)) { return this.maskCache.get(cacheKey)!; } - let mask = BitMask64Utils.clone(BitMask64Utils.ZERO); + const mask = BitMask64Utils.clone(BitMask64Utils.ZERO); for (const name of componentNames) { const componentId = this.getComponentId(name); if (componentId !== undefined) { @@ -212,4 +212,4 @@ export class ComponentRegistry { this.maskCache.clear(); this.nextBitIndex = 0; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/Events/index.ts b/packages/core/src/ECS/Core/Events/index.ts index 50d79b23..a8de6f02 100644 --- a/packages/core/src/ECS/Core/Events/index.ts +++ b/packages/core/src/ECS/Core/Events/index.ts @@ -1,2 +1,2 @@ export { EventBus, GlobalEventBus } from '../EventBus'; -export { TypeSafeEventSystem, EventListenerConfig, EventStats } from '../EventSystem'; \ No newline at end of file +export { TypeSafeEventSystem, EventListenerConfig, EventStats } from '../EventSystem'; diff --git a/packages/core/src/ECS/Core/FluentAPI.ts b/packages/core/src/ECS/Core/FluentAPI.ts index 80d223f8..9a7033f2 100644 --- a/packages/core/src/ECS/Core/FluentAPI.ts +++ b/packages/core/src/ECS/Core/FluentAPI.ts @@ -8,4 +8,4 @@ export { createECSAPI, initializeECS, ECS -} from './FluentAPI/index'; \ No newline at end of file +} from './FluentAPI/index'; diff --git a/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts b/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts index 5040232c..ac21d5ac 100644 --- a/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts +++ b/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts @@ -52,4 +52,4 @@ export class ComponentBuilder { public build(): T { return this.component; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts b/packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts index b8be16fd..9ab2fc7b 100644 --- a/packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts +++ b/packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts @@ -47,7 +47,7 @@ export class ECSFluentAPI { * @returns 组件构建器 */ public createComponent( - componentClass: new (...args: unknown[]) => T, + componentClass: new (...args: unknown[]) => T, ...args: unknown[] ): ComponentBuilder { return new ComponentBuilder(componentClass, ...args); @@ -164,7 +164,7 @@ export class ECSFluentAPI { componentStats: Map; queryStats: unknown; eventStats: Map; - } { + } { return { entityCount: this.scene.entities.count, systemCount: this.scene.systems.length, @@ -183,8 +183,8 @@ export class ECSFluentAPI { * @returns ECS流式API实例 */ export function createECSAPI( - scene: IScene, - querySystem: QuerySystem, + scene: IScene, + querySystem: QuerySystem, eventSystem: TypeSafeEventSystem ): ECSFluentAPI { return new ECSFluentAPI(scene, querySystem, eventSystem); @@ -202,9 +202,9 @@ export let ECS: ECSFluentAPI; * @param eventSystem 事件系统 */ export function initializeECS( - scene: IScene, - querySystem: QuerySystem, + scene: IScene, + querySystem: QuerySystem, eventSystem: TypeSafeEventSystem ): void { ECS = createECSAPI(scene, querySystem, eventSystem); -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts b/packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts index 4d08217d..8eb8b04f 100644 --- a/packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts +++ b/packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts @@ -95,4 +95,4 @@ export class EntityBatchOperator { public count(): number { return this.entities.length; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts b/packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts index f266b4c0..8f198a94 100644 --- a/packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts +++ b/packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts @@ -15,7 +15,7 @@ export class EntityBuilder { this.scene = scene; this.storageManager = storageManager; const id = scene.identifierPool.checkOut(); - this.entity = new Entity("", id); + this.entity = new Entity('', id); this.entity.scene = this.scene as any; } @@ -92,7 +92,7 @@ export class EntityBuilder { * @returns 实体构建器 */ public configure( - componentType: ComponentType, + componentType: ComponentType, configurator: (component: T) => void ): EntityBuilder { const component = this.entity.getComponent(componentType); @@ -199,4 +199,4 @@ export class EntityBuilder { newBuilder.entity = this.entity; // 实际应该是深度克隆 return newBuilder; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts b/packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts index a8bc2489..33b1c830 100644 --- a/packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts +++ b/packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts @@ -87,4 +87,4 @@ export class SceneBuilder { public build(): Scene { return this.scene; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/FluentAPI/index.ts b/packages/core/src/ECS/Core/FluentAPI/index.ts index 84ffe4dd..f141b41d 100644 --- a/packages/core/src/ECS/Core/FluentAPI/index.ts +++ b/packages/core/src/ECS/Core/FluentAPI/index.ts @@ -2,4 +2,4 @@ export { EntityBuilder } from './EntityBuilder'; export { SceneBuilder } from './SceneBuilder'; export { ComponentBuilder } from './ComponentBuilder'; export { EntityBatchOperator } from './EntityBatchOperator'; -export { ECSFluentAPI, createECSAPI, initializeECS, ECS } from './ECSFluentAPI'; \ No newline at end of file +export { ECSFluentAPI, createECSAPI, initializeECS, ECS } from './ECSFluentAPI'; diff --git a/packages/core/src/ECS/Core/Query/index.ts b/packages/core/src/ECS/Core/Query/index.ts index 384cd4db..89efc042 100644 --- a/packages/core/src/ECS/Core/Query/index.ts +++ b/packages/core/src/ECS/Core/Query/index.ts @@ -1,3 +1,2 @@ export { QuerySystem } from '../QuerySystem'; export { ECSFluentAPI, createECSAPI } from '../FluentAPI'; - \ No newline at end of file diff --git a/packages/core/src/ECS/Core/QuerySystem.ts b/packages/core/src/ECS/Core/QuerySystem.ts index c0ba8291..894ab243 100644 --- a/packages/core/src/ECS/Core/QuerySystem.ts +++ b/packages/core/src/ECS/Core/QuerySystem.ts @@ -882,7 +882,7 @@ export class QuerySystem { size: number; hitRate: string; }; - } { + } { return { entityCount: this._entities.length, indexStats: { diff --git a/packages/core/src/ECS/Core/ReactiveQuery.ts b/packages/core/src/ECS/Core/ReactiveQuery.ts index 55758480..5c2194ab 100644 --- a/packages/core/src/ECS/Core/ReactiveQuery.ts +++ b/packages/core/src/ECS/Core/ReactiveQuery.ts @@ -136,7 +136,7 @@ export class ReactiveQuery { private generateQueryId(): string { const typeStr = this._condition.type; const componentsStr = this._condition.componentTypes - .map(t => t.name) + .map((t) => t.name) .sort() .join(','); return `${typeStr}:${componentsStr}`; diff --git a/packages/core/src/ECS/Core/SoAStorage.ts b/packages/core/src/ECS/Core/SoAStorage.ts index befce482..4644f3b6 100644 --- a/packages/core/src/ECS/Core/SoAStorage.ts +++ b/packages/core/src/ECS/Core/SoAStorage.ts @@ -345,12 +345,12 @@ export class SoAStorage { private _size = 0; private _capacity = 1000; public readonly type: ComponentType; - + constructor(componentType: ComponentType) { this.type = componentType; this.initializeFields(componentType); } - + private initializeFields(componentType: ComponentType): void { const instance = new componentType(); const highPrecisionFields = (componentType as any).__highPrecisionFields || new Set(); @@ -368,12 +368,12 @@ export class SoAStorage { const serializeSetFields = (componentType as any).__serializeSetFields || new Set(); const serializeArrayFields = (componentType as any).__serializeArrayFields || new Set(); // const deepCopyFields = (componentType as any).__deepCopyFields || new Set(); // 未使用,但保留供future使用 - + for (const key in instance) { if (instance.hasOwnProperty(key) && key !== 'id') { const value = (instance as any)[key]; const type = typeof value; - + if (type === 'number') { if (highPrecisionFields.has(key)) { // 标记为高精度,作为复杂对象处理 @@ -438,14 +438,14 @@ export class SoAStorage { } } } - + public addComponent(entityId: number, component: T): void { if (this.entityToIndex.has(entityId)) { const index = this.entityToIndex.get(entityId)!; this.updateComponentAtIndex(index, component); return; } - + let index: number; if (this.freeIndices.length > 0) { index = this.freeIndices.pop()!; @@ -455,13 +455,13 @@ export class SoAStorage { this.resize(this._capacity * 2); } } - + this.entityToIndex.set(entityId, index); this.indexToEntity[index] = entityId; this.updateComponentAtIndex(index, component); this._size++; } - + private updateComponentAtIndex(index: number, component: T): void { const entityId = this.indexToEntity[index]!; const complexFieldMap = new Map(); @@ -470,13 +470,13 @@ export class SoAStorage { const serializeSetFields = (this.type as any).__serializeSetFields || new Set(); const serializeArrayFields = (this.type as any).__serializeArrayFields || new Set(); const deepCopyFields = (this.type as any).__deepCopyFields || new Set(); - + // 处理所有字段 for (const key in component) { if (component.hasOwnProperty(key) && key !== 'id') { const value = (component as any)[key]; const type = typeof value; - + if (type === 'number') { if (highPrecisionFields.has(key) || !this.fields.has(key)) { // 标记为高精度或未在TypedArray中的数值作为复杂对象存储 @@ -487,7 +487,7 @@ export class SoAStorage { array[index] = value; } } else if (type === 'boolean' && this.fields.has(key)) { - // 布尔值存储到TypedArray + // 布尔值存储到TypedArray const array = this.fields.get(key)!; array[index] = value ? 1 : 0; } else if (this.stringFields.has(key)) { @@ -509,13 +509,13 @@ export class SoAStorage { } } } - + // 存储复杂字段 if (complexFieldMap.size > 0) { this.complexFields.set(entityId, complexFieldMap); } } - + /** * 序列化值为JSON字符串 */ @@ -539,14 +539,14 @@ export class SoAStorage { return '{}'; } } - + /** * 反序列化JSON字符串为值 */ private deserializeValue(serialized: string, key: string, mapFields: Set, setFields: Set, arrayFields: Set): any { try { const parsed = JSON.parse(serialized); - + if (mapFields.has(key)) { // 恢复Map return new Map(parsed); @@ -564,7 +564,7 @@ export class SoAStorage { return null; } } - + /** * 深拷贝对象 */ @@ -572,15 +572,15 @@ export class SoAStorage { if (obj === null || typeof obj !== 'object') { return obj; } - + if (obj instanceof Date) { return new Date(obj.getTime()); } - + if (obj instanceof Array) { - return obj.map(item => this.deepClone(item)); + return obj.map((item) => this.deepClone(item)); } - + if (obj instanceof Map) { const cloned = new Map(); for (const [key, value] of obj.entries()) { @@ -588,7 +588,7 @@ export class SoAStorage { } return cloned; } - + if (obj instanceof Set) { const cloned = new Set(); for (const value of obj.values()) { @@ -596,7 +596,7 @@ export class SoAStorage { } return cloned; } - + // 普通对象 const cloned: any = {}; for (const key in obj) { @@ -606,36 +606,36 @@ export class SoAStorage { } return cloned; } - + public getComponent(entityId: number): T | null { const index = this.entityToIndex.get(entityId); if (index === undefined) { return null; } - + // 创建真正的组件实例以保持兼容性 const component = new this.type() as any; const serializeMapFields = (this.type as any).__serializeMapFields || new Set(); const serializeSetFields = (this.type as any).__serializeSetFields || new Set(); const serializeArrayFields = (this.type as any).__serializeArrayFields || new Set(); - + // 恢复数值字段 for (const [fieldName, array] of this.fields.entries()) { const value = array[index]; const fieldType = this.getFieldType(fieldName); - + if (fieldType === 'boolean') { component[fieldName] = value === 1; } else { component[fieldName] = value; } } - + // 恢复字符串字段 for (const [fieldName, stringArray] of this.stringFields.entries()) { component[fieldName] = stringArray[index]; } - + // 恢复序列化字段 for (const [fieldName, serializedArray] of this.serializedFields.entries()) { const serialized = serializedArray[index]; @@ -643,7 +643,7 @@ export class SoAStorage { component[fieldName] = this.deserializeValue(serialized, fieldName, serializeMapFields, serializeSetFields, serializeArrayFields); } } - + // 恢复复杂字段 const complexFieldMap = this.complexFields.get(entityId); if (complexFieldMap) { @@ -651,39 +651,39 @@ export class SoAStorage { component[fieldName] = value; } } - + return component as T; } - + private getFieldType(fieldName: string): string { // 通过创建临时实例检查字段类型 const tempInstance = new this.type(); const value = (tempInstance as any)[fieldName]; return typeof value; } - + public hasComponent(entityId: number): boolean { return this.entityToIndex.has(entityId); } - + public removeComponent(entityId: number): T | null { const index = this.entityToIndex.get(entityId); if (index === undefined) { return null; } - + // 获取组件副本以便返回 const component = this.getComponent(entityId); - + // 清理复杂字段 this.complexFields.delete(entityId); - + this.entityToIndex.delete(entityId); this.freeIndices.push(index); this._size--; return component; } - + private resize(newCapacity: number): void { // 调整数值字段的TypedArray for (const [fieldName, oldArray] of this.fields.entries()) { @@ -716,7 +716,7 @@ export class SoAStorage { newArray.set(oldArray); this.fields.set(fieldName, newArray); } - + // 调整字符串字段的数组 for (const [fieldName, oldArray] of this.stringFields.entries()) { const newArray = new Array(newCapacity); @@ -725,7 +725,7 @@ export class SoAStorage { } this.stringFields.set(fieldName, newArray); } - + // 调整序列化字段的数组 for (const [fieldName, oldArray] of this.serializedFields.entries()) { const newArray = new Array(newCapacity); @@ -734,14 +734,14 @@ export class SoAStorage { } this.serializedFields.set(fieldName, newArray); } - + this._capacity = newCapacity; } - + public getActiveIndices(): number[] { return Array.from(this.entityToIndex.values()); } - + public getFieldArray(fieldName: string): SupportedTypedArray | null { return this.fields.get(fieldName) || null; } @@ -749,38 +749,38 @@ export class SoAStorage { public getTypedFieldArray(fieldName: K): SupportedTypedArray | null { return this.fields.get(String(fieldName)) || null; } - + public getEntityIndex(entityId: number): number | undefined { return this.entityToIndex.get(entityId); } - + public getEntityIdByIndex(index: number): number | undefined { return this.indexToEntity[index]; } - + public size(): number { return this._size; } - + public clear(): void { this.entityToIndex.clear(); this.indexToEntity = []; this.freeIndices = []; this.complexFields.clear(); this._size = 0; - + // 重置数值字段数组 for (const array of this.fields.values()) { array.fill(0); } - + // 重置字符串字段数组 for (const stringArray of this.stringFields.values()) { for (let i = 0; i < stringArray.length; i++) { stringArray[i] = undefined as any; } } - + // 重置序列化字段数组 for (const serializedArray of this.serializedFields.values()) { for (let i = 0; i < serializedArray.length; i++) { @@ -884,7 +884,7 @@ export class SoAStorage { bytesPerElement = 4; typeName = 'unknown'; } - + const memory = array.length * bytesPerElement; totalMemory += memory; @@ -914,4 +914,4 @@ export class SoAStorage { const activeIndices = this.getActiveIndices(); operation(this.fields, activeIndices); } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/Storage/index.ts b/packages/core/src/ECS/Core/Storage/index.ts index 17eeb3ea..37edc40e 100644 --- a/packages/core/src/ECS/Core/Storage/index.ts +++ b/packages/core/src/ECS/Core/Storage/index.ts @@ -1,3 +1,3 @@ export { ComponentPool, ComponentPoolManager } from '../ComponentPool'; export { ComponentStorage, ComponentRegistry } from '../ComponentStorage'; -export { EnableSoA, HighPrecision, Float64, Float32, Int32, SerializeMap, SoAStorage } from '../SoAStorage'; \ No newline at end of file +export { EnableSoA, HighPrecision, Float64, Float32, Int32, SerializeMap, SoAStorage } from '../SoAStorage'; diff --git a/packages/core/src/ECS/Core/StorageDecorators.ts b/packages/core/src/ECS/Core/StorageDecorators.ts index b613db8f..31ebbe55 100644 --- a/packages/core/src/ECS/Core/StorageDecorators.ts +++ b/packages/core/src/ECS/Core/StorageDecorators.ts @@ -46,4 +46,4 @@ export { // 类型定义 SupportedTypedArray -} from './SoAStorage'; \ No newline at end of file +} from './SoAStorage'; diff --git a/packages/core/src/ECS/CoreEvents.ts b/packages/core/src/ECS/CoreEvents.ts index 57d136fb..94aa4c4d 100644 --- a/packages/core/src/ECS/CoreEvents.ts +++ b/packages/core/src/ECS/CoreEvents.ts @@ -13,14 +13,14 @@ export enum ECSEventType { ENTITY_TAG_ADDED = 'entity:tag:added', ENTITY_TAG_REMOVED = 'entity:tag:removed', ENTITY_NAME_CHANGED = 'entity:name:changed', - + // 组件相关事件 COMPONENT_ADDED = 'component:added', COMPONENT_REMOVED = 'component:removed', COMPONENT_MODIFIED = 'component:modified', COMPONENT_ENABLED = 'component:enabled', COMPONENT_DISABLED = 'component:disabled', - + // 系统相关事件 SYSTEM_ADDED = 'system:added', SYSTEM_REMOVED = 'system:removed', @@ -29,7 +29,7 @@ export enum ECSEventType { SYSTEM_PROCESSING_START = 'system:processing:start', SYSTEM_PROCESSING_END = 'system:processing:end', SYSTEM_ERROR = 'system:error', - + // 场景相关事件 SCENE_CREATED = 'scene:created', SCENE_DESTROYED = 'scene:destroyed', @@ -37,41 +37,41 @@ export enum ECSEventType { SCENE_DEACTIVATED = 'scene:deactivated', SCENE_PAUSED = 'scene:paused', SCENE_RESUMED = 'scene:resumed', - + // 查询相关事件 QUERY_EXECUTED = 'query:executed', QUERY_CACHE_HIT = 'query:cache:hit', QUERY_CACHE_MISS = 'query:cache:miss', QUERY_OPTIMIZED = 'query:optimized', - + // 性能相关事件 PERFORMANCE_WARNING = 'performance:warning', PERFORMANCE_CRITICAL = 'performance:critical', MEMORY_USAGE_HIGH = 'memory:usage:high', FRAME_RATE_DROP = 'frame:rate:drop', - + // 索引相关事件 INDEX_CREATED = 'index:created', INDEX_UPDATED = 'index:updated', INDEX_OPTIMIZED = 'index:optimized', - + // Archetype相关事件 ARCHETYPE_CREATED = 'archetype:created', ARCHETYPE_ENTITY_ADDED = 'archetype:entity:added', ARCHETYPE_ENTITY_REMOVED = 'archetype:entity:removed', - + // 脏标记相关事件 DIRTY_MARK_ADDED = 'dirty:mark:added', DIRTY_BATCH_PROCESSED = 'dirty:batch:processed', - + // 错误和警告事件 ERROR_OCCURRED = 'error:occurred', WARNING_ISSUED = 'warning:issued', - + // 生命周期事件 FRAMEWORK_INITIALIZED = 'framework:initialized', FRAMEWORK_SHUTDOWN = 'framework:shutdown', - + // 调试相关事件 DEBUG_INFO = 'debug:info', DEBUG_STATS_UPDATED = 'debug:stats:updated' @@ -105,7 +105,7 @@ export const EVENT_TYPES = { TAG_REMOVED: ECSEventType.ENTITY_TAG_REMOVED, NAME_CHANGED: ECSEventType.ENTITY_NAME_CHANGED }, - + // 组件事件 COMPONENT: { ADDED: ECSEventType.COMPONENT_ADDED, @@ -114,7 +114,7 @@ export const EVENT_TYPES = { ENABLED: ECSEventType.COMPONENT_ENABLED, DISABLED: ECSEventType.COMPONENT_DISABLED }, - + // 系统事件 SYSTEM: { ADDED: ECSEventType.SYSTEM_ADDED, @@ -125,7 +125,7 @@ export const EVENT_TYPES = { PROCESSING_END: ECSEventType.SYSTEM_PROCESSING_END, ERROR: ECSEventType.SYSTEM_ERROR }, - + // 性能事件 PERFORMANCE: { WARNING: ECSEventType.PERFORMANCE_WARNING, @@ -147,7 +147,7 @@ export class EventTypeValidator { ...Object.values(EVENT_TYPES.SYSTEM), ...Object.values(EVENT_TYPES.PERFORMANCE) ]); - + /** * 验证事件类型是否有效 * @param eventType 事件类型 @@ -156,7 +156,7 @@ export class EventTypeValidator { public static isValid(eventType: string): boolean { return this.validTypes.has(eventType); } - + /** * 获取所有有效的事件类型 * @returns 事件类型数组 @@ -164,7 +164,7 @@ export class EventTypeValidator { public static getAllValidTypes(): string[] { return Array.from(this.validTypes); } - + /** * 添加自定义事件类型 * @param eventType 事件类型 @@ -172,7 +172,7 @@ export class EventTypeValidator { public static addCustomType(eventType: string): void { this.validTypes.add(eventType); } - + /** * 移除自定义事件类型 * @param eventType 事件类型 diff --git a/packages/core/src/ECS/Decorators/TypeDecorators.ts b/packages/core/src/ECS/Decorators/TypeDecorators.ts index 285e37fa..8e59e8e3 100644 --- a/packages/core/src/ECS/Decorators/TypeDecorators.ts +++ b/packages/core/src/ECS/Decorators/TypeDecorators.ts @@ -1,6 +1,6 @@ -import type {Component} from '../Component'; -import type {EntitySystem} from '../Systems'; -import {ComponentType} from "../../Types"; +import type { Component } from '../Component'; +import type { EntitySystem } from '../Systems'; +import { ComponentType } from '../../Types'; /** * 存储组件类型名称的Symbol键 @@ -15,7 +15,7 @@ export const SYSTEM_TYPE_NAME = Symbol('SystemTypeName'); /** * 组件类型装饰器 * 用于为组件类指定固定的类型名称,避免在代码混淆后失效 - * + * * @param typeName 组件类型名称 * @example * ```typescript @@ -31,10 +31,10 @@ export function ECSComponent(typeName: string) { if (!typeName || typeof typeName !== 'string') { throw new Error('ECSComponent装饰器必须提供有效的类型名称'); } - + // 在构造函数上存储类型名称 (target as any)[COMPONENT_TYPE_NAME] = typeName; - + return target; }; } @@ -107,7 +107,7 @@ export function getSystemMetadata(systemType: new (...args: any[]) => EntitySyst /** * 获取组件类型的名称,优先使用装饰器指定的名称 - * + * * @param componentType 组件构造函数 * @returns 组件类型名称 */ @@ -119,14 +119,14 @@ export function getComponentTypeName( if (decoratorName) { return decoratorName; } - + // 回退到constructor.name return componentType.name || 'UnknownComponent'; } /** * 获取系统类型的名称,优先使用装饰器指定的名称 - * + * * @param systemType 系统构造函数 * @returns 系统类型名称 */ @@ -138,14 +138,14 @@ export function getSystemTypeName( if (decoratorName) { return decoratorName; } - + // 回退到constructor.name return systemType.name || 'UnknownSystem'; } /** * 从组件实例获取类型名称 - * + * * @param component 组件实例 * @returns 组件类型名称 */ @@ -155,7 +155,7 @@ export function getComponentInstanceTypeName(component: Component): string { /** * 从系统实例获取类型名称 - * + * * @param system 系统实例 * @returns 系统类型名称 */ diff --git a/packages/core/src/ECS/Decorators/index.ts b/packages/core/src/ECS/Decorators/index.ts index 6ff55d4d..cc7fd03f 100644 --- a/packages/core/src/ECS/Decorators/index.ts +++ b/packages/core/src/ECS/Decorators/index.ts @@ -19,4 +19,4 @@ export { ENTITY_REF_METADATA } from './EntityRefDecorator'; -export type { EntityRefMetadata } from './EntityRefDecorator'; \ No newline at end of file +export type { EntityRefMetadata } from './EntityRefDecorator'; diff --git a/packages/core/src/ECS/IScene.ts b/packages/core/src/ECS/IScene.ts index 42bcec2d..16bb91a0 100644 --- a/packages/core/src/ECS/IScene.ts +++ b/packages/core/src/ECS/IScene.ts @@ -50,12 +50,12 @@ export interface IScene { * 标识符池 */ readonly identifierPool: IdentifierPool; - + /** * 组件存储管理器 */ readonly componentStorageManager: ComponentStorageManager; - + /** * 查询系统 */ @@ -316,4 +316,4 @@ export interface ISceneConfig { * 场景名称 */ name?: string; -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Serialization/ComponentSerializer.ts b/packages/core/src/ECS/Serialization/ComponentSerializer.ts index 777b0c44..6b38a88d 100644 --- a/packages/core/src/ECS/Serialization/ComponentSerializer.ts +++ b/packages/core/src/ECS/Serialization/ComponentSerializer.ts @@ -212,7 +212,7 @@ export class ComponentSerializer { // 数组 if (Array.isArray(value)) { - return value.map(item => this.serializeValue(item)); + return value.map((item) => this.serializeValue(item)); } // Map (如果没有使用@SerializeMap装饰器) @@ -276,7 +276,7 @@ export class ComponentSerializer { // 数组 if (Array.isArray(value)) { - return value.map(item => this.deserializeValue(item)); + return value.map((item) => this.deserializeValue(item)); } // 普通对象 @@ -340,10 +340,10 @@ export class ComponentSerializer { return { type: metadata.options.typeId || getComponentTypeName(componentType), version: metadata.options.version, - fields: Array.from(metadata.fields.keys()).map(k => + fields: Array.from(metadata.fields.keys()).map((k) => typeof k === 'symbol' ? k.toString() : k ), - ignoredFields: Array.from(metadata.ignoredFields).map(k => + ignoredFields: Array.from(metadata.ignoredFields).map((k) => typeof k === 'symbol' ? k.toString() : k ), isSerializable: true diff --git a/packages/core/src/ECS/Serialization/IncrementalSerializer.ts b/packages/core/src/ECS/Serialization/IncrementalSerializer.ts index 6354f8f2..b00d2ef7 100644 --- a/packages/core/src/ECS/Serialization/IncrementalSerializer.ts +++ b/packages/core/src/ECS/Serialization/IncrementalSerializer.ts @@ -696,22 +696,22 @@ export class IncrementalSerializer { componentChanges: incremental.componentChanges.length, sceneDataChanges: incremental.sceneDataChanges.length, addedEntities: incremental.entityChanges.filter( - c => c.operation === ChangeOperation.EntityAdded + (c) => c.operation === ChangeOperation.EntityAdded ).length, removedEntities: incremental.entityChanges.filter( - c => c.operation === ChangeOperation.EntityRemoved + (c) => c.operation === ChangeOperation.EntityRemoved ).length, updatedEntities: incremental.entityChanges.filter( - c => c.operation === ChangeOperation.EntityUpdated + (c) => c.operation === ChangeOperation.EntityUpdated ).length, addedComponents: incremental.componentChanges.filter( - c => c.operation === ChangeOperation.ComponentAdded + (c) => c.operation === ChangeOperation.ComponentAdded ).length, removedComponents: incremental.componentChanges.filter( - c => c.operation === ChangeOperation.ComponentRemoved + (c) => c.operation === ChangeOperation.ComponentRemoved ).length, updatedComponents: incremental.componentChanges.filter( - c => c.operation === ChangeOperation.ComponentUpdated + (c) => c.operation === ChangeOperation.ComponentUpdated ).length }; } diff --git a/packages/core/src/ECS/Serialization/SceneSerializer.ts b/packages/core/src/ECS/Serialization/SceneSerializer.ts index 85bb06b2..608de07f 100644 --- a/packages/core/src/ECS/Serialization/SceneSerializer.ts +++ b/packages/core/src/ECS/Serialization/SceneSerializer.ts @@ -363,7 +363,7 @@ export class SceneSerializer { // 数组 if (Array.isArray(value)) { - return value.map(item => this.serializeValue(item)); + return value.map((item) => this.serializeValue(item)); } // 普通对象 @@ -409,7 +409,7 @@ export class SceneSerializer { // 数组 if (Array.isArray(value)) { - return value.map(item => this.deserializeValue(item)); + return value.map((item) => this.deserializeValue(item)); } // 普通对象 @@ -437,8 +437,8 @@ export class SceneSerializer { const componentTypeSet = new Set(options.components); // 只返回拥有指定组件的实体 - return entities.filter(entity => { - return Array.from(entity.components).some(component => + return entities.filter((entity) => { + return Array.from(entity.components).some((component) => componentTypeSet.has(component.constructor as ComponentType) ); }); diff --git a/packages/core/src/ECS/Serialization/VersionMigration.ts b/packages/core/src/ECS/Serialization/VersionMigration.ts index 171410da..23f666af 100644 --- a/packages/core/src/ECS/Serialization/VersionMigration.ts +++ b/packages/core/src/ECS/Serialization/VersionMigration.ts @@ -127,7 +127,7 @@ export class VersionMigrationManager { return component; } - let migratedData = { ...component }; + const migratedData = { ...component }; let version = currentVersion; // 执行迁移链 @@ -193,12 +193,12 @@ export class VersionMigrationManager { private static migrateSceneComponents(scene: SerializedScene): SerializedScene { const migratedScene = { ...scene }; - migratedScene.entities = scene.entities.map(entity => ({ + migratedScene.entities = scene.entities.map((entity) => ({ ...entity, - components: entity.components.map(component => { + components: entity.components.map((component) => { // 查找组件的目标版本 const typeInfo = scene.componentTypeRegistry.find( - t => t.typeName === component.type + (t) => t.typeName === component.type ); if (typeInfo && typeInfo.version !== component.version) { @@ -220,10 +220,10 @@ export class VersionMigrationManager { entities: any[], typeRegistry: Array<{ typeName: string; version: number }> ): any[] { - return entities.map(entity => ({ + return entities.map((entity) => ({ ...entity, components: entity.components.map((component: SerializedComponent) => { - const typeInfo = typeRegistry.find(t => t.typeName === component.type); + const typeInfo = typeRegistry.find((t) => t.typeName === component.type); if (typeInfo && typeInfo.version !== component.version) { return this.migrateComponent(component, typeInfo.version); diff --git a/packages/core/src/ECS/Systems/EntityCache.ts b/packages/core/src/ECS/Systems/EntityCache.ts index 7b299dc5..9941c3ef 100644 --- a/packages/core/src/ECS/Systems/EntityCache.ts +++ b/packages/core/src/ECS/Systems/EntityCache.ts @@ -154,7 +154,7 @@ export class EntityCache { trackedCount: number; frameEntityCount: number; persistentEntityCount: number; - } { + } { return { hasFrame: this._frameCache !== null, hasPersistent: this._persistentCache !== null, diff --git a/packages/core/src/ECS/Systems/IntervalSystem.ts b/packages/core/src/ECS/Systems/IntervalSystem.ts index 89a6a6a8..c78fd18d 100644 --- a/packages/core/src/ECS/Systems/IntervalSystem.ts +++ b/packages/core/src/ECS/Systems/IntervalSystem.ts @@ -55,4 +55,4 @@ export abstract class IntervalSystem extends EntitySystem { protected getIntervalDelta(): number { return this.interval + this.intervalRemainder; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Systems/PassiveSystem.ts b/packages/core/src/ECS/Systems/PassiveSystem.ts index b937cce0..762db644 100644 --- a/packages/core/src/ECS/Systems/PassiveSystem.ts +++ b/packages/core/src/ECS/Systems/PassiveSystem.ts @@ -8,7 +8,7 @@ import { Matcher } from '../Utils/Matcher'; * 被动的实体系统不会对实体进行任何修改,只会被动地接收实体的变化事件 */ export abstract class PassiveSystem extends EntitySystem { - + constructor(matcher?: Matcher) { super(matcher); } diff --git a/packages/core/src/ECS/Systems/ProcessingSystem.ts b/packages/core/src/ECS/Systems/ProcessingSystem.ts index db5dd627..9b6f7e9f 100644 --- a/packages/core/src/ECS/Systems/ProcessingSystem.ts +++ b/packages/core/src/ECS/Systems/ProcessingSystem.ts @@ -8,7 +8,7 @@ import { Matcher } from '../Utils/Matcher'; * 子类需要实现processSystem方法,用于实现具体的处理逻辑 */ export abstract class ProcessingSystem extends EntitySystem { - + constructor(matcher?: Matcher) { super(matcher); } diff --git a/packages/core/src/ECS/Systems/WorkerEntitySystem.ts b/packages/core/src/ECS/Systems/WorkerEntitySystem.ts index 7c234f74..617ef435 100644 --- a/packages/core/src/ECS/Systems/WorkerEntitySystem.ts +++ b/packages/core/src/ECS/Systems/WorkerEntitySystem.ts @@ -197,7 +197,7 @@ export abstract class WorkerEntitySystem extends EntitySystem protected sharedBuffer: SharedArrayBuffer | null = null; protected sharedFloatArray: Float32Array | null = null; private platformAdapter: IPlatformAdapter; - private hasLoggedSyncMode = false; + private hasLoggedSyncMode = false; constructor(matcher?: Matcher, config: WorkerSystemConfig = {}) { super(matcher); @@ -414,7 +414,7 @@ export abstract class WorkerEntitySystem extends EntitySystem ${sharedProcessFunctionBody} }; userProcessFunction(sharedFloatArray, startIndex, endIndex, deltaTime, systemConfig); - ` : ``} + ` : ''} } `; } @@ -494,7 +494,7 @@ export abstract class WorkerEntitySystem extends EntitySystem const deltaTime = Time.deltaTime; // 3. Worker执行阶段 - const promises = batches.map(batch => + const promises = batches.map((batch) => this.workerPool!.execute({ entities: batch, deltaTime, @@ -525,7 +525,7 @@ export abstract class WorkerEntitySystem extends EntitySystem */ private processSynchronously(entities: readonly Entity[]): void { // 1. 数据提取阶段 - const entityData = entities.map(entity => this.extractEntityData(entity)); + const entityData = entities.map((entity) => this.extractEntityData(entity)); // 2. 主线程处理阶段 const deltaTime = Time.deltaTime; @@ -534,7 +534,7 @@ export abstract class WorkerEntitySystem extends EntitySystem // 3. 结果应用阶段 // 处理Promise返回值 if (results && typeof (results as any).then === 'function') { - (results as Promise).then(finalResults => { + (results as Promise).then((finalResults) => { entities.forEach((entity, index) => { this.applyResult(entity, finalResults[index]!); }); @@ -813,7 +813,7 @@ export abstract class WorkerEntitySystem extends EntitySystem sharedArrayBufferSupported: boolean; sharedArrayBufferEnabled: boolean; currentMode: 'shared-buffer' | 'worker' | 'sync'; - } { + } { let currentMode: 'shared-buffer' | 'worker' | 'sync' = 'sync'; if (this.config.enableWorker && this.workerPool) { diff --git a/packages/core/src/ECS/Systems/index.ts b/packages/core/src/ECS/Systems/index.ts index 0f3cd186..3548a3e3 100644 --- a/packages/core/src/ECS/Systems/index.ts +++ b/packages/core/src/ECS/Systems/index.ts @@ -10,4 +10,4 @@ export type { WorkerProcessFunction, WorkerSystemConfig, SharedArrayBufferProcessFunction -} from './WorkerEntitySystem'; \ No newline at end of file +} from './WorkerEntitySystem'; diff --git a/packages/core/src/ECS/Utils/BigIntCompatibility.ts b/packages/core/src/ECS/Utils/BigIntCompatibility.ts index a7637937..b68e88ef 100644 --- a/packages/core/src/ECS/Utils/BigIntCompatibility.ts +++ b/packages/core/src/ECS/Utils/BigIntCompatibility.ts @@ -69,7 +69,7 @@ export class BitMask64Utils { return maskSegments.some((seg, index) => { const bitsSeg = bitsSegments[index]; return bitsSeg && ((seg[SegmentPart.LOW] & bitsSeg[SegmentPart.LOW]) !== 0 || (seg[SegmentPart.HIGH] & bitsSeg[SegmentPart.HIGH]) !== 0); - }) + }); } /** @@ -145,7 +145,7 @@ export class BitMask64Utils { return baseIsZero; } // 额外检查扩展区域是否都为0 - return mask.segments.every(seg => seg[SegmentPart.LOW] === 0 && seg[SegmentPart.HIGH] === 0); + return mask.segments.every((seg) => seg[SegmentPart.LOW] === 0 && seg[SegmentPart.HIGH] === 0); } /** @@ -155,7 +155,7 @@ export class BitMask64Utils { * @returns 如果两个掩码完全相等则返回true */ public static equals(a: BitMask64Data, b: BitMask64Data): boolean { - let baseEquals = a.base[SegmentPart.LOW] === b.base[SegmentPart.LOW] && a.base[SegmentPart.HIGH] === b.base[SegmentPart.HIGH]; + const baseEquals = a.base[SegmentPart.LOW] === b.base[SegmentPart.LOW] && a.base[SegmentPart.HIGH] === b.base[SegmentPart.HIGH]; // base不相等,或ab都没有扩展区域位,直接返回base比较结果 if(!baseEquals || (!a.segments && !b.segments)) return baseEquals; // 不能假设a,b的segments都存在或长度相同. @@ -355,7 +355,7 @@ export class BitMask64Utils { if(!source.segments || source.segments.length == 0) return; // 没有拓展段,则直接复制数组 if(!target.segments){ - target.segments = source.segments.map(seg => [...seg]); + target.segments = source.segments.map((seg) => [...seg]); return; } // source有扩展段,target扩展段不足,则补充长度 @@ -382,7 +382,7 @@ export class BitMask64Utils { public static clone(mask: BitMask64Data): BitMask64Data { return { base: mask.base.slice() as BitMask64Segment, - ...(mask.segments && { segments: mask.segments.map(seg => [...seg] as BitMask64Segment) }) + ...(mask.segments && { segments: mask.segments.map((seg) => [...seg] as BitMask64Segment) }) }; } @@ -414,8 +414,8 @@ export class BitMask64Utils { for (let i = -1; i < totalLength; i++) { let segResult = ''; const bitMaskData = i == -1 ? mask.base : mask.segments![i]!; - let hi = bitMaskData[SegmentPart.HIGH]; - let lo = bitMaskData[SegmentPart.LOW]; + const hi = bitMaskData[SegmentPart.HIGH]; + const lo = bitMaskData[SegmentPart.LOW]; if(radix == 2){ const hiBits = hi.toString(2).padStart(32, '0'); const loBits = lo.toString(2).padStart(32, '0'); @@ -493,4 +493,4 @@ export class BitMask64Utils { return segments[targetSegIndex] ?? null; } } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Utils/BitMaskHashMap.ts b/packages/core/src/ECS/Utils/BitMaskHashMap.ts index 4848e53c..113a2253 100644 --- a/packages/core/src/ECS/Utils/BitMaskHashMap.ts +++ b/packages/core/src/ECS/Utils/BitMaskHashMap.ts @@ -1,4 +1,4 @@ -import { BitMask64Data } from "./BigIntCompatibility"; +import { BitMask64Data } from './BigIntCompatibility'; // FlatHashMapFast.ts diff --git a/packages/core/src/ECS/Utils/Bits.ts b/packages/core/src/ECS/Utils/Bits.ts index 64bd6408..d030e6a2 100644 --- a/packages/core/src/ECS/Utils/Bits.ts +++ b/packages/core/src/ECS/Utils/Bits.ts @@ -156,10 +156,10 @@ export class Bits { if (maxBits > 64) { maxBits = 64; } - + const result = new Bits(); BitMask64Utils.copy(this._value, result._value); - + if (maxBits <= 32) { const mask = (1 << maxBits) - 1; result._value.base[SegmentPart.LOW] = (~result._value.base[SegmentPart.LOW]) & mask; @@ -174,7 +174,7 @@ export class Bits { result._value.base[SegmentPart.HIGH] = ~result._value.base[SegmentPart.HIGH]; } } - + return result; } @@ -317,7 +317,7 @@ export class Bits { if (BitMask64Utils.isZero(this._value)) { return -1; } - + if (this._value.base[SegmentPart.HIGH] !== 0) { for (let i = 31; i >= 0; i--) { if ((this._value.base[SegmentPart.HIGH] & (1 << i)) !== 0) { @@ -325,13 +325,13 @@ export class Bits { } } } - + for (let i = 31; i >= 0; i--) { if ((this._value.base[SegmentPart.LOW] & (1 << i)) !== 0) { return i; } } - + return -1; } @@ -343,19 +343,19 @@ export class Bits { if (BitMask64Utils.isZero(this._value)) { return -1; } - + for (let i = 0; i < 32; i++) { if ((this._value.base[SegmentPart.LOW] & (1 << i)) !== 0) { return i; } } - + for (let i = 0; i < 32; i++) { if ((this._value.base[SegmentPart.HIGH] & (1 << i)) !== 0) { return i + 32; } } - + return -1; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Utils/ComponentSparseSet.ts b/packages/core/src/ECS/Utils/ComponentSparseSet.ts index c8ac7803..d5c06bb2 100644 --- a/packages/core/src/ECS/Utils/ComponentSparseSet.ts +++ b/packages/core/src/ECS/Utils/ComponentSparseSet.ts @@ -7,14 +7,14 @@ import { IPoolable } from '../../Utils/Pool/IPoolable'; /** * 可池化的实体集合 - * + * * 实现IPoolable接口,支持对象池复用以减少内存分配开销。 */ class PoolableEntitySet extends Set implements IPoolable { constructor(..._args: unknown[]) { super(); } - + reset(): void { this.clear(); } @@ -22,9 +22,9 @@ class PoolableEntitySet extends Set implements IPoolable { /** * 组件稀疏集合实现 - * + * * 结合通用稀疏集合和组件位掩码 - * + * * 存储结构: * - 稀疏集合存储实体 * - 位掩码数组存储组件信息 @@ -33,42 +33,42 @@ class PoolableEntitySet extends Set implements IPoolable { export class ComponentSparseSet { /** * 实体稀疏集合 - * + * * 存储所有拥有组件的实体,提供O(1)的实体操作。 */ private _entities: SparseSet; - + /** * 组件位掩码数组 - * + * * 与实体稀疏集合的密集数组对应,存储每个实体的组件位掩码。 * 数组索引与稀疏集合的密集数组索引一一对应。 */ private _componentMasks: BitMask64Data[] = []; - + /** * 组件类型到实体集合的映射 - * + * * 维护每个组件类型对应的实体集合,用于快速的单组件查询。 */ private _componentToEntities = new Map(); - + /** * 实体集合对象池 - * + * * 使用core库的Pool系统来管理PoolableEntitySet对象的复用。 */ private static _entitySetPool = Pool.getPool(PoolableEntitySet, 50, 512); - + constructor() { this._entities = new SparseSet(); } - + /** * 添加实体到组件索引 - * + * * 分析实体的组件组成,生成位掩码,并更新所有相关索引。 - * + * * @param entity 要添加的实体 */ public addEntity(entity: Entity): void { @@ -76,44 +76,44 @@ export class ComponentSparseSet { if (this._entities.has(entity)) { this.removeEntity(entity); } - - let componentMask = BitMask64Utils.clone(BitMask64Utils.ZERO); + + const componentMask = BitMask64Utils.clone(BitMask64Utils.ZERO); const entityComponents = new Set(); - + // 分析实体组件并构建位掩码 for (const component of entity.components) { const componentType = component.constructor as ComponentType; entityComponents.add(componentType); - + // 确保组件类型已注册 if (!ComponentRegistry.isRegistered(componentType)) { ComponentRegistry.register(componentType); } - + // 获取组件位掩码并合并 const bitMask = ComponentRegistry.getBitMask(componentType); BitMask64Utils.orInPlace(componentMask, bitMask); } - + // 添加实体到稀疏集合 this._entities.add(entity); const entityIndex = this._entities.getIndex(entity)!; - + // 确保位掩码数组有足够空间 while (this._componentMasks.length <= entityIndex) { this._componentMasks.push(BitMask64Utils.clone(BitMask64Utils.ZERO)); } this._componentMasks[entityIndex] = componentMask; - + // 更新组件类型到实体的映射 this.updateComponentMappings(entity, entityComponents, true); } - + /** * 从组件索引中移除实体 - * + * * 清理实体相关的所有索引数据,保持数据结构的紧凑性。 - * + * * @param entity 要移除的实体 */ public removeEntity(entity: Entity): void { @@ -121,16 +121,16 @@ export class ComponentSparseSet { if (entityIndex === undefined) { return; // 实体不存在 } - + // 获取实体的组件类型集合 const entityComponents = this.getEntityComponentTypes(entity); - + // 更新组件类型到实体的映射 this.updateComponentMappings(entity, entityComponents, false); - + // 从稀疏集合中移除实体 this._entities.remove(entity); - + // 维护位掩码数组的紧凑性 const lastIndex = this._componentMasks.length - 1; if (entityIndex !== lastIndex) { @@ -139,10 +139,10 @@ export class ComponentSparseSet { } this._componentMasks.pop(); } - + /** * 查询包含指定组件的所有实体 - * + * * @param componentType 组件类型 * @returns 包含该组件的实体集合 */ @@ -150,12 +150,12 @@ export class ComponentSparseSet { const entities = this._componentToEntities.get(componentType); return entities ? new Set(entities) : new Set(); } - + /** * 多组件查询(AND操作) - * + * * 查找同时包含所有指定组件的实体。 - * + * * @param componentTypes 组件类型数组 * @returns 满足条件的实体集合 */ @@ -163,13 +163,13 @@ export class ComponentSparseSet { if (componentTypes.length === 0) { return new Set(); } - + if (componentTypes.length === 1) { return this.queryByComponent(componentTypes[0]!); } - + // 构建目标位掩码 - let targetMask = BitMask64Utils.clone(BitMask64Utils.ZERO); + const targetMask = BitMask64Utils.clone(BitMask64Utils.ZERO); for (const componentType of componentTypes) { if (!ComponentRegistry.isRegistered(componentType)) { return new Set(); // 未注册的组件类型,结果为空 @@ -177,9 +177,9 @@ export class ComponentSparseSet { const bitMask = ComponentRegistry.getBitMask(componentType); BitMask64Utils.orInPlace(targetMask, bitMask); } - + const result = ComponentSparseSet._entitySetPool.obtain(); - + // 遍历所有实体,检查位掩码匹配 this._entities.forEach((entity, index) => { const entityMask = this._componentMasks[index]!; @@ -187,15 +187,15 @@ export class ComponentSparseSet { result.add(entity); } }); - + return result; } - + /** * 多组件查询(OR操作) - * + * * 查找包含任意一个指定组件的实体。 - * + * * @param componentTypes 组件类型数组 * @returns 满足条件的实体集合 */ @@ -203,26 +203,26 @@ export class ComponentSparseSet { if (componentTypes.length === 0) { return new Set(); } - + if (componentTypes.length === 1) { return this.queryByComponent(componentTypes[0]!); } - + // 构建目标位掩码 - let targetMask = BitMask64Utils.clone(BitMask64Utils.ZERO); + const targetMask = BitMask64Utils.clone(BitMask64Utils.ZERO); for (const componentType of componentTypes) { if (ComponentRegistry.isRegistered(componentType)) { const bitMask = ComponentRegistry.getBitMask(componentType); BitMask64Utils.orInPlace(targetMask, bitMask); } } - + if (BitMask64Utils.equals(targetMask, BitMask64Utils.ZERO)) { return new Set(); // 没有有效的组件类型 } - + const result = ComponentSparseSet._entitySetPool.obtain(); - + // 遍历所有实体,检查位掩码匹配 this._entities.forEach((entity, index) => { const entityMask = this._componentMasks[index]!; @@ -230,13 +230,13 @@ export class ComponentSparseSet { result.add(entity); } }); - + return result; } - + /** * 检查实体是否包含指定组件 - * + * * @param entity 实体 * @param componentType 组件类型 * @returns 是否包含该组件 @@ -246,20 +246,20 @@ export class ComponentSparseSet { if (entityIndex === undefined) { return false; } - + if (!ComponentRegistry.isRegistered(componentType)) { return false; } - + const entityMask = this._componentMasks[entityIndex]!; const componentMask = ComponentRegistry.getBitMask(componentType); return BitMask64Utils.hasAny(entityMask, componentMask); } - + /** * 获取实体的组件位掩码 - * + * * @param entity 实体 * @returns 组件位掩码,如果实体不存在则返回undefined */ @@ -270,33 +270,33 @@ export class ComponentSparseSet { } return this._componentMasks[entityIndex]; } - + /** * 获取所有实体 - * + * * @returns 所有实体的数组 */ public getAllEntities(): Entity[] { return this._entities.toArray(); } - + /** * 获取实体数量 */ public get size(): number { return this._entities.size; } - + /** * 检查是否为空 */ public get isEmpty(): boolean { return this._entities.isEmpty; } - + /** * 遍历所有实体 - * + * * @param callback 遍历回调函数 */ public forEach(callback: (entity: Entity, mask: BitMask64Data, index: number) => void): void { @@ -304,21 +304,21 @@ export class ComponentSparseSet { callback(entity, this._componentMasks[index]!, index); }); } - + /** * 清空所有数据 */ public clear(): void { this._entities.clear(); this._componentMasks.length = 0; - + // 清理时将所有持有的实体集合返回到池中 for (const entitySet of this._componentToEntities.values()) { ComponentSparseSet._entitySetPool.release(entitySet); } this._componentToEntities.clear(); } - + /** * 获取内存使用统计 */ @@ -327,15 +327,15 @@ export class ComponentSparseSet { masksMemory: number; mappingsMemory: number; totalMemory: number; - } { + } { const entitiesStats = this._entities.getMemoryStats(); const masksMemory = this._componentMasks.length * 16; // 估计每个BigInt 16字节 - + let mappingsMemory = this._componentToEntities.size * 16; // Map条目开销 for (const entitySet of this._componentToEntities.values()) { mappingsMemory += entitySet.size * 8; // 每个实体引用8字节 } - + return { entitiesMemory: entitiesStats.totalMemory, masksMemory, @@ -343,7 +343,7 @@ export class ComponentSparseSet { totalMemory: entitiesStats.totalMemory + masksMemory + mappingsMemory }; } - + /** * 验证数据结构完整性 */ @@ -352,12 +352,12 @@ export class ComponentSparseSet { if (!this._entities.validate()) { return false; } - + // 检查位掩码数组长度一致性 if (this._componentMasks.length !== this._entities.size) { return false; } - + // 检查组件映射的一致性 const allMappedEntities = new Set(); for (const entitySet of this._componentToEntities.values()) { @@ -365,17 +365,17 @@ export class ComponentSparseSet { allMappedEntities.add(entity); } } - + // 验证映射中的实体都在稀疏集合中 for (const entity of allMappedEntities) { if (!this._entities.has(entity)) { return false; } } - + return true; } - + /** * 获取实体的组件类型集合 */ @@ -386,18 +386,18 @@ export class ComponentSparseSet { } return componentTypes; } - + /** * 更新组件类型到实体的映射 */ private updateComponentMappings( - entity: Entity, - componentTypes: Set, + entity: Entity, + componentTypes: Set, add: boolean ): void { for (const componentType of componentTypes) { let entities = this._componentToEntities.get(componentType); - + if (add) { if (!entities) { entities = ComponentSparseSet._entitySetPool.obtain(); @@ -415,5 +415,5 @@ export class ComponentSparseSet { } } } - -} \ No newline at end of file + +} diff --git a/packages/core/src/ECS/Utils/EntityList.ts b/packages/core/src/ECS/Utils/EntityList.ts index 11e60661..a7f0938a 100644 --- a/packages/core/src/ECS/Utils/EntityList.ts +++ b/packages/core/src/ECS/Utils/EntityList.ts @@ -45,7 +45,7 @@ export class EntityList { this.buffer.push(entity); this._idToEntity.set(entity.id, entity); - + // 更新名称索引 this.updateNameIndex(entity, true); } @@ -67,10 +67,10 @@ export class EntityList { if (index !== -1) { this.buffer.splice(index, 1); this._idToEntity.delete(entity.id); - + // 更新名称索引 this.updateNameIndex(entity, false); - + // 回收实体ID到ID池 if (this._scene && this._scene.identifierPool) { this._scene.identifierPool.checkIn(entity.id); @@ -84,19 +84,19 @@ export class EntityList { public removeAllEntities(): void { // 收集所有实体ID用于回收 const idsToRecycle: number[] = []; - + for (let i = this.buffer.length - 1; i >= 0; i--) { idsToRecycle.push(this.buffer[i]!.id); this.buffer[i]!.destroy(); } - + // 批量回收ID if (this._scene && this._scene.identifierPool) { for (const id of idsToRecycle) { this._scene.identifierPool.checkIn(id); } } - + this.buffer.length = 0; this._idToEntity.clear(); this._nameToEntities.clear(); @@ -170,13 +170,13 @@ export class EntityList { */ public findEntitiesByTag(tag: number): Entity[] { const result: Entity[] = []; - + for (const entity of this.buffer) { if (entity.tag === tag) { result.push(entity); } } - + return result; } @@ -187,13 +187,13 @@ export class EntityList { */ public findEntitiesWithComponent(componentType: new (...args: any[]) => T): Entity[] { const result: Entity[] = []; - + for (const entity of this.buffer) { if (entity.hasComponent(componentType)) { result.push(entity); } } - + return result; } @@ -243,7 +243,7 @@ export class EntityList { const index = entities.indexOf(entity); if (index !== -1) { entities.splice(index, 1); - + // 如果数组为空,删除映射 if (entities.length === 0) { this._nameToEntities.delete(entity.name); @@ -263,7 +263,7 @@ export class EntityList { pendingAdd: number; pendingRemove: number; nameIndexSize: number; - } { + } { let activeCount = 0; for (const entity of this.buffer) { if (entity.enabled && !entity.isDestroyed) { diff --git a/packages/core/src/ECS/Utils/EntityProcessorList.ts b/packages/core/src/ECS/Utils/EntityProcessorList.ts index da5d4c9b..cdf8a05d 100644 --- a/packages/core/src/ECS/Utils/EntityProcessorList.ts +++ b/packages/core/src/ECS/Utils/EntityProcessorList.ts @@ -53,7 +53,7 @@ export class EntityProcessorList { /** * 开始处理 - * + * * 对所有处理器进行排序以确保正确的执行顺序。 */ public begin(): void { diff --git a/packages/core/src/ECS/Utils/IdentifierPool.ts b/packages/core/src/ECS/Utils/IdentifierPool.ts index dcb6cc7e..f991e854 100644 --- a/packages/core/src/ECS/Utils/IdentifierPool.ts +++ b/packages/core/src/ECS/Utils/IdentifierPool.ts @@ -1,22 +1,22 @@ /** * 世代式ID池管理器 - * + * * 用于管理实体ID的分配和回收,支持世代版本控制以防止悬空引用问题。 * 世代式ID由索引和版本组成,当ID被回收时版本会递增,确保旧引用失效。 - * + * * 支持动态扩展,理论上可以支持到65535个索引(16位),每个索引65535个版本(16位)。 * 总计可以处理超过42亿个独特的ID组合,完全满足ECS大规模实体需求。 - * + * * @example * ```typescript * const pool = new IdentifierPool(); - * + * * // 分配ID * const id = pool.checkOut(); // 例如: 65536 (版本1,索引0) - * + * * // 回收ID * pool.checkIn(id); - * + * * // 验证ID是否有效 * const isValid = pool.isValid(id); // false,因为版本已递增 * ``` @@ -26,18 +26,18 @@ export class IdentifierPool { * 下一个可用的索引 */ private _nextAvailableIndex = 0; - + /** * 空闲的索引列表 */ private _freeIndices: number[] = []; - + /** * 每个索引对应的世代版本 * 动态扩展的Map,按需分配内存 */ private _generations = new Map(); - + /** * 延迟回收队列 * 防止在同一帧内立即重用ID,避免时序问题 @@ -47,30 +47,30 @@ export class IdentifierPool { generation: number; timestamp: number; }> = []; - + /** * 延迟回收时间(毫秒) */ private _recycleDelay: number = 100; - + /** * 最大索引限制(16位) * 这是框架设计选择:16位索引 + 16位版本 = 32位ID,确保高效位操作 * 不是硬件限制,而是性能和内存效率的权衡 */ private static readonly MAX_INDEX = 0xFFFF; // 65535 - + /** * 最大世代限制(16位) */ private static readonly MAX_GENERATION = 0xFFFF; // 65535 - + /** * 内存扩展块大小 * 当需要更多内存时,一次性预分配的索引数量 */ private _expansionBlockSize: number; - + /** * 统计信息 */ @@ -83,32 +83,32 @@ export class IdentifierPool { /** * 构造函数 - * + * * @param recycleDelay 延迟回收时间(毫秒),默认为100ms * @param expansionBlockSize 内存扩展块大小,默认为1024 */ constructor(recycleDelay: number = 100, expansionBlockSize: number = 1024) { this._recycleDelay = recycleDelay; this._expansionBlockSize = expansionBlockSize; - + // 预分配第一个块的世代信息 this._preAllocateGenerations(0, this._expansionBlockSize); } /** * 获取一个可用的ID - * + * * 返回一个32位ID,高16位为世代版本,低16位为索引。 - * + * * @returns 新分配的实体ID * @throws {Error} 当达到索引限制时抛出错误 */ public checkOut(): number { // 处理延迟回收队列 this._processDelayedRecycle(); - + let index: number; - + if (this._freeIndices.length > 0) { // 重用回收的索引 index = this._freeIndices.pop()!; @@ -117,69 +117,69 @@ export class IdentifierPool { if (this._nextAvailableIndex > IdentifierPool.MAX_INDEX) { throw new Error( `实体索引已达到框架设计限制 (${IdentifierPool.MAX_INDEX})。` + - `这意味着您已经分配了超过65535个不同的实体索引。` + - `这是16位索引设计的限制,考虑优化实体回收策略或升级到64位ID设计。` + '这意味着您已经分配了超过65535个不同的实体索引。' + + '这是16位索引设计的限制,考虑优化实体回收策略或升级到64位ID设计。' ); } - + index = this._nextAvailableIndex++; - + // 按需扩展世代存储 this._ensureGenerationCapacity(index); } - + const generation = this._generations.get(index) || 1; this._stats.totalAllocated++; this._stats.currentActive++; - + return this._packId(index, generation); } /** * 回收一个ID - * + * * 验证ID的有效性后,将其加入延迟回收队列。 * ID不会立即可重用,而是在延迟时间后才真正回收。 - * + * * @param id 要回收的实体ID * @returns 是否成功回收(ID是否有效且未被重复回收) */ public checkIn(id: number): boolean { const index = this._unpackIndex(id); const generation = this._unpackGeneration(id); - + // 验证ID有效性 if (!this._isValidId(index, generation)) { return false; } - + // 检查是否已经在待回收队列中 const alreadyPending = this._pendingRecycle.some( - item => item.index === index && item.generation === generation + (item) => item.index === index && item.generation === generation ); - + if (alreadyPending) { return false; // 已经在回收队列中,拒绝重复回收 } - + // 加入延迟回收队列 this._pendingRecycle.push({ index, generation, timestamp: Date.now() }); - + this._stats.currentActive--; this._stats.totalRecycled++; - + return true; } /** * 验证ID是否有效 - * + * * 检查ID的索引和世代版本是否匹配当前状态。 - * + * * @param id 要验证的实体ID * @returns ID是否有效 */ @@ -191,7 +191,7 @@ export class IdentifierPool { /** * 获取统计信息 - * + * * @returns 池的当前状态统计 */ public getStats(): { @@ -217,20 +217,20 @@ export class IdentifierPool { averageGeneration: number; /** 世代存储大小 */ generationStorageSize: number; - } { + } { // 计算平均世代版本 let totalGeneration = 0; let generationCount = 0; - + for (const [index, generation] of this._generations) { if (index < this._nextAvailableIndex) { totalGeneration += generation; generationCount++; } } - - const averageGeneration = generationCount > 0 - ? totalGeneration / generationCount + + const averageGeneration = generationCount > 0 + ? totalGeneration / generationCount : 1; return { @@ -250,7 +250,7 @@ export class IdentifierPool { /** * 强制执行延迟回收处理 - * + * * 在某些情况下可能需要立即处理延迟回收队列, * 比如内存压力大或者需要精确的统计信息时。 */ @@ -260,19 +260,19 @@ export class IdentifierPool { /** * 清理过期的延迟回收项 - * + * * 将超过延迟时间的回收项真正回收到空闲列表中。 - * + * * @param forceAll 是否强制处理所有延迟回收项 * @private */ private _processDelayedRecycle(forceAll: boolean = false): void { if (this._pendingRecycle.length === 0) return; - + const now = Date.now(); const readyToRecycle: typeof this._pendingRecycle = []; const stillPending: typeof this._pendingRecycle = []; - + // 分离已到期和未到期的项 for (const item of this._pendingRecycle) { if (forceAll || now - item.timestamp >= this._recycleDelay) { @@ -281,33 +281,33 @@ export class IdentifierPool { stillPending.push(item); } } - + // 处理到期的回收项 for (const item of readyToRecycle) { // 再次验证ID有效性(防止重复回收) if (this._isValidId(item.index, item.generation)) { // 递增世代版本 let newGeneration = item.generation + 1; - + // 防止世代版本溢出 if (newGeneration > IdentifierPool.MAX_GENERATION) { newGeneration = 1; // 重置为1而不是0 } - + this._generations.set(item.index, newGeneration); - + // 添加到空闲列表 this._freeIndices.push(item.index); } } - + // 更新待回收队列 this._pendingRecycle = stillPending; } /** * 预分配世代信息 - * + * * @param startIndex 起始索引 * @param count 分配数量 * @private @@ -324,7 +324,7 @@ export class IdentifierPool { /** * 确保指定索引的世代信息存在 - * + * * @param index 索引 * @private */ @@ -332,7 +332,7 @@ export class IdentifierPool { if (!this._generations.has(index)) { // 计算需要扩展的起始位置 const expansionStart = Math.floor(index / this._expansionBlockSize) * this._expansionBlockSize; - + // 预分配一个块 this._preAllocateGenerations(expansionStart, this._expansionBlockSize); } @@ -340,7 +340,7 @@ export class IdentifierPool { /** * 计算内存使用量 - * + * * @returns 内存使用字节数 * @private */ @@ -348,13 +348,13 @@ export class IdentifierPool { const generationMapSize = this._generations.size * 16; // Map overhead + number pair const freeIndicesSize = this._freeIndices.length * 8; const pendingRecycleSize = this._pendingRecycle.length * 32; - + return generationMapSize + freeIndicesSize + pendingRecycleSize; } /** * 打包索引和世代为32位ID - * + * * @param index 索引(16位) * @param generation 世代版本(16位) * @returns 打包后的32位ID @@ -366,7 +366,7 @@ export class IdentifierPool { /** * 从ID中解包索引 - * + * * @param id 32位ID * @returns 索引部分(16位) * @private @@ -377,7 +377,7 @@ export class IdentifierPool { /** * 从ID中解包世代版本 - * + * * @param id 32位ID * @returns 世代版本部分(16位) * @private @@ -388,7 +388,7 @@ export class IdentifierPool { /** * 内部ID有效性检查 - * + * * @param index 索引 * @param generation 世代版本 * @returns 是否有效 @@ -398,8 +398,8 @@ export class IdentifierPool { if (index < 0 || index >= this._nextAvailableIndex) { return false; } - + const currentGeneration = this._generations.get(index); return currentGeneration !== undefined && currentGeneration === generation; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Utils/Matcher.ts b/packages/core/src/ECS/Utils/Matcher.ts index 4dbea402..31e97580 100644 --- a/packages/core/src/ECS/Utils/Matcher.ts +++ b/packages/core/src/ECS/Utils/Matcher.ts @@ -15,15 +15,15 @@ export interface QueryCondition { /** * 实体匹配条件描述符 - * + * * 用于描述实体查询条件,不执行实际查询 - * + * * @example * ```typescript * const matcher = Matcher.all(Position, Velocity) * .any(Health, Shield) * .none(Dead); - * + * * // 获取查询条件 * const condition = matcher.getCondition(); * ``` @@ -219,8 +219,8 @@ export class Matcher { * 检查是否为空条件 */ public isEmpty(): boolean { - return this.condition.all.length === 0 && - this.condition.any.length === 0 && + return this.condition.all.length === 0 && + this.condition.any.length === 0 && this.condition.none.length === 0 && this.condition.tag === undefined && this.condition.name === undefined && @@ -265,32 +265,32 @@ export class Matcher { */ public toString(): string { const parts: string[] = []; - + if (this.condition.all.length > 0) { - parts.push(`all(${this.condition.all.map(t => getComponentTypeName(t)).join(', ')})`); + parts.push(`all(${this.condition.all.map((t) => getComponentTypeName(t)).join(', ')})`); } - + if (this.condition.any.length > 0) { - parts.push(`any(${this.condition.any.map(t => getComponentTypeName(t)).join(', ')})`); + parts.push(`any(${this.condition.any.map((t) => getComponentTypeName(t)).join(', ')})`); } - + if (this.condition.none.length > 0) { - parts.push(`none(${this.condition.none.map(t => getComponentTypeName(t)).join(', ')})`); + parts.push(`none(${this.condition.none.map((t) => getComponentTypeName(t)).join(', ')})`); } - + if (this.condition.tag !== undefined) { parts.push(`tag(${this.condition.tag})`); } - + if (this.condition.name !== undefined) { parts.push(`name(${this.condition.name})`); } - + if (this.condition.component !== undefined) { parts.push(`component(${getComponentTypeName(this.condition.component)})`); } - + return `Matcher[${parts.join(' & ')}]`; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Utils/SparseSet.ts b/packages/core/src/ECS/Utils/SparseSet.ts index 83505a2c..273e74aa 100644 --- a/packages/core/src/ECS/Utils/SparseSet.ts +++ b/packages/core/src/ECS/Utils/SparseSet.ts @@ -1,22 +1,22 @@ /** * 稀疏集合实现 - * + * * 提供O(1)的插入、删除、查找操作,同时保持数据的紧凑存储。 * 使用密集数组存储实际数据,稀疏映射提供快速访问 - * + * * @template T 存储的数据类型 - * + * * @example * ```typescript * const sparseSet = new SparseSet(); - * + * * sparseSet.add(entity1); * sparseSet.add(entity2); - * + * * if (sparseSet.has(entity1)) { * sparseSet.remove(entity1); * } - * + * * sparseSet.forEach((entity, index) => { * console.log(`Entity at index ${index}: ${entity.name}`); * }); @@ -25,21 +25,21 @@ export class SparseSet { /** * 密集存储数组 - * + * * 连续存储所有有效数据,确保遍历时的缓存友好性。 */ private _dense: T[] = []; - + /** * 稀疏映射表 - * + * * 将数据项映射到密集数组中的索引,提供O(1)的查找性能。 */ private _sparse = new Map(); - + /** * 添加元素到集合 - * + * * @param item 要添加的元素 * @returns 是否成功添加(false表示元素已存在) */ @@ -47,21 +47,21 @@ export class SparseSet { if (this._sparse.has(item)) { return false; // 元素已存在 } - + const index = this._dense.length; this._dense.push(item); this._sparse.set(item, index); return true; } - + /** * 从集合中移除元素 - * + * * 使用swap-and-pop技术保持数组紧凑性: * 1. 将要删除的元素与最后一个元素交换 * 2. 删除最后一个元素 * 3. 更新映射表 - * + * * @param item 要移除的元素 * @returns 是否成功移除(false表示元素不存在) */ @@ -70,72 +70,72 @@ export class SparseSet { if (index === undefined) { return false; // 元素不存在 } - + const lastIndex = this._dense.length - 1; - + // 如果不是最后一个元素,则与最后一个元素交换 if (index !== lastIndex) { const lastItem = this._dense[lastIndex]!; this._dense[index] = lastItem; this._sparse.set(lastItem, index); } - + // 移除最后一个元素 this._dense.pop(); this._sparse.delete(item); return true; } - + /** * 检查元素是否存在于集合中 - * + * * @param item 要检查的元素 * @returns 元素是否存在 */ public has(item: T): boolean { return this._sparse.has(item); } - + /** * 获取元素在密集数组中的索引 - * + * * @param item 要查询的元素 * @returns 索引,如果元素不存在则返回undefined */ public getIndex(item: T): number | undefined { return this._sparse.get(item); } - + /** * 根据索引获取元素 - * + * * @param index 索引 * @returns 元素,如果索引无效则返回undefined */ public getByIndex(index: number): T | undefined { return this._dense[index]; } - + /** * 获取集合大小 */ public get size(): number { return this._dense.length; } - + /** * 检查集合是否为空 */ public get isEmpty(): boolean { return this._dense.length === 0; } - + /** * 遍历集合中的所有元素 - * + * * 保证遍历顺序与添加顺序一致(除非中间有删除操作)。 * 遍历性能优秀,因为数据在内存中连续存储。 - * + * * @param callback 遍历回调函数 */ public forEach(callback: (item: T, index: number) => void): void { @@ -143,10 +143,10 @@ export class SparseSet { callback(this._dense[i]!, i); } } - + /** * 映射集合中的所有元素 - * + * * @param callback 映射回调函数 * @returns 映射后的新数组 */ @@ -157,10 +157,10 @@ export class SparseSet { } return result; } - + /** * 过滤集合中的元素 - * + * * @param predicate 过滤条件 * @returns 满足条件的元素数组 */ @@ -173,10 +173,10 @@ export class SparseSet { } return result; } - + /** * 查找第一个满足条件的元素 - * + * * @param predicate 查找条件 * @returns 找到的元素,如果没有则返回undefined */ @@ -188,10 +188,10 @@ export class SparseSet { } return undefined; } - + /** * 检查是否存在满足条件的元素 - * + * * @param predicate 检查条件 * @returns 是否存在满足条件的元素 */ @@ -203,10 +203,10 @@ export class SparseSet { } return false; } - + /** * 检查是否所有元素都满足条件 - * + * * @param predicate 检查条件 * @returns 是否所有元素都满足条件 */ @@ -218,26 +218,26 @@ export class SparseSet { } return true; } - + /** * 获取密集数组的只读副本 - * + * * 返回数组的浅拷贝,确保外部无法直接修改内部数据。 */ public getDenseArray(): readonly T[] { return [...this._dense]; } - + /** * 获取密集数组的直接引用(内部使用) - * + * * 警告:直接修改返回的数组会破坏数据结构的完整性。 * 仅在性能关键场景下使用,并确保不会修改数组内容。 */ public getDenseArrayUnsafe(): readonly T[] { return this._dense; } - + /** * 清空集合 */ @@ -245,21 +245,21 @@ export class SparseSet { this._dense.length = 0; this._sparse.clear(); } - + /** * 转换为数组 */ public toArray(): T[] { return [...this._dense]; } - + /** * 转换为Set */ public toSet(): Set { return new Set(this._dense); } - + /** * 获取内存使用统计信息 */ @@ -267,20 +267,20 @@ export class SparseSet { denseArraySize: number; sparseMapSize: number; totalMemory: number; - } { + } { const denseArraySize = this._dense.length * 8; // 估计每个引用8字节 const sparseMapSize = this._sparse.size * 16; // 估计每个Map条目16字节 - + return { denseArraySize, sparseMapSize, totalMemory: denseArraySize + sparseMapSize }; } - + /** * 验证数据结构的完整性 - * + * * 调试用方法,检查内部数据结构是否一致。 */ public validate(): boolean { @@ -288,7 +288,7 @@ export class SparseSet { if (this._dense.length !== this._sparse.size) { return false; } - + // 检查映射关系的正确性 for (let i = 0; i < this._dense.length; i++) { const item = this._dense[i]!; @@ -297,14 +297,14 @@ export class SparseSet { return false; } } - + // 检查稀疏映射中的所有项都在密集数组中 for (const [item, index] of this._sparse) { if (index >= this._dense.length || this._dense[index] !== item) { return false; } } - + return true; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Utils/index.ts b/packages/core/src/ECS/Utils/index.ts index 3aa716b5..cf2feef7 100644 --- a/packages/core/src/ECS/Utils/index.ts +++ b/packages/core/src/ECS/Utils/index.ts @@ -6,4 +6,4 @@ export { Matcher } from './Matcher'; export { Bits } from './Bits'; export { BitMask64Utils, BitMask64Data } from './BigIntCompatibility'; export { SparseSet } from './SparseSet'; -export { ComponentSparseSet } from './ComponentSparseSet'; \ No newline at end of file +export { ComponentSparseSet } from './ComponentSparseSet'; diff --git a/packages/core/src/ECS/World.ts b/packages/core/src/ECS/World.ts index 6e018f29..60f57881 100644 --- a/packages/core/src/ECS/World.ts +++ b/packages/core/src/ECS/World.ts @@ -13,22 +13,22 @@ export interface IGlobalSystem { * 系统名称 */ readonly name: string; - + /** * 初始化系统 */ initialize?(): void; - + /** * 更新系统 */ update(deltaTime?: number): void; - + /** * 重置系统 */ reset?(): void; - + /** * 销毁系统 */ @@ -43,17 +43,17 @@ export interface IWorldConfig { * World名称 */ name?: string; - + /** * 是否启用调试模式 */ debug?: boolean; - + /** * 最大Scene数量限制 */ maxScenes?: number; - + /** * 是否自动清理空Scene */ @@ -62,22 +62,22 @@ export interface IWorldConfig { /** * World类 - ECS世界管理器 - * + * * World是Scene的容器,每个World可以管理多个Scene。 * 这种设计允许创建独立的游戏世界,如: * - 游戏房间(每个房间一个World) * - 不同的游戏模式 * - 独立的模拟环境 - * + * * @example * ```typescript * // 创建游戏房间的World * const roomWorld = new World({ name: 'Room_001' }); - * + * * // 在World中创建Scene * const gameScene = roomWorld.createScene('game', new Scene()); * const uiScene = roomWorld.createScene('ui', new Scene()); - * + * * // 更新整个World * roomWorld.update(deltaTime); * ``` @@ -99,7 +99,7 @@ export class World { autoCleanup: true, ...config }; - + this.name = this._config.name!; this._createdAt = Date.now(); } @@ -120,7 +120,7 @@ export class World { // 如果没有提供Scene实例,创建默认Scene const scene = sceneInstance || (new Scene() as unknown as T); - + // 设置Scene的标识 if ('id' in scene) { (scene as any).id = sceneId; @@ -154,7 +154,7 @@ export class World { // 清理Scene资源 scene.end(); this._scenes.delete(sceneId); - + logger.info(`从World '${this.name}' 中移除Scene: ${sceneId}`); return true; } @@ -244,7 +244,7 @@ export class World { if (system.initialize) { system.initialize(); } - + logger.debug(`在World '${this.name}' 中添加全局System: ${system.name}`); return system; } @@ -262,7 +262,7 @@ export class World { if (system.reset) { system.reset(); } - + logger.debug(`从World '${this.name}' 中移除全局System: ${system.name}`); return true; } @@ -290,14 +290,14 @@ export class World { } this._isActive = true; - + // 启动所有全局System for (const system of this._globalSystems) { if (system.initialize) { system.initialize(); } } - + logger.info(`启动World: ${this.name}`); } @@ -408,7 +408,7 @@ export class World { globalSystemCount: this._globalSystems.length, createdAt: this._createdAt, config: { ...this._config }, - scenes: Array.from(this._scenes.keys()).map(sceneId => ({ + scenes: Array.from(this._scenes.keys()).map((sceneId) => ({ id: sceneId, isActive: this._activeScenes.has(sceneId), name: this._scenes.get(sceneId)?.name || sceneId @@ -454,8 +454,8 @@ export class World { const cleanupThreshold = 5 * 60 * 1000; // 5分钟 for (const [sceneId, scene] of this._scenes) { - if (!this._activeScenes.has(sceneId) && - scene.entities && + if (!this._activeScenes.has(sceneId) && + scene.entities && scene.entities.count === 0 && (currentTime - this._createdAt) > cleanupThreshold) { return true; @@ -472,15 +472,15 @@ export class World { const sceneIds = Array.from(this._scenes.keys()); const currentTime = Date.now(); const cleanupThreshold = 5 * 60 * 1000; // 5分钟 - + for (const sceneId of sceneIds) { const scene = this._scenes.get(sceneId); - if (scene && - !this._activeScenes.has(sceneId) && - scene.entities && + if (scene && + !this._activeScenes.has(sceneId) && + scene.entities && scene.entities.count === 0 && (currentTime - this._createdAt) > cleanupThreshold) { - + this.removeScene(sceneId); logger.debug(`自动清理空Scene: ${sceneId} from World ${this.name}`); } @@ -509,4 +509,4 @@ export class World { public get createdAt(): number { return this._createdAt; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/WorldManager.ts b/packages/core/src/ECS/WorldManager.ts index 8ae14007..d4930ad0 100644 --- a/packages/core/src/ECS/WorldManager.ts +++ b/packages/core/src/ECS/WorldManager.ts @@ -12,17 +12,17 @@ export interface IWorldManagerConfig { * 最大World数量 */ maxWorlds?: number; - + /** * 是否自动清理空World */ autoCleanup?: boolean; - + /** * 清理间隔(毫秒) */ cleanupInterval?: number; - + /** * 是否启用调试模式 */ @@ -242,11 +242,11 @@ export class WorldManager implements IService { */ public startAll(): void { this._isRunning = true; - + for (const worldId of this._worlds.keys()) { this.setWorldActive(worldId, true); } - + logger.info('启动所有World'); } @@ -255,11 +255,11 @@ export class WorldManager implements IService { */ public stopAll(): void { this._isRunning = false; - + for (const worldId of this._activeWorlds) { this.setWorldActive(worldId, false); } - + logger.info('停止所有World'); } @@ -432,7 +432,7 @@ export class WorldManager implements IService { // 1. World未激活 // 2. 没有Scene或所有Scene都是空的 // 3. 创建时间超过10分钟 - + if (world.isActive) { return false; } @@ -444,7 +444,7 @@ export class WorldManager implements IService { // 检查是否所有Scene都是空的 const allScenes = world.getAllScenes(); - const hasEntities = allScenes.some(scene => + const hasEntities = allScenes.some((scene) => scene.entities && scene.entities.count > 0 ); @@ -485,4 +485,4 @@ export class WorldManager implements IService { public get config(): IWorldManagerConfig { return { ...this._config }; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/index.ts b/packages/core/src/ECS/index.ts index e0c66e28..4c37f576 100644 --- a/packages/core/src/ECS/index.ts +++ b/packages/core/src/ECS/index.ts @@ -17,4 +17,4 @@ export * from './Serialization'; export { ReferenceTracker, getSceneByEntityId } from './Core/ReferenceTracker'; export type { EntityRefRecord } from './Core/ReferenceTracker'; export { ReactiveQuery, ReactiveQueryChangeType } from './Core/ReactiveQuery'; -export type { ReactiveQueryChange, ReactiveQueryListener, ReactiveQueryConfig } from './Core/ReactiveQuery'; \ No newline at end of file +export type { ReactiveQueryChange, ReactiveQueryListener, ReactiveQueryConfig } from './Core/ReactiveQuery'; diff --git a/packages/core/src/Platform/PlatformDetector.ts b/packages/core/src/Platform/PlatformDetector.ts index ddd3fc48..61f9f134 100644 --- a/packages/core/src/Platform/PlatformDetector.ts +++ b/packages/core/src/Platform/PlatformDetector.ts @@ -235,4 +235,4 @@ export class PlatformDetector { return info; } -} \ No newline at end of file +} diff --git a/packages/core/src/Platform/PlatformManager.ts b/packages/core/src/Platform/PlatformManager.ts index 63a3954d..0bbaa4c5 100644 --- a/packages/core/src/Platform/PlatformManager.ts +++ b/packages/core/src/Platform/PlatformManager.ts @@ -98,7 +98,7 @@ export class PlatformManager { platformSupportsSharedArrayBuffer: boolean; platformMaxWorkerCount: number; platformLimitations: any; - } { + } { if (!this.adapter) { return { platformSupportsWorker: false, @@ -134,4 +134,4 @@ export class PlatformManager { // 否则返回同步配置 return this.adapter.getPlatformConfig(); } -} \ No newline at end of file +} diff --git a/packages/core/src/Platform/index.ts b/packages/core/src/Platform/index.ts index 5ac01e52..f1b40242 100644 --- a/packages/core/src/Platform/index.ts +++ b/packages/core/src/Platform/index.ts @@ -44,4 +44,4 @@ export function supportsFeature(feature: 'worker' | 'shared-array-buffer' | 'tra export function hasAdapter() { return PlatformManager.getInstance().hasAdapter(); -} \ No newline at end of file +} diff --git a/packages/core/src/Plugins/DebugPlugin.ts b/packages/core/src/Plugins/DebugPlugin.ts index e19af4c2..5603a0e7 100644 --- a/packages/core/src/Plugins/DebugPlugin.ts +++ b/packages/core/src/Plugins/DebugPlugin.ts @@ -208,8 +208,8 @@ export class DebugPlugin implements IPlugin, IService { return { name: scene.name, entityCount: entities.length, - systems: systems.map(sys => this.getSystemInfo(sys)), - entities: entities.map(entity => this.getEntityInfo(entity)) + systems: systems.map((sys) => this.getSystemInfo(sys)), + entities: entities.map((entity) => this.getEntityInfo(entity)) }; } @@ -246,7 +246,7 @@ export class DebugPlugin implements IPlugin, IService { enabled: entity.enabled, tag: entity.tag, componentCount: components.length, - components: components.map(comp => this.getComponentInfo(comp)) + components: components.map((comp) => this.getComponentInfo(comp)) }; } @@ -304,7 +304,7 @@ export class DebugPlugin implements IPlugin, IService { if (filter.hasComponent) { const hasComp = entity.components.some( - c => c.constructor.name === filter.hasComponent + (c) => c.constructor.name === filter.hasComponent ); if (!hasComp) { continue; diff --git a/packages/core/src/Types/index.ts b/packages/core/src/Types/index.ts index 14fdaa7f..06edf59a 100644 --- a/packages/core/src/Types/index.ts +++ b/packages/core/src/Types/index.ts @@ -28,7 +28,7 @@ export interface IComponent { /** * 系统基础接口 - * + * * 为现有的EntitySystem类提供类型定义 */ export interface ISystemBase { @@ -38,7 +38,7 @@ export interface ISystemBase { updateOrder: number; /** 系统启用状态 */ enabled: boolean; - + /** 系统初始化 */ initialize(): void; /** 更新系统(主要处理阶段) */ @@ -49,7 +49,7 @@ export interface ISystemBase { /** * 组件类型定义 - * + * * 用于类型安全的组件操作 * 支持任意构造函数签名,提供更好的类型安全性 */ @@ -66,14 +66,14 @@ export interface IEventBus { * @param data 事件数据 */ emit(eventType: string, data: T): void; - + /** * 异步发射事件 * @param eventType 事件类型 * @param data 事件数据 */ emitAsync(eventType: string, data: T): Promise; - + /** * 监听事件 * @param eventType 事件类型 @@ -82,7 +82,7 @@ export interface IEventBus { * @returns 监听器ID */ on(eventType: string, handler: (data: T) => void, config?: IEventListenerConfig): string; - + /** * 监听事件(一次性) * @param eventType 事件类型 @@ -91,7 +91,7 @@ export interface IEventBus { * @returns 监听器ID */ once(eventType: string, handler: (data: T) => void, config?: IEventListenerConfig): string; - + /** * 异步监听事件 * @param eventType 事件类型 @@ -100,32 +100,32 @@ export interface IEventBus { * @returns 监听器ID */ onAsync(eventType: string, handler: (data: T) => Promise, config?: IEventListenerConfig): string; - + /** * 移除事件监听器 * @param eventType 事件类型 * @param listenerId 监听器ID */ off(eventType: string, listenerId: string): boolean; - + /** * 移除指定事件类型的所有监听器 * @param eventType 事件类型 */ offAll(eventType: string): void; - + /** * 检查是否有指定事件的监听器 * @param eventType 事件类型 */ hasListeners(eventType: string): boolean; - + /** * 获取事件统计信息 * @param eventType 事件类型(可选) */ getStats(eventType?: string): IEventStats | Map; - + /** * 清空所有监听器 */ @@ -499,4 +499,4 @@ export interface ISceneDebugData { sceneMemory: number; /** 场景启动时间 */ sceneUptime: number; -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/ComponentDataCollector.ts b/packages/core/src/Utils/Debug/ComponentDataCollector.ts index 4e7072cd..22b79d57 100644 --- a/packages/core/src/Utils/Debug/ComponentDataCollector.ts +++ b/packages/core/src/Utils/Debug/ComponentDataCollector.ts @@ -47,18 +47,18 @@ export class ComponentDataCollector { }); // 获取池利用率信息 - let poolUtilizations = new Map(); - let poolSizes = new Map(); - + const poolUtilizations = new Map(); + const poolSizes = new Map(); + try { const poolManager = ComponentPoolManager.getInstance(); const poolStats = poolManager.getPoolStats(); const utilizations = poolManager.getPoolUtilization(); - + for (const [typeName, stats] of poolStats.entries()) { poolSizes.set(typeName, stats.maxSize); } - + for (const [typeName, util] of utilizations.entries()) { poolUtilizations.set(typeName, util.utilization); } @@ -74,7 +74,7 @@ export class ComponentDataCollector { const poolUtilization = poolUtilizations.get(typeName) || 0; // 使用预估的基础内存大小,避免每帧计算 const memoryPerInstance = this.getEstimatedComponentSize(typeName, scene); - + return { typeName, instanceCount: stats.count, @@ -97,12 +97,12 @@ export class ComponentDataCollector { } if (!scene) return 64; - + const entityList = (scene as any).entities; if (!entityList?.buffer) return 64; - + let calculatedSize = 64; - + try { for (const entity of entityList.buffer) { if (entity.components) { @@ -116,25 +116,25 @@ export class ComponentDataCollector { } catch (error) { calculatedSize = 64; } - + ComponentDataCollector.componentSizeCache.set(typeName, calculatedSize); return calculatedSize; } private calculateQuickObjectSize(obj: any): number { if (!obj || typeof obj !== 'object') return 8; - + let size = 32; const visited = new WeakSet(); - + const calculate = (item: any, depth: number = 0): number => { if (!item || typeof item !== 'object' || visited.has(item) || depth > 3) { return 0; } visited.add(item); - + let itemSize = 0; - + try { const keys = Object.keys(item); for (let i = 0; i < Math.min(keys.length, 20); i++) { @@ -143,7 +143,7 @@ export class ComponentDataCollector { const value = item[key]; itemSize += key.length * 2; - + if (typeof value === 'string') { itemSize += Math.min(value.length * 2, 200); } else if (typeof value === 'number') { @@ -157,10 +157,10 @@ export class ComponentDataCollector { } catch (error) { return 32; } - + return itemSize; }; - + size += calculate(obj); return Math.max(size, 32); } @@ -176,7 +176,7 @@ export class ComponentDataCollector { const entityList = (scene as any).entities; if (!entityList?.buffer) return this.getEstimatedComponentSize(typeName, scene); - + try { // 找到第一个包含此组件的实体,分析组件大小 for (const entity of entityList.buffer) { @@ -190,7 +190,7 @@ export class ComponentDataCollector { } catch (error) { // 忽略错误,使用估算值 } - + return this.getEstimatedComponentSize(typeName, scene); } @@ -201,10 +201,10 @@ export class ComponentDataCollector { private estimateObjectSize(obj: any, visited = new WeakSet(), depth = 0): number { if (obj === null || obj === undefined || depth > 10) return 0; if (visited.has(obj)) return 0; - + let size = 0; const type = typeof obj; - + switch (type) { case 'boolean': size = 4; @@ -217,7 +217,7 @@ export class ComponentDataCollector { break; case 'object': visited.add(obj); - + if (Array.isArray(obj)) { size = 40 + (obj.length * 8); const maxElements = Math.min(obj.length, 50); @@ -226,11 +226,11 @@ export class ComponentDataCollector { } } else { size = 32; - + try { const ownKeys = Object.getOwnPropertyNames(obj); const maxProps = Math.min(ownKeys.length, 30); - + for (let i = 0; i < maxProps; i++) { const key = ownKeys[i]; if (!key) continue; @@ -263,11 +263,11 @@ export class ComponentDataCollector { default: size = 8; } - + return Math.ceil(size / 8) * 8; } public static clearCache(): void { ComponentDataCollector.componentSizeCache.clear(); } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/DebugManager.ts b/packages/core/src/Utils/Debug/DebugManager.ts index a752657b..d4772615 100644 --- a/packages/core/src/Utils/Debug/DebugManager.ts +++ b/packages/core/src/Utils/Debug/DebugManager.ts @@ -135,7 +135,7 @@ export class DebugManager implements IService, IUpdatable { * 格式化日志消息 */ private formatLogMessage(args: unknown[]): string { - return args.map(arg => { + return args.map((arg) => { if (typeof arg === 'string') return arg; if (arg instanceof Error) return `${arg.name}: ${arg.message}`; if (arg === null) return 'null'; @@ -173,7 +173,7 @@ export class DebugManager implements IService, IUpdatable { seen.add(value); if (Array.isArray(value)) { - const result = value.map(item => stringify(item, depth + 1)); + const result = value.map((item) => stringify(item, depth + 1)); seen.delete(value); return result; } @@ -436,9 +436,6 @@ export class DebugManager implements IService, IUpdatable { } - - - /** * 处理内存快照请求 */ @@ -519,7 +516,7 @@ export class DebugManager implements IService, IUpdatable { jsHeapSizeLimit: number; } | null; detailedMemory?: unknown; - } { + } { const memoryInfo = { totalMemory: 0, usedMemory: 0, @@ -575,7 +572,6 @@ export class DebugManager implements IService, IUpdatable { } - /** * 收集组件内存统计(仅用于内存快照) */ @@ -672,7 +668,7 @@ export class DebugManager implements IService, IUpdatable { enabled: boolean; updateOrder: number; }>; - } { + } { const scene = this.sceneManager.currentScene; let totalSystemMemory = 0; const systemBreakdown: Array<{ @@ -766,7 +762,7 @@ export class DebugManager implements IService, IUpdatable { utilization: number; hitRate?: number; }>; - } { + } { let totalPoolMemory = 0; const poolBreakdown: Array<{ typeName: string; @@ -845,7 +841,7 @@ export class DebugManager implements IService, IUpdatable { samples: number; }>; error?: string; - } { + } { try { if (!this.performanceMonitor) { return { enabled: false }; @@ -959,4 +955,4 @@ export class DebugManager implements IService, IUpdatable { console.warn = this.originalConsole.warn; console.error = this.originalConsole.error; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/EntityDataCollector.ts b/packages/core/src/Utils/Debug/EntityDataCollector.ts index d6d663fc..2b8d033a 100644 --- a/packages/core/src/Utils/Debug/EntityDataCollector.ts +++ b/packages/core/src/Utils/Debug/EntityDataCollector.ts @@ -641,10 +641,10 @@ export class EntityDataCollector { componentTypes: baseDebugInfo.componentTypes || componentDetails.map((comp) => comp.typeName), cachePerformance: componentCacheStats ? { - hitRate: componentCacheStats.cacheStats.hitRate, - size: componentCacheStats.cacheStats.size, - maxSize: componentCacheStats.cacheStats.maxSize - } + hitRate: componentCacheStats.cacheStats.hitRate, + size: componentCacheStats.cacheStats.size, + maxSize: componentCacheStats.cacheStats.maxSize + } : null }; }); diff --git a/packages/core/src/Utils/Debug/PerformanceDataCollector.ts b/packages/core/src/Utils/Debug/PerformanceDataCollector.ts index 5b1e8f98..2e1e190c 100644 --- a/packages/core/src/Utils/Debug/PerformanceDataCollector.ts +++ b/packages/core/src/Utils/Debug/PerformanceDataCollector.ts @@ -17,11 +17,11 @@ export class PerformanceDataCollector { const frameTimeSeconds = Time.deltaTime; const engineFrameTimeMs = frameTimeSeconds * 1000; const currentFps = frameTimeSeconds > 0 ? Math.round(1 / frameTimeSeconds) : 0; - + const ecsPerformanceData = this.getECSPerformanceData(performanceMonitor); const ecsExecutionTimeMs = ecsPerformanceData.totalExecutionTime; const ecsPercentage = engineFrameTimeMs > 0 ? (ecsExecutionTimeMs / engineFrameTimeMs * 100) : 0; - + let memoryUsage = 0; if ((performance as any).memory) { memoryUsage = (performance as any).memory.usedJSHeapSize / 1024 / 1024; @@ -32,9 +32,9 @@ export class PerformanceDataCollector { if (this.frameTimeHistory.length > this.maxHistoryLength) { this.frameTimeHistory.shift(); } - + // 计算ECS执行时间统计 - const history = this.frameTimeHistory.filter(t => t >= 0); + const history = this.frameTimeHistory.filter((t) => t >= 0); const averageECSTime = history.length > 0 ? history.reduce((a, b) => a + b, 0) / history.length : ecsExecutionTimeMs; const minECSTime = history.length > 0 ? Math.min(...history) : ecsExecutionTimeMs; const maxECSTime = history.length > 0 ? Math.max(...history) : ecsExecutionTimeMs; @@ -77,20 +77,20 @@ export class PerformanceDataCollector { try { let totalTime = 0; const systemBreakdown = []; - + const stats = performanceMonitor.getAllSystemStats(); - + if (stats.size === 0) { return { totalExecutionTime: 0, systemBreakdown: [] }; } - + // 计算各系统的执行时间 for (const [systemName, stat] of stats.entries()) { // 使用最近的执行时间而不是平均时间,这样更能反映当前状态 - const systemTime = stat.recentTimes && stat.recentTimes.length > 0 ? - stat.recentTimes[stat.recentTimes.length - 1] : + const systemTime = stat.recentTimes && stat.recentTimes.length > 0 ? + stat.recentTimes[stat.recentTimes.length - 1] : (stat.averageTime || 0); - + totalTime += systemTime; systemBreakdown.push({ systemName: systemName, @@ -98,15 +98,15 @@ export class PerformanceDataCollector { percentage: 0 // 后面计算 }); } - + // 计算各系统占ECS总时间的百分比 - systemBreakdown.forEach(system => { + systemBreakdown.forEach((system) => { system.percentage = totalTime > 0 ? (system.executionTime / totalTime * 100) : 0; }); - + // 按执行时间排序 systemBreakdown.sort((a, b) => b.executionTime - a.executionTime); - + return { totalExecutionTime: totalTime, systemBreakdown: systemBreakdown @@ -127,7 +127,7 @@ export class PerformanceDataCollector { try { const stats = performanceMonitor.getAllSystemStats(); const systemData = performanceMonitor.getAllSystemData(); - + return Array.from(stats.entries() as Iterable<[string, any]>).map(([systemName, stat]) => { const data = systemData.get(systemName); return { @@ -167,7 +167,7 @@ export class PerformanceDataCollector { memoryInfo.totalMemory = perfMemory.jsHeapSizeLimit || 512 * 1024 * 1024; memoryInfo.usedMemory = perfMemory.usedJSHeapSize || 0; memoryInfo.freeMemory = memoryInfo.totalMemory - memoryInfo.usedMemory; - + // 检测GC:如果使用的内存突然大幅减少,可能发生了GC if (this.lastMemoryCheck > 0) { const memoryDrop = this.lastMemoryCheck - memoryInfo.usedMemory; @@ -207,16 +207,16 @@ export class PerformanceDataCollector { // 实际的GC检测需要更复杂的逻辑 return this.gcCollections; } - + // 如果有其他GC检测API,可以在这里添加 if ((performance as any).measureUserAgentSpecificMemory) { // 实验性API,可能不可用 return this.gcCollections; } - + return this.gcCollections; } catch (error) { return this.gcCollections; } } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/SceneDataCollector.ts b/packages/core/src/Utils/Debug/SceneDataCollector.ts index d31fd314..ae8ff562 100644 --- a/packages/core/src/Utils/Debug/SceneDataCollector.ts +++ b/packages/core/src/Utils/Debug/SceneDataCollector.ts @@ -47,4 +47,4 @@ export class SceneDataCollector { public setSceneStartTime(time: number): void { this.sceneStartTime = time; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/SystemDataCollector.ts b/packages/core/src/Utils/Debug/SystemDataCollector.ts index a7abdc53..7b2a4903 100644 --- a/packages/core/src/Utils/Debug/SystemDataCollector.ts +++ b/packages/core/src/Utils/Debug/SystemDataCollector.ts @@ -28,11 +28,11 @@ export class SystemDataCollector { } const systems = entityProcessors.processors || []; - + // 获取性能监控数据 let systemStats: Map = new Map(); let systemData: Map = new Map(); - + if (performanceMonitor) { try { systemStats = performanceMonitor.getAllSystemStats(); @@ -41,14 +41,14 @@ export class SystemDataCollector { // 忽略错误,使用空的Map } } - + return { totalSystems: systems.length, systemsInfo: systems.map((system: any) => { const systemName = system.systemName || getSystemInstanceTypeName(system); const stats = systemStats.get(systemName); const data = systemData.get(systemName); - + return { name: systemName, type: getSystemInstanceTypeName(system), @@ -64,4 +64,4 @@ export class SystemDataCollector { }) }; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/WebSocketManager.ts b/packages/core/src/Utils/Debug/WebSocketManager.ts index 309b3736..763b8d4f 100644 --- a/packages/core/src/Utils/Debug/WebSocketManager.ts +++ b/packages/core/src/Utils/Debug/WebSocketManager.ts @@ -33,7 +33,7 @@ export class WebSocketManager { return new Promise((resolve, reject) => { try { this.ws = new WebSocket(this.url); - + this.ws.onopen = (event) => { this.handleOpen(event); resolve(); @@ -112,7 +112,7 @@ export class WebSocketManager { this.reconnectAttempts++; this.reconnectTimer = setTimeout(() => { - this.connect().catch(_error => { + this.connect().catch((_error) => { if (this.reconnectAttempts < this.maxReconnectAttempts) { this.scheduleReconnect(); } @@ -137,7 +137,7 @@ export class WebSocketManager { private handleOpen(event: Event): void { this.isConnected = true; this.reconnectAttempts = 0; - + if (this.onOpen) { this.onOpen(event); } @@ -145,11 +145,11 @@ export class WebSocketManager { private handleClose(event: CloseEvent): void { this.isConnected = false; - + if (this.onClose) { this.onClose(event); } - + if (this.autoReconnect && this.reconnectAttempts < this.maxReconnectAttempts) { this.scheduleReconnect(); } @@ -166,4 +166,4 @@ export class WebSocketManager { this.onError(error); } } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/index.ts b/packages/core/src/Utils/Debug/index.ts index 637cf40f..1cfea5cf 100644 --- a/packages/core/src/Utils/Debug/index.ts +++ b/packages/core/src/Utils/Debug/index.ts @@ -5,4 +5,4 @@ export { ComponentDataCollector } from './ComponentDataCollector'; export { SceneDataCollector } from './SceneDataCollector'; export { WebSocketManager } from './WebSocketManager'; export { DebugManager } from './DebugManager'; -export { DebugConfigService } from './DebugConfigService'; \ No newline at end of file +export { DebugConfigService } from './DebugConfigService'; diff --git a/packages/core/src/Utils/Emitter.ts b/packages/core/src/Utils/Emitter.ts index 96eea33b..9deb32e2 100644 --- a/packages/core/src/Utils/Emitter.ts +++ b/packages/core/src/Utils/Emitter.ts @@ -47,9 +47,9 @@ export class Emitter { * @param handler 事件函数 */ public removeObserver(eventType: T, handler: Function) { - let messageData = this._messageTable.get(eventType); + const messageData = this._messageTable.get(eventType); if (messageData) { - let index = messageData.findIndex(data => data.func == handler); + const index = messageData.findIndex((data) => data.func == handler); if (index != -1) messageData.splice(index, 1); } @@ -61,9 +61,9 @@ export class Emitter { * @param data 事件数据 */ public emit(eventType: T, ...data: TData[]) { - let list = this._messageTable.get(eventType); + const list = this._messageTable.get(eventType); if (list) { - for (let observer of list) { + for (const observer of list) { observer.func.call(observer.context, ...data); } } @@ -75,8 +75,8 @@ export class Emitter { * @param handler 事件函数 */ public hasObserver(eventType: T, handler: Function): boolean { - let list = this._messageTable.get(eventType); - return list ? list.some(observer => observer.func === handler) : false; + const list = this._messageTable.get(eventType); + return list ? list.some((observer) => observer.func === handler) : false; } /** diff --git a/packages/core/src/Utils/Extensions/NumberExtension.ts b/packages/core/src/Utils/Extensions/NumberExtension.ts index c536d19f..11ca9a04 100644 --- a/packages/core/src/Utils/Extensions/NumberExtension.ts +++ b/packages/core/src/Utils/Extensions/NumberExtension.ts @@ -12,4 +12,4 @@ export class NumberExtension { if (value == undefined) return 0; return Number(value); } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Extensions/TypeUtils.ts b/packages/core/src/Utils/Extensions/TypeUtils.ts index 287634d1..671fdd72 100644 --- a/packages/core/src/Utils/Extensions/TypeUtils.ts +++ b/packages/core/src/Utils/Extensions/TypeUtils.ts @@ -11,4 +11,4 @@ export class TypeUtils { public static getType(obj: any) { return obj.constructor; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Extensions/index.ts b/packages/core/src/Utils/Extensions/index.ts index da1cdef6..20c06819 100644 --- a/packages/core/src/Utils/Extensions/index.ts +++ b/packages/core/src/Utils/Extensions/index.ts @@ -1,3 +1,3 @@ // 扩展工具类导出 export { TypeUtils } from './TypeUtils'; -export { NumberExtension } from './NumberExtension'; \ No newline at end of file +export { NumberExtension } from './NumberExtension'; diff --git a/packages/core/src/Utils/Logger/ConsoleLogger.ts b/packages/core/src/Utils/Logger/ConsoleLogger.ts index 18700b5f..961d787d 100644 --- a/packages/core/src/Utils/Logger/ConsoleLogger.ts +++ b/packages/core/src/Utils/Logger/ConsoleLogger.ts @@ -1,5 +1,5 @@ -import { Colors, LogLevel } from "./Constants"; -import { ILogger, LoggerColorConfig, LoggerConfig } from "./Types"; +import { Colors, LogLevel } from './Constants'; +import { ILogger, LoggerColorConfig, LoggerConfig } from './Types'; /** @@ -138,7 +138,7 @@ export class ConsoleLogger implements ILogger { */ private outputToConsole(level: LogLevel, message: string, ...args: unknown[]): void { const colors = this._config.enableColors ? this.getColors() : null; - + switch (level) { case LogLevel.Debug: if (colors) { diff --git a/packages/core/src/Utils/Logger/Constants.ts b/packages/core/src/Utils/Logger/Constants.ts index 3bc9ab4f..ce36092c 100644 --- a/packages/core/src/Utils/Logger/Constants.ts +++ b/packages/core/src/Utils/Logger/Constants.ts @@ -23,7 +23,7 @@ export const Colors = { MAGENTA: '\x1b[35m', CYAN: '\x1b[36m', WHITE: '\x1b[37m', - + // 亮色版本 BRIGHT_BLACK: '\x1b[90m', BRIGHT_RED: '\x1b[91m', @@ -33,7 +33,7 @@ export const Colors = { BRIGHT_MAGENTA: '\x1b[95m', BRIGHT_CYAN: '\x1b[96m', BRIGHT_WHITE: '\x1b[97m', - + // 特殊 RESET: '\x1b[0m', BOLD: '\x1b[1m', diff --git a/packages/core/src/Utils/Logger/LoggerManager.ts b/packages/core/src/Utils/Logger/LoggerManager.ts index 6bf9506f..c8e27848 100644 --- a/packages/core/src/Utils/Logger/LoggerManager.ts +++ b/packages/core/src/Utils/Logger/LoggerManager.ts @@ -1,6 +1,6 @@ -import { ConsoleLogger } from "./ConsoleLogger"; -import { LogLevel } from "./Constants"; -import { ILogger, LoggerColorConfig } from "./Types"; +import { ConsoleLogger } from './ConsoleLogger'; +import { LogLevel } from './Constants'; +import { ILogger, LoggerColorConfig } from './Types'; /** * 日志管理器 @@ -186,7 +186,7 @@ export function setGlobalLogLevel(level: LogLevel): void { } /** - * 设置日志器工厂方法 + * 设置日志器工厂方法 * @param factory 日志器工厂方法 */ export function setLoggerFactory(factory: (name?: string) => ILogger): void { diff --git a/packages/core/src/Utils/Logger/Types.ts b/packages/core/src/Utils/Logger/Types.ts index b32721be..bbdc2073 100644 --- a/packages/core/src/Utils/Logger/Types.ts +++ b/packages/core/src/Utils/Logger/Types.ts @@ -1,4 +1,4 @@ -import type { LogLevel } from "./Constants"; +import type { LogLevel } from './Constants'; /** * 日志接口 diff --git a/packages/core/src/Utils/PerformanceMonitor.ts b/packages/core/src/Utils/PerformanceMonitor.ts index c13d9dd4..63259d8c 100644 --- a/packages/core/src/Utils/PerformanceMonitor.ts +++ b/packages/core/src/Utils/PerformanceMonitor.ts @@ -183,7 +183,7 @@ export class PerformanceMonitor implements IService { */ private updateStats(systemName: string, executionTime: number): void { let stats = this._systemStats.get(systemName); - + if (!stats) { stats = { totalTime: 0, @@ -231,7 +231,7 @@ export class PerformanceMonitor implements IService { // 计算百分位数 const sortedTimes = [...stats.recentTimes].sort((a, b) => a - b); const len = sortedTimes.length; - + stats.percentile95 = sortedTimes[Math.floor(len * 0.95)] || 0; stats.percentile99 = sortedTimes[Math.floor(len * 0.99)] || 0; } @@ -276,12 +276,12 @@ export class PerformanceMonitor implements IService { */ public getPerformanceReport(): string { if (!this._isEnabled) { - return "Performance monitoring is disabled."; + return 'Performance monitoring is disabled.'; } const lines: string[] = []; - lines.push("=== ECS Performance Report ==="); - lines.push(""); + lines.push('=== ECS Performance Report ==='); + lines.push(''); // 按平均执行时间排序 const sortedSystems = Array.from(this._systemStats.entries()) @@ -289,24 +289,24 @@ export class PerformanceMonitor implements IService { for (const [systemName, stats] of sortedSystems) { const data = this._systemData.get(systemName); - + lines.push(`System: ${systemName}`); lines.push(` Current: ${data?.executionTime.toFixed(2)}ms (${data?.entityCount} entities)`); lines.push(` Average: ${stats.averageTime.toFixed(2)}ms`); lines.push(` Min/Max: ${stats.minTime.toFixed(2)}ms / ${stats.maxTime.toFixed(2)}ms`); lines.push(` Total: ${stats.totalTime.toFixed(2)}ms (${stats.executionCount} calls)`); - + if (data?.averageTimePerEntity && data.averageTimePerEntity > 0) { lines.push(` Per Entity: ${data.averageTimePerEntity.toFixed(4)}ms`); } - - lines.push(""); + + lines.push(''); } // 总体统计 const totalCurrentTime = Array.from(this._systemData.values()) .reduce((sum, data) => sum + data.executionTime, 0); - + lines.push(`Total Frame Time: ${totalCurrentTime.toFixed(2)}ms`); lines.push(`Systems Count: ${this._systemData.size}`); @@ -337,13 +337,13 @@ export class PerformanceMonitor implements IService { */ public getPerformanceWarnings(thresholdMs: number = 16.67): string[] { const warnings: string[] = []; - + for (const [systemName, data] of this._systemData.entries()) { if (data.executionTime > thresholdMs) { warnings.push(`${systemName}: ${data.executionTime.toFixed(2)}ms (>${thresholdMs}ms)`); } } - + return warnings; } @@ -370,4 +370,4 @@ export class PerformanceMonitor implements IService { this._systemStats.clear(); this._isEnabled = false; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Pool/IPoolable.ts b/packages/core/src/Utils/Pool/IPoolable.ts index e0fa7300..c981587b 100644 --- a/packages/core/src/Utils/Pool/IPoolable.ts +++ b/packages/core/src/Utils/Pool/IPoolable.ts @@ -26,4 +26,4 @@ export interface PoolStats { hitRate: number; /** 内存使用估算(字节) */ estimatedMemoryUsage: number; -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Pool/Pool.ts b/packages/core/src/Utils/Pool/Pool.ts index bb69146e..b42e567d 100644 --- a/packages/core/src/Utils/Pool/Pool.ts +++ b/packages/core/src/Utils/Pool/Pool.ts @@ -6,7 +6,7 @@ import { IPoolable, PoolStats } from './IPoolable'; */ export class Pool { private static _pools = new Map>(); - + private _objects: T[] = []; private _createFn: () => T; private _maxSize: number; @@ -42,17 +42,17 @@ export class Pool { * @returns 对象池实例 */ public static getPool( - type: new (...args: unknown[]) => T, + type: new (...args: unknown[]) => T, maxSize: number = 100, estimatedObjectSize: number = 1024 ): Pool { let pool = this._pools.get(type); - + if (!pool) { pool = new Pool(() => new type(), maxSize, estimatedObjectSize); this._pools.set(type, pool); } - + return pool; } @@ -62,7 +62,7 @@ export class Pool { */ public obtain(): T { this._stats.totalObtained++; - + if (this._objects.length > 0) { const obj = this._objects.pop()!; this._stats.size--; @@ -70,7 +70,7 @@ export class Pool { this._updateMemoryUsage(); return obj; } - + // 池中没有可用对象,创建新对象 this._stats.totalCreated++; this._updateHitRate(); @@ -83,9 +83,9 @@ export class Pool { */ public release(obj: T): void { if (!obj) return; - + this._stats.totalReleased++; - + // 如果池未满,将对象放回池中 if (this._stats.size < this._maxSize) { // 重置对象状态 @@ -113,7 +113,7 @@ export class Pool { for (const obj of this._objects) { obj.reset(); } - + this._objects.length = 0; this._stats.size = 0; this._updateMemoryUsage(); @@ -125,7 +125,7 @@ export class Pool { */ public compact(targetSize?: number): void { const target = targetSize ?? Math.floor(this._objects.length / 2); - + while (this._objects.length > target) { const obj = this._objects.pop(); if (obj) { @@ -133,7 +133,7 @@ export class Pool { this._stats.size--; } } - + this._updateMemoryUsage(); } @@ -143,7 +143,7 @@ export class Pool { */ public prewarm(count: number): void { const actualCount = Math.min(count, this._maxSize - this._objects.length); - + for (let i = 0; i < actualCount; i++) { const obj = this._createFn(); obj.reset(); @@ -151,7 +151,7 @@ export class Pool { this._stats.totalCreated++; this._stats.size++; } - + this._updateMemoryUsage(); } @@ -162,7 +162,7 @@ export class Pool { public setMaxSize(maxSize: number): void { this._maxSize = maxSize; this._stats.maxSize = maxSize; - + // 如果当前池大小超过新的最大值,进行压缩 if (this._objects.length > maxSize) { this.compact(maxSize); @@ -207,12 +207,12 @@ export class Pool { */ public static getAllPoolStats(): Record { const stats: Record = {}; - + for (const [type, pool] of this._pools) { const typeName = type.name || type.toString(); stats[typeName] = pool.getStats(); } - + return stats; } @@ -242,12 +242,12 @@ export class Pool { public static getGlobalStatsString(): string { const stats = this.getAllPoolStats(); const lines: string[] = ['=== Object Pool Global Statistics ===', '']; - + if (Object.keys(stats).length === 0) { lines.push('No pools registered'); return lines.join('\n'); } - + for (const [typeName, stat] of Object.entries(stats)) { lines.push(`${typeName}:`); lines.push(` Size: ${stat.size}/${stat.maxSize}`); @@ -257,7 +257,7 @@ export class Pool { lines.push(` Memory: ${(stat.estimatedMemoryUsage / 1024).toFixed(1)} KB`); lines.push(''); } - + return lines.join('\n'); } @@ -279,4 +279,4 @@ export class Pool { private _updateMemoryUsage(): void { this._stats.estimatedMemoryUsage = this._stats.size * this._objectSize; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Pool/PoolManager.ts b/packages/core/src/Utils/Pool/PoolManager.ts index 6299e389..28be67c8 100644 --- a/packages/core/src/Utils/Pool/PoolManager.ts +++ b/packages/core/src/Utils/Pool/PoolManager.ts @@ -38,7 +38,7 @@ export class PoolManager implements IService { */ public update(): void { const now = Date.now(); - + if (now - this.lastCompactTime > this.autoCompactInterval) { this.compactAllPools(); this.lastCompactTime = now; @@ -60,12 +60,12 @@ export class PoolManager implements IService { estimatedObjectSize: number = 1024 ): Pool { let pool = this.pools.get(name) as Pool; - + if (!pool) { pool = new Pool(createFn, maxSize, estimatedObjectSize); this.pools.set(name, pool); } - + return pool; } @@ -125,11 +125,11 @@ export class PoolManager implements IService { */ public getAllStats(): Map { const stats = new Map(); - + for (const [name, pool] of this.pools) { stats.set(name, pool.getStats()); } - + return stats; } @@ -144,7 +144,7 @@ export class PoolManager implements IService { let totalObtained = 0; let totalReleased = 0; let totalMemoryUsage = 0; - + for (const pool of this.pools.values()) { const stats = pool.getStats(); totalSize += stats.size; @@ -154,9 +154,9 @@ export class PoolManager implements IService { totalReleased += stats.totalReleased; totalMemoryUsage += stats.estimatedMemoryUsage; } - + const hitRate = totalObtained === 0 ? 0 : (totalObtained - totalCreated) / totalObtained; - + return { size: totalSize, maxSize: totalMaxSize, @@ -174,18 +174,18 @@ export class PoolManager implements IService { */ public getStatsString(): string { const lines: string[] = ['=== Pool Manager Statistics ===', '']; - + if (this.pools.size === 0) { lines.push('No pools registered'); return lines.join('\n'); } - + const globalStats = this.getGlobalStats(); lines.push(`Total Pools: ${this.pools.size}`); lines.push(`Global Hit Rate: ${(globalStats.hitRate * 100).toFixed(1)}%`); lines.push(`Global Memory Usage: ${(globalStats.estimatedMemoryUsage / 1024).toFixed(1)} KB`); lines.push(''); - + for (const [name, pool] of this.pools) { const stats = pool.getStats(); lines.push(`${name}:`); @@ -194,7 +194,7 @@ export class PoolManager implements IService { lines.push(` Memory: ${(stats.estimatedMemoryUsage / 1024).toFixed(1)} KB`); lines.push(''); } - + return lines.join('\n'); } @@ -233,4 +233,4 @@ export class PoolManager implements IService { public dispose(): void { this.reset(); } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Pool/index.ts b/packages/core/src/Utils/Pool/index.ts index 2f238812..8ecafe81 100644 --- a/packages/core/src/Utils/Pool/index.ts +++ b/packages/core/src/Utils/Pool/index.ts @@ -1,3 +1,3 @@ export * from './IPoolable'; export * from './Pool'; -export * from './PoolManager'; \ No newline at end of file +export * from './PoolManager'; diff --git a/packages/core/src/Utils/Time.ts b/packages/core/src/Utils/Time.ts index 239dad2e..0ea73687 100644 --- a/packages/core/src/Utils/Time.ts +++ b/packages/core/src/Utils/Time.ts @@ -7,27 +7,27 @@ export class Time { * 上一帧到当前帧的时间间隔(秒) */ public static deltaTime: number = 0; - + /** * 未缩放的帧时间间隔(秒) */ public static unscaledDeltaTime: number = 0; - + /** * 游戏开始以来的总时间(秒) */ public static totalTime: number = 0; - + /** * 未缩放的总时间(秒) */ public static unscaledTotalTime: number = 0; - + /** * 时间缩放比例 */ public static timeScale: number = 1; - + /** * 当前帧数 */ @@ -70,4 +70,4 @@ export class Time { public static checkEvery(interval: number, lastTime: number): boolean { return this.totalTime - lastTime >= interval; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Timers/ITimer.ts b/packages/core/src/Utils/Timers/ITimer.ts index 942d55a5..c42a8839 100644 --- a/packages/core/src/Utils/Timers/ITimer.ts +++ b/packages/core/src/Utils/Timers/ITimer.ts @@ -15,4 +15,4 @@ export interface ITimer { * 返回投向T的上下文,作为方便 */ getContext(): T; -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Timers/Timer.ts b/packages/core/src/Utils/Timers/Timer.ts index 3b371a3f..21eca82b 100644 --- a/packages/core/src/Utils/Timers/Timer.ts +++ b/packages/core/src/Utils/Timers/Timer.ts @@ -67,4 +67,4 @@ export class Timer implements ITimer{ this.context = null as unknown as TContext; this._onTime = null!; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Timers/TimerManager.ts b/packages/core/src/Utils/Timers/TimerManager.ts index b05ddc4f..d613d5a6 100644 --- a/packages/core/src/Utils/Timers/TimerManager.ts +++ b/packages/core/src/Utils/Timers/TimerManager.ts @@ -30,7 +30,7 @@ export class TimerManager implements IService, IUpdatable { * @param onTime */ public schedule(timeInSeconds: number, repeats: boolean, context: TContext, onTime: (timer: ITimer)=>void): Timer { - let timer = new Timer(); + const timer = new Timer(); timer.initialize(timeInSeconds, repeats, context, onTime); this._timers.push(timer as Timer); @@ -46,4 +46,4 @@ export class TimerManager implements IService, IUpdatable { } this._timers = []; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/index.ts b/packages/core/src/Utils/index.ts index d9817f6a..9fd78f2c 100644 --- a/packages/core/src/Utils/index.ts +++ b/packages/core/src/Utils/index.ts @@ -6,4 +6,4 @@ export * from './PerformanceMonitor'; export { Time } from './Time'; export * from './Debug'; export * from './Logger'; -export * from './BinarySerializer'; +export * from './BinarySerializer'; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 2ef87b2d..8f203399 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -36,13 +36,13 @@ export { ITimer } from './Utils/Timers/ITimer'; export { Timer } from './Utils/Timers/Timer'; // 日志系统 -export { - LoggerManager, - ConsoleLogger, - Logger, - createLogger, +export { + LoggerManager, + ConsoleLogger, + Logger, + createLogger, setGlobalLogLevel, - LogLevel + LogLevel } from './Utils/Logger'; export type { ILogger, LoggerConfig } from './Utils/Logger'; @@ -64,4 +64,4 @@ export * from './Types'; export { ComponentPool, ComponentPoolManager } from './ECS/Core/Storage'; // 平台适配 -export * from './Platform'; \ No newline at end of file +export * from './Platform';