From 3e037f4ae058023f595c6042ea2b8c454405b462 Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Fri, 31 Oct 2025 18:29:53 +0800 Subject: [PATCH] =?UTF-8?q?style(core):=20=E7=BB=9F=E4=B8=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E9=A3=8E=E6=A0=BC=E5=B9=B6=E5=BC=BA=E5=8C=96=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.json | 25 +- packages/core/src/Core.ts | 68 +++--- packages/core/src/Core/DI/Decorators.ts | 22 +- packages/core/src/Core/DI/index.ts | 4 +- packages/core/src/Core/Plugin.ts | 10 +- packages/core/src/Core/PluginManager.ts | 22 +- packages/core/src/Core/ServiceContainer.ts | 26 +- packages/core/src/ECS/Component.ts | 15 +- packages/core/src/ECS/Core/ArchetypeSystem.ts | 40 ++-- packages/core/src/ECS/Core/ComponentPool.ts | 16 +- .../core/src/ECS/Core/ComponentStorage.ts | 33 ++- .../ComponentStorage/ComponentRegistry.ts | 26 +- packages/core/src/ECS/Core/EventBus.ts | 137 ++++++----- packages/core/src/ECS/Core/EventSystem.ts | 19 +- packages/core/src/ECS/Core/Events/index.ts | 4 +- packages/core/src/ECS/Core/FluentAPI.ts | 2 +- .../ECS/Core/FluentAPI/ComponentBuilder.ts | 4 +- .../src/ECS/Core/FluentAPI/ECSFluentAPI.ts | 34 +-- .../ECS/Core/FluentAPI/EntityBatchOperator.ts | 8 +- .../src/ECS/Core/FluentAPI/EntityBuilder.ts | 12 +- .../src/ECS/Core/FluentAPI/SceneBuilder.ts | 10 +- packages/core/src/ECS/Core/FluentAPI/index.ts | 10 +- .../core/src/ECS/Core/Query/TypedQuery.ts | 10 +- packages/core/src/ECS/Core/Query/index.ts | 5 +- packages/core/src/ECS/Core/QuerySystem.ts | 150 +++++++----- packages/core/src/ECS/Core/QueryTypes.ts | 12 +- packages/core/src/ECS/Core/ReactiveQuery.ts | 32 +-- .../core/src/ECS/Core/ReferenceTracker.ts | 12 +- packages/core/src/ECS/Core/SoAStorage.ts | 218 ++++++++--------- packages/core/src/ECS/Core/Storage/index.ts | 6 +- .../core/src/ECS/Core/StorageDecorators.ts | 2 +- packages/core/src/ECS/CoreEvents.ts | 130 +++++----- .../src/ECS/Decorators/EntityRefDecorator.ts | 20 +- .../core/src/ECS/Decorators/TypeDecorators.ts | 38 +-- packages/core/src/ECS/Decorators/index.ts | 8 +- packages/core/src/ECS/Entity.ts | 157 ++++++------ packages/core/src/ECS/IScene.ts | 30 +-- packages/core/src/ECS/Scene.ts | 100 ++++---- packages/core/src/ECS/SceneManager.ts | 24 +- .../ECS/Serialization/ComponentSerializer.ts | 62 ++--- .../src/ECS/Serialization/EntitySerializer.ts | 8 +- .../Serialization/IncrementalSerializer.ts | 54 ++--- .../src/ECS/Serialization/SceneSerializer.ts | 72 +++--- .../Serialization/SerializationDecorators.ts | 18 +- .../src/ECS/Serialization/VersionMigration.ts | 20 +- packages/core/src/ECS/Serialization/index.ts | 24 +- packages/core/src/ECS/Systems/EntitySystem.ts | 92 ++++--- .../core/src/ECS/Systems/IntervalSystem.ts | 8 +- .../core/src/ECS/Systems/PassiveSystem.ts | 8 +- .../core/src/ECS/Systems/ProcessingSystem.ts | 8 +- .../src/ECS/Systems/WorkerEntitySystem.ts | 56 ++--- packages/core/src/ECS/Systems/index.ts | 12 +- packages/core/src/ECS/TypedEntity.ts | 8 +- .../core/src/ECS/Utils/BigIntCompatibility.ts | 46 ++-- packages/core/src/ECS/Utils/BitMaskHashMap.ts | 2 +- packages/core/src/ECS/Utils/Bits.ts | 56 ++--- .../core/src/ECS/Utils/ComponentSparseSet.ts | 190 ++++++++------- packages/core/src/ECS/Utils/EntityList.ts | 28 +-- .../core/src/ECS/Utils/EntityProcessorList.ts | 10 +- packages/core/src/ECS/Utils/IdentifierPool.ts | 128 +++++----- packages/core/src/ECS/Utils/Matcher.ts | 44 ++-- packages/core/src/ECS/Utils/SparseSet.ts | 110 ++++----- packages/core/src/ECS/Utils/index.ts | 16 +- packages/core/src/ECS/World.ts | 70 +++--- packages/core/src/ECS/WorldManager.ts | 54 ++--- packages/core/src/ECS/index.ts | 40 ++-- .../core/src/Platform/IPlatformAdapter.ts | 8 +- .../core/src/Platform/PlatformDetector.ts | 156 ++++++------ packages/core/src/Platform/PlatformManager.ts | 26 +- packages/core/src/Platform/index.ts | 14 +- packages/core/src/Plugins/DebugPlugin.ts | 64 ++--- packages/core/src/Plugins/index.ts | 2 +- packages/core/src/Types/IUpdatable.ts | 2 +- packages/core/src/Types/TypeHelpers.ts | 6 +- packages/core/src/Types/index.ts | 32 +-- packages/core/src/Utils/BinarySerializer.ts | 2 +- .../src/Utils/Debug/ComponentDataCollector.ts | 96 ++++---- .../src/Utils/Debug/DebugConfigService.ts | 8 +- packages/core/src/Utils/Debug/DebugManager.ts | 168 +++++++------ .../src/Utils/Debug/EntityDataCollector.ts | 225 +++++++++--------- .../Utils/Debug/PerformanceDataCollector.ts | 52 ++-- .../src/Utils/Debug/SceneDataCollector.ts | 10 +- .../src/Utils/Debug/SystemDataCollector.ts | 16 +- .../core/src/Utils/Debug/WebSocketManager.ts | 14 +- packages/core/src/Utils/Debug/index.ts | 16 +- packages/core/src/Utils/Emitter.ts | 12 +- .../src/Utils/Extensions/NumberExtension.ts | 2 +- .../core/src/Utils/Extensions/TypeUtils.ts | 2 +- packages/core/src/Utils/Extensions/index.ts | 4 +- .../core/src/Utils/Logger/ConsoleLogger.ts | 8 +- packages/core/src/Utils/Logger/Constants.ts | 42 ++-- .../core/src/Utils/Logger/LoggerManager.ts | 16 +- packages/core/src/Utils/Logger/Types.ts | 2 +- packages/core/src/Utils/Logger/index.ts | 8 +- packages/core/src/Utils/PerformanceMonitor.ts | 36 +-- packages/core/src/Utils/Pool/IPoolable.ts | 2 +- packages/core/src/Utils/Pool/Pool.ts | 60 ++--- packages/core/src/Utils/Pool/PoolManager.ts | 44 ++-- packages/core/src/Utils/Pool/index.ts | 6 +- packages/core/src/Utils/Time.ts | 12 +- packages/core/src/Utils/Timers/ITimer.ts | 2 +- packages/core/src/Utils/Timers/Timer.ts | 6 +- .../core/src/Utils/Timers/TimerManager.ts | 14 +- packages/core/src/Utils/index.ts | 18 +- packages/core/src/index.ts | 60 ++--- packages/core/tests/ECS/Component.test.ts | 3 +- 106 files changed, 2054 insertions(+), 1967 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 80c2703b..ae438249 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -31,9 +31,32 @@ "@typescript-eslint/no-unsafe-call": "warn", "@typescript-eslint/no-unsafe-return": "warn", "@typescript-eslint/no-unsafe-argument": "warn", + "@typescript-eslint/no-unsafe-function-type": "error", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], - "@typescript-eslint/no-non-null-assertion": "off" + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "memberLike", + "modifiers": ["private"], + "format": ["camelCase"], + "leadingUnderscore": "require" + }, + { + "selector": "memberLike", + "modifiers": ["public"], + "format": ["camelCase"], + "leadingUnderscore": "forbid" + }, + { + "selector": "memberLike", + "modifiers": ["protected"], + "format": ["camelCase"], + "leadingUnderscore": "require" + } + ] }, "ignorePatterns": [ "node_modules/", diff --git a/packages/core/src/Core.ts b/packages/core/src/Core.ts index 968f9ca1..0af10582 100644 --- a/packages/core/src/Core.ts +++ b/packages/core/src/Core.ts @@ -1,20 +1,20 @@ -import { TimerManager } from './Utils/Timers/TimerManager'; -import { ITimer } from './Utils/Timers/ITimer'; -import { Timer } from './Utils/Timers/Timer'; -import { Time } from './Utils/Time'; -import { PerformanceMonitor } from './Utils/PerformanceMonitor'; -import { PoolManager } from './Utils/Pool/PoolManager'; -import { DebugManager } from './Utils/Debug'; -import { ICoreConfig, IECSDebugConfig } from './Types'; -import { createLogger } from './Utils/Logger'; -import { SceneManager } from './ECS/SceneManager'; -import { IScene } from './ECS/IScene'; -import { ServiceContainer } from './Core/ServiceContainer'; -import { PluginManager } from './Core/PluginManager'; -import { IPlugin } from './Core/Plugin'; -import { WorldManager } from './ECS/WorldManager'; -import { DebugConfigService } from './Utils/Debug/DebugConfigService'; -import { createInstance } from './Core/DI/Decorators'; +import {TimerManager} from "./Utils/Timers/TimerManager"; +import {ITimer} from "./Utils/Timers/ITimer"; +import {Timer} from "./Utils/Timers/Timer"; +import {Time} from "./Utils/Time"; +import {PerformanceMonitor} from "./Utils/PerformanceMonitor"; +import {PoolManager} from "./Utils/Pool/PoolManager"; +import {DebugManager} from "./Utils/Debug"; +import {ICoreConfig, IECSDebugConfig} from "./Types"; +import {createLogger} from "./Utils/Logger"; +import {SceneManager} from "./ECS/SceneManager"; +import {IScene} from "./ECS/IScene"; +import {ServiceContainer} from "./Core/ServiceContainer"; +import {PluginManager} from "./Core/PluginManager"; +import {IPlugin} from "./Core/Plugin"; +import {WorldManager} from "./ECS/WorldManager"; +import {DebugConfigService} from "./Utils/Debug/DebugConfigService"; +import {createInstance} from "./Core/DI/Decorators"; /** * 游戏引擎核心类 @@ -67,7 +67,7 @@ export class Core { /** * Core专用日志器 */ - private static _logger = createLogger('Core'); + private static _logger = createLogger("Core"); /** * 实体系统启用状态 @@ -246,7 +246,7 @@ export class Core { */ public static get services(): ServiceContainer { if (!this._instance) { - throw new Error('Core实例未创建,请先调用Core.create()'); + throw new Error("Core实例未创建,请先调用Core.create()"); } return this._instance._serviceContainer; } @@ -270,7 +270,7 @@ export class Core { */ public static get worldManager(): WorldManager { if (!this._instance) { - throw new Error('Core实例未创建,请先调用Core.create()'); + throw new Error("Core实例未创建,请先调用Core.create()"); } return this._instance._worldManager; } @@ -302,12 +302,12 @@ export class Core { public static create(config: ICoreConfig | boolean = true): Core { if (this._instance == null) { // 向后兼容:如果传入boolean,转换为配置对象 - const coreConfig: ICoreConfig = typeof config === 'boolean' - ? { debug: config, enableEntitySystems: true } + const coreConfig: ICoreConfig = typeof config === "boolean" + ? {debug: config, enableEntitySystems: true} : config; this._instance = new Core(coreConfig); } else { - this._logger.warn('Core实例已创建,返回现有实例'); + this._logger.warn("Core实例已创建,返回现有实例"); } return this._instance; } @@ -457,10 +457,10 @@ export class Core { */ public static schedule(timeInSeconds: number, repeats: boolean = false, context?: TContext, onTime?: (timer: ITimer) => void): Timer { if (!this._instance) { - throw new Error('Core实例未创建,请先调用Core.create()'); + throw new Error("Core实例未创建,请先调用Core.create()"); } if (!onTime) { - throw new Error('onTime callback is required'); + throw new Error("onTime callback is required"); } return this._instance._timerManager.schedule(timeInSeconds, repeats, context as TContext, onTime); } @@ -549,7 +549,7 @@ export class Core { */ public static async installPlugin(plugin: IPlugin): Promise { if (!this._instance) { - throw new Error('Core实例未创建,请先调用Core.create()'); + throw new Error("Core实例未创建,请先调用Core.create()"); } await this._instance._pluginManager.install(plugin); @@ -568,7 +568,7 @@ export class Core { */ public static async uninstallPlugin(name: string): Promise { if (!this._instance) { - throw new Error('Core实例未创建,请先调用Core.create()'); + throw new Error("Core实例未创建,请先调用Core.create()"); } await this._instance._pluginManager.uninstall(name); @@ -624,7 +624,7 @@ export class Core { */ protected initialize() { // 核心系统初始化 - Core._logger.info('Core initialized', { + Core._logger.info("Core initialized", { debug: this.debug, entitySystemsEnabled: Core.entitySystemsEnabled, debugEnabled: this._config.debugConfig?.enabled || false @@ -640,20 +640,20 @@ export class Core { if (Core.paused) return; // 开始性能监控 - const frameStartTime = this._performanceMonitor.startMonitoring('Core.update'); + const frameStartTime = this._performanceMonitor.startMonitoring("Core.update"); // 更新时间系统 Time.update(deltaTime); // 更新FPS监控(如果性能监控器支持) - if ('updateFPS' in this._performanceMonitor && typeof this._performanceMonitor.updateFPS === 'function') { + if ("updateFPS" in this._performanceMonitor && typeof this._performanceMonitor.updateFPS === "function") { this._performanceMonitor.updateFPS(Time.deltaTime); } // 更新所有可更新的服务 - const servicesStartTime = this._performanceMonitor.startMonitoring('Services.update'); + const servicesStartTime = this._performanceMonitor.startMonitoring("Services.update"); this._serviceContainer.updateAll(deltaTime); - this._performanceMonitor.endMonitoring('Services.update', servicesStartTime, this._serviceContainer.getUpdatableCount()); + this._performanceMonitor.endMonitoring("Services.update", servicesStartTime, this._serviceContainer.getUpdatableCount()); // 更新对象池管理器 this._poolManager.update(); @@ -665,7 +665,7 @@ export class Core { this._worldManager.updateAll(); // 结束性能监控 - this._performanceMonitor.endMonitoring('Core.update', frameStartTime); + this._performanceMonitor.endMonitoring("Core.update", frameStartTime); } /** @@ -684,7 +684,7 @@ export class Core { // 清理所有服务 this._instance._serviceContainer.clear(); - Core._logger.info('Core destroyed'); + Core._logger.info("Core destroyed"); // 清空实例引用,允许重新创建Core实例 this._instance = null; diff --git a/packages/core/src/Core/DI/Decorators.ts b/packages/core/src/Core/DI/Decorators.ts index 2f266e62..3b7d701d 100644 --- a/packages/core/src/Core/DI/Decorators.ts +++ b/packages/core/src/Core/DI/Decorators.ts @@ -4,8 +4,8 @@ * 提供 @Injectable、@Inject 和 @Updatable 装饰器,用于标记可注入的类和依赖注入点 */ -import type { ServiceContainer } from '../ServiceContainer'; -import type { IService, ServiceType } from '../ServiceContainer'; +import type {ServiceContainer} from "../ServiceContainer"; +import type {IService, ServiceType} from "../ServiceContainer"; /** * 依赖注入元数据存储 @@ -76,13 +76,13 @@ export interface UpdatableMetadata { * ``` */ export function Injectable(): ClassDecorator { - return function (target: Function): void { - const existing = injectableMetadata.get(target as Constructor); + return function (target: Constructor): void { + const existing = injectableMetadata.get(target); injectableMetadata.set(target as Constructor, { injectable: true, dependencies: [], - ...(existing?.properties && { properties: existing.properties }) + ...(existing?.properties && {properties: existing.properties}) }); } as ClassDecorator; } @@ -117,13 +117,13 @@ export function Injectable(): ClassDecorator { * ``` */ export function Updatable(priority: number = 0): ClassDecorator { - return function (target: Function): void { + return function (target: Constructor): void { // 验证类原型上是否有update方法 const prototype = (target as Constructor & { prototype: { update?: unknown } }).prototype; - if (!prototype || typeof prototype.update !== 'function') { + 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." ); } @@ -246,10 +246,10 @@ export function createInstance( if (serviceType) { // 如果有显式的@Inject标记,使用标记的类型 - if (typeof serviceType === 'string' || typeof serviceType === 'symbol') { + 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/DI/index.ts b/packages/core/src/Core/DI/index.ts index 43803bd9..02564cd2 100644 --- a/packages/core/src/Core/DI/index.ts +++ b/packages/core/src/Core/DI/index.ts @@ -17,6 +17,6 @@ export { createInstance, injectProperties, registerInjectable -} from './Decorators'; +} from "./Decorators"; -export type { InjectableMetadata, UpdatableMetadata } from './Decorators'; +export type {InjectableMetadata, UpdatableMetadata} from "./Decorators"; diff --git a/packages/core/src/Core/Plugin.ts b/packages/core/src/Core/Plugin.ts index e00c1d55..fd0c5b3c 100644 --- a/packages/core/src/Core/Plugin.ts +++ b/packages/core/src/Core/Plugin.ts @@ -1,5 +1,5 @@ -import type { Core } from '../Core'; -import type { ServiceContainer } from './ServiceContainer'; +import type {Core} from "../Core"; +import type {ServiceContainer} from "./ServiceContainer"; /** * 插件状态 @@ -8,17 +8,17 @@ export enum PluginState { /** * 未安装 */ - NotInstalled = 'not_installed', + NotInstalled = "not_installed", /** * 已安装 */ - Installed = 'installed', + Installed = "installed", /** * 安装失败 */ - Failed = 'failed' + Failed = "failed" } /** diff --git a/packages/core/src/Core/PluginManager.ts b/packages/core/src/Core/PluginManager.ts index a25607c4..01fee992 100644 --- a/packages/core/src/Core/PluginManager.ts +++ b/packages/core/src/Core/PluginManager.ts @@ -1,10 +1,10 @@ -import { IPlugin, IPluginMetadata, PluginState } from './Plugin'; -import type { IService } from './ServiceContainer'; -import type { Core } from '../Core'; -import type { ServiceContainer } from './ServiceContainer'; -import { createLogger } from '../Utils/Logger'; +import {IPlugin, IPluginMetadata, PluginState} from "./Plugin"; +import type {IService} from "./ServiceContainer"; +import type {Core} from "../Core"; +import type {ServiceContainer} from "./ServiceContainer"; +import {createLogger} from "../Utils/Logger"; -const logger = createLogger('PluginManager'); +const logger = createLogger("PluginManager"); /** * 插件管理器 @@ -57,7 +57,7 @@ export class PluginManager implements IService { public initialize(core: Core, services: ServiceContainer): void { this._core = core; this._services = services; - logger.info('PluginManager initialized'); + logger.info("PluginManager initialized"); } /** @@ -70,7 +70,7 @@ export class PluginManager implements IService { */ public async install(plugin: IPlugin): Promise { if (!this._core || !this._services) { - throw new Error('PluginManager not initialized. Call initialize() first.'); + throw new Error("PluginManager not initialized. Call initialize() first."); } // 检查是否已安装 @@ -213,7 +213,7 @@ export class PluginManager implements IService { if (missingDeps.length > 0) { throw new Error( - `Plugin ${plugin.name} has unmet dependencies: ${missingDeps.join(', ')}` + `Plugin ${plugin.name} has unmet dependencies: ${missingDeps.join(", ")}` ); } } @@ -235,7 +235,7 @@ export class PluginManager implements IService { if (dependents.length > 0) { throw new Error( - `Cannot uninstall plugin ${name}: it is required by ${dependents.join(', ')}` + `Cannot uninstall plugin ${name}: it is required by ${dependents.join(", ")}` ); } } @@ -261,6 +261,6 @@ export class PluginManager implements IService { this._core = null; this._services = null; - logger.info('PluginManager disposed'); + logger.info("PluginManager disposed"); } } diff --git a/packages/core/src/Core/ServiceContainer.ts b/packages/core/src/Core/ServiceContainer.ts index 50e34069..04e2ce3e 100644 --- a/packages/core/src/Core/ServiceContainer.ts +++ b/packages/core/src/Core/ServiceContainer.ts @@ -1,7 +1,7 @@ -import { createLogger } from '../Utils/Logger'; -import { isUpdatable as checkUpdatable, getUpdatableMetadata } from './DI'; +import {createLogger} from "../Utils/Logger"; +import {isUpdatable as checkUpdatable, getUpdatableMetadata} from "./DI"; -const logger = createLogger('ServiceContainer'); +const logger = createLogger("ServiceContainer"); /** * 服务基础接口 @@ -30,12 +30,12 @@ export enum ServiceLifetime { /** * 单例模式 - 整个应用生命周期内只有一个实例 */ - Singleton = 'singleton', + Singleton = "singleton", /** * 瞬时模式 - 每次请求都创建新实例 */ - Transient = 'transient' + Transient = "transient" } /** @@ -139,7 +139,7 @@ export class ServiceContainer { this._services.set(type as ServiceType, { type: type as ServiceType, - ...(factory && { factory: factory as (container: ServiceContainer) => IService }), + ...(factory && {factory: factory as (container: ServiceContainer) => IService}), lifetime: ServiceLifetime.Singleton }); @@ -171,7 +171,7 @@ export class ServiceContainer { this._services.set(type as ServiceType, { type: type as ServiceType, - ...(factory && { factory: factory as (container: ServiceContainer) => IService }), + ...(factory && {factory: factory as (container: ServiceContainer) => IService}), lifetime: ServiceLifetime.Transient }); @@ -208,7 +208,7 @@ export class ServiceContainer { if (checkUpdatable(type)) { const metadata = getUpdatableMetadata(type); const priority = metadata?.priority ?? 0; - this._updatableServices.push({ instance, priority }); + this._updatableServices.push({instance, priority}); // 按优先级排序(数值越小越先执行) this._updatableServices.sort((a, b) => a.priority - b.priority); @@ -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}`); } @@ -272,7 +272,7 @@ export class ServiceContainer { if (checkUpdatable(registration.type)) { const metadata = getUpdatableMetadata(registration.type); const priority = metadata?.priority ?? 0; - this._updatableServices.push({ instance, priority }); + this._updatableServices.push({instance, priority}); // 按优先级排序(数值越小越先执行) this._updatableServices.sort((a, b) => a.priority - b.priority); @@ -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); } @@ -363,7 +363,7 @@ export class ServiceContainer { this._services.clear(); this._updatableServices = []; - logger.debug('Cleared all services'); + logger.debug("Cleared all services"); } /** @@ -391,7 +391,7 @@ export class ServiceContainer { * ``` */ public updateAll(deltaTime?: number): void { - for (const { instance } of this._updatableServices) { + for (const {instance} of this._updatableServices) { (instance as IService & { update: (deltaTime?: number) => void }).update(deltaTime); } } diff --git a/packages/core/src/ECS/Component.ts b/packages/core/src/ECS/Component.ts index 31ecc878..2e057d00 100644 --- a/packages/core/src/ECS/Component.ts +++ b/packages/core/src/ECS/Component.ts @@ -1,4 +1,4 @@ -import type { IComponent } from '../Types'; +import type {IComponent} from "../Types"; /** * 游戏组件基类 @@ -36,7 +36,16 @@ export abstract class Component implements IComponent { * * 用于为每个组件分配唯一的ID。 */ - public static _idGenerator: number = 0; + private static _nextId: number = 0; + + /** + * 获取下一个组件ID(只读) + * + * @returns 下一个将要分配的组件ID + */ + public static get nextComponentId(): number { + return Component._nextId; + } /** * 组件唯一标识符 @@ -58,7 +67,7 @@ export abstract class Component implements IComponent { * 自动分配唯一ID给组件。 */ constructor() { - this.id = Component._idGenerator++; + this.id = Component._nextId++; } /** diff --git a/packages/core/src/ECS/Core/ArchetypeSystem.ts b/packages/core/src/ECS/Core/ArchetypeSystem.ts index b56cddb6..0687a0b0 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 {Entity} from "../Entity"; +import {ComponentType, ComponentRegistry} from "./ComponentStorage"; +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); } - + /** * 查询包含指定组件组合的原型 * @@ -126,18 +126,18 @@ export class ArchetypeSystem { * @param operation 查询操作类型:'AND'(包含所有)或 'OR'(包含任意) * @returns 匹配的原型列表及实体总数 */ - public queryArchetypes(componentTypes: ComponentType[], operation: 'AND' | 'OR' = 'AND'): ArchetypeQueryResult { + public queryArchetypes(componentTypes: ComponentType[], operation: "AND" | "OR" = "AND"): ArchetypeQueryResult { const matchingArchetypes: Archetype[] = []; let totalEntities = 0; - if (operation === 'AND') { + if (operation === "AND") { if (componentTypes.length === 0) { for (const archetype of this._allArchetypes) { matchingArchetypes.push(archetype); totalEntities += archetype.entities.size; } - return { archetypes: matchingArchetypes, totalEntities }; + return {archetypes: matchingArchetypes, totalEntities}; } if (componentTypes.length === 1) { @@ -148,7 +148,7 @@ export class ArchetypeSystem { totalEntities += archetype.entities.size; } } - return { archetypes: matchingArchetypes, totalEntities }; + return {archetypes: matchingArchetypes, totalEntities}; } let smallestSet: Set | undefined; @@ -157,7 +157,7 @@ export class ArchetypeSystem { for (const componentType of componentTypes) { const archetypes = this._componentToArchetypes.get(componentType); if (!archetypes || archetypes.size === 0) { - return { archetypes: [], totalEntities: 0 }; + return {archetypes: [], totalEntities: 0}; } if (archetypes.size < smallestSize) { smallestSize = archetypes.size; @@ -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..68a4eadf 100644 --- a/packages/core/src/ECS/Core/ComponentPool.ts +++ b/packages/core/src/ECS/Core/ComponentPool.ts @@ -1,4 +1,4 @@ -import { Component } from '../Component'; +import {Component} from "../Component"; /** * 组件对象池,用于复用组件实例以减少内存分配 @@ -183,7 +183,7 @@ export class ComponentPoolManager { acquireComponent(componentName: string): T | null { const pool = this.pools.get(componentName); - this.trackUsage(componentName, 'create'); + this.trackUsage(componentName, "create"); return pool ? (pool.acquire() as T) : null; } @@ -194,7 +194,7 @@ export class ComponentPoolManager { releaseComponent(componentName: string, component: T): void { const pool = this.pools.get(componentName); - this.trackUsage(componentName, 'release'); + this.trackUsage(componentName, "release"); if (pool) { pool.release(component); @@ -204,7 +204,7 @@ export class ComponentPoolManager { /** * 追踪使用情况 */ - private trackUsage(componentName: string, action: 'create' | 'release'): void { + private trackUsage(componentName: string, action: "create" | "release"): void { let tracker = this.usageTracker.get(componentName); if (!tracker) { @@ -216,7 +216,7 @@ export class ComponentPoolManager { this.usageTracker.set(componentName, tracker); } - if (action === 'create') { + if (action === "create") { tracker.createCount++; } else { tracker.releaseCount++; @@ -289,12 +289,12 @@ export class ComponentPoolManager { */ getGlobalStats(): Array<{ componentName: string; - poolStats: ReturnType['getStats']>; + poolStats: ReturnType["getStats"]>; usage: ComponentUsageTracker | undefined; }> { const stats: Array<{ componentName: string; - poolStats: ReturnType['getStats']>; + poolStats: ReturnType["getStats"]>; usage: ComponentUsageTracker | undefined; }> = []; @@ -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..64ff43c5 100644 --- a/packages/core/src/ECS/Core/ComponentStorage.ts +++ b/packages/core/src/ECS/Core/ComponentStorage.ts @@ -1,13 +1,12 @@ -import { Component } from '../Component'; -import { BitMask64Utils, BitMask64Data } from '../Utils/BigIntCompatibility'; -import { SoAStorage, SupportedTypedArray } from './SoAStorage'; -import { createLogger } from '../../Utils/Logger'; -import { getComponentTypeName } from '../Decorators'; -import { ComponentRegistry, ComponentType } from './ComponentStorage/ComponentRegistry'; +import {Component} from "../Component"; +import {BitMask64Utils, BitMask64Data} from "../Utils/BigIntCompatibility"; +import {SoAStorage, SupportedTypedArray} from "./SoAStorage"; +import {createLogger} from "../../Utils/Logger"; +import {getComponentTypeName} from "../Decorators"; +import {ComponentRegistry, ComponentType} from "./ComponentStorage/ComponentRegistry"; // 导出核心类型 -export { ComponentRegistry, ComponentType }; - +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; // 永远无空洞 @@ -172,7 +171,7 @@ export class ComponentStorage { * 管理所有组件类型的存储器 */ export class ComponentStorageManager { - private static readonly _logger = createLogger('ComponentStorage'); + private static readonly _logger = createLogger("ComponentStorage"); private storages = new Map | SoAStorage>(); /** @@ -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..c3a8f639 100644 --- a/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts +++ b/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts @@ -1,7 +1,7 @@ -import { Component } from '../../Component'; -import { BitMask64Utils, BitMask64Data } from '../../Utils/BigIntCompatibility'; -import { createLogger } from '../../../Utils/Logger'; -import { getComponentTypeName } from '../../Decorators'; +import {Component} from "../../Component"; +import {BitMask64Utils, BitMask64Data} from "../../Utils/BigIntCompatibility"; +import {createLogger} from "../../../Utils/Logger"; +import {getComponentTypeName} from "../../Decorators"; /** * 组件类型定义 @@ -13,10 +13,10 @@ export type ComponentType = new (...args: any[] * 管理组件类型的位掩码分配 */ export class ComponentRegistry { - protected static readonly _logger = createLogger('ComponentStorage'); - private static componentTypes = new Map(); - private static bitIndexToType = new Map(); - private static componentNameToType = new Map(); + protected static readonly _logger = createLogger("ComponentStorage"); + private static componentTypes = new Map(); + private static bitIndexToType = new Map(); + private static componentNameToType = new Map(); private static componentNameToId = new Map(); private static maskCache = new Map(); private static nextBitIndex = 0; @@ -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)!; } @@ -175,13 +175,13 @@ export class ComponentRegistry { */ public static createComponentMask(componentNames: string[]): BitMask64Data { const sortedNames = [...componentNames].sort(); - const cacheKey = `multi:${sortedNames.join(',')}`; - + 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/EventBus.ts b/packages/core/src/ECS/Core/EventBus.ts index b51b0e92..00c01348 100644 --- a/packages/core/src/ECS/Core/EventBus.ts +++ b/packages/core/src/ECS/Core/EventBus.ts @@ -1,6 +1,6 @@ -import { - IEventBus, - IEventListenerConfig, +import { + IEventBus, + IEventListenerConfig, IEventStats, IEventData, IEntityEventData, @@ -8,34 +8,34 @@ import { ISystemEventData, ISceneEventData, IPerformanceEventData -} from '../../Types'; -import { createLogger } from '../../Utils/Logger'; -import { - TypeSafeEventSystem, - EventListenerConfig, - EventStats -} from './EventSystem'; +} from "../../Types"; +import {createLogger} from "../../Utils/Logger"; +import { + TypeSafeEventSystem, + EventListenerConfig, + EventStats +} from "./EventSystem"; import { ECSEventType, EventPriority, EventTypeValidator -} from '../CoreEvents'; +} from "../CoreEvents"; /** * 增强的事件总线实现 * 基于TypeSafeEventSystem,提供类型安全的事件发布订阅机制 */ export class EventBus implements IEventBus { - private static readonly _logger = createLogger('EventBus'); + private static readonly _logger = createLogger("EventBus"); private eventSystem: TypeSafeEventSystem; private eventIdCounter = 0; private isDebugMode = false; - + constructor(debugMode: boolean = false) { this.eventSystem = new TypeSafeEventSystem(); this.isDebugMode = debugMode; } - + /** * 发射事件 * @param eventType 事件类型 @@ -53,7 +53,7 @@ export class EventBus implements IEventBus { this.eventSystem.emitSync(eventType, finalData); } - + /** * 异步发射事件 * @param eventType 事件类型 @@ -71,7 +71,7 @@ export class EventBus implements IEventBus { await this.eventSystem.emit(eventType, finalData); } - + /** * 监听事件 * @param eventType 事件类型 @@ -80,26 +80,26 @@ export class EventBus implements IEventBus { * @returns 监听器ID */ public on( - eventType: string, - handler: (data: T) => void, + eventType: string, + handler: (data: T) => void, config: IEventListenerConfig = {} ): string { this.validateEventType(eventType); - + const eventConfig: EventListenerConfig = { once: config.once || false, priority: config.priority || EventPriority.NORMAL, async: config.async || false, context: config.context }; - + if (this.isDebugMode) { EventBus._logger.info(`添加监听器: ${eventType}`, eventConfig); } - + return this.eventSystem.on(eventType, handler, eventConfig); } - + /** * 监听事件(一次性) * @param eventType 事件类型 @@ -108,13 +108,13 @@ export class EventBus implements IEventBus { * @returns 监听器ID */ public once( - eventType: string, - handler: (data: T) => void, + eventType: string, + handler: (data: T) => void, config: IEventListenerConfig = {} ): string { - return this.on(eventType, handler, { ...config, once: true }); + return this.on(eventType, handler, {...config, once: true}); } - + /** * 异步监听事件 * @param eventType 事件类型 @@ -123,13 +123,13 @@ export class EventBus implements IEventBus { * @returns 监听器ID */ public onAsync( - eventType: string, - handler: (data: T) => Promise, + eventType: string, + handler: (data: T) => Promise, config: IEventListenerConfig = {} ): string { - return this.on(eventType, handler as any, { ...config, async: true }); + return this.on(eventType, handler as any, {...config, async: true}); } - + /** * 移除事件监听器 * @param eventType 事件类型 @@ -139,10 +139,10 @@ export class EventBus implements IEventBus { if (this.isDebugMode) { EventBus._logger.info(`移除监听器: ${listenerId} 事件: ${eventType}`); } - + return this.eventSystem.off(eventType, listenerId); } - + /** * 移除指定事件类型的所有监听器 * @param eventType 事件类型 @@ -151,10 +151,10 @@ export class EventBus implements IEventBus { if (this.isDebugMode) { EventBus._logger.info(`移除所有监听器: ${eventType}`); } - + this.eventSystem.offAll(eventType); } - + /** * 检查是否有指定事件的监听器 * @param eventType 事件类型 @@ -162,14 +162,14 @@ export class EventBus implements IEventBus { public hasListeners(eventType: string): boolean { return this.eventSystem.hasListeners(eventType); } - + /** * 获取事件统计信息 * @param eventType 事件类型(可选) */ public getStats(eventType?: string): IEventStats | Map { const stats = this.eventSystem.getStats(eventType); - + if (stats instanceof Map) { // 转换Map中的每个EventStats为IEventStats const result = new Map(); @@ -181,18 +181,18 @@ export class EventBus implements IEventBus { return this.convertEventStats(stats); } } - + /** * 清空所有监听器 */ public clear(): void { if (this.isDebugMode) { - EventBus._logger.info('清空所有监听器'); + EventBus._logger.info("清空所有监听器"); } - + this.eventSystem.clear(); } - + /** * 启用或禁用事件系统 * @param enabled 是否启用 @@ -200,7 +200,7 @@ export class EventBus implements IEventBus { public setEnabled(enabled: boolean): void { this.eventSystem.setEnabled(enabled); } - + /** * 设置调试模式 * @param debug 是否启用调试 @@ -208,7 +208,7 @@ export class EventBus implements IEventBus { public setDebugMode(debug: boolean): void { this.isDebugMode = debug; } - + /** * 设置最大监听器数量 * @param max 最大数量 @@ -216,7 +216,7 @@ export class EventBus implements IEventBus { public setMaxListeners(max: number): void { this.eventSystem.setMaxListeners(max); } - + /** * 获取监听器数量 * @param eventType 事件类型 @@ -224,7 +224,7 @@ export class EventBus implements IEventBus { public getListenerCount(eventType: string): number { return this.eventSystem.getListenerCount(eventType); } - + /** * 设置事件批处理配置 * @param eventType 事件类型 @@ -238,7 +238,7 @@ export class EventBus implements IEventBus { enabled: true }); } - + /** * 刷新指定事件的批处理队列 * @param eventType 事件类型 @@ -246,7 +246,7 @@ export class EventBus implements IEventBus { public flushBatch(eventType: string): void { this.eventSystem.flushBatch(eventType); } - + /** * 重置事件统计 * @param eventType 事件类型(可选) @@ -254,9 +254,9 @@ export class EventBus implements IEventBus { public resetStats(eventType?: string): void { this.eventSystem.resetStats(eventType); } - + // 便捷方法:发射预定义的ECS事件 - + /** * 发射实体创建事件 * @param entityData 实体事件数据 @@ -320,59 +320,59 @@ export class EventBus implements IEventBus { public emitPerformanceWarning(performanceData: IPerformanceEventData): void { this.emit(ECSEventType.PERFORMANCE_WARNING, performanceData); } - + // 便捷方法:监听预定义的ECS事件 - + /** * 监听实体创建事件 * @param handler 事件处理器 * @param config 监听器配置 */ public onEntityCreated( - handler: (data: IEntityEventData) => void, + handler: (data: IEntityEventData) => void, config?: IEventListenerConfig ): string { return this.on(ECSEventType.ENTITY_CREATED, handler, config); } - + /** * 监听组件添加事件 * @param handler 事件处理器 * @param config 监听器配置 */ public onComponentAdded( - handler: (data: IComponentEventData) => void, + handler: (data: IComponentEventData) => void, config?: IEventListenerConfig ): string { return this.on(ECSEventType.COMPONENT_ADDED, handler, config); } - + /** * 监听系统错误事件 * @param handler 事件处理器 * @param config 监听器配置 */ public onSystemError( - handler: (data: ISystemEventData) => void, + handler: (data: ISystemEventData) => void, config?: IEventListenerConfig ): string { return this.on(ECSEventType.SYSTEM_ERROR, handler, config); } - + /** * 监听性能警告事件 * @param handler 事件处理器 * @param config 监听器配置 */ public onPerformanceWarning( - handler: (data: IPerformanceEventData) => void, + handler: (data: IPerformanceEventData) => void, config?: IEventListenerConfig ): string { return this.on(ECSEventType.PERFORMANCE_WARNING, handler, config); } - + // 私有方法 - + /** * 验证事件类型(仅在debug模式下执行,提升性能) * @param eventType 事件类型 @@ -387,7 +387,7 @@ export class EventBus implements IEventBus { } } } - + /** * 增强事件数据 * @param eventType 事件类型 @@ -399,12 +399,12 @@ export class EventBus implements IEventBus { return { timestamp: Date.now(), eventId: `${eventType}_${++this.eventIdCounter}`, - source: 'EventBus' + source: "EventBus" } as T & IEventData; } - + const enhanced = data as T & IEventData; - + // 如果数据还没有基础事件属性,添加它们 if (!enhanced.timestamp) { enhanced.timestamp = Date.now(); @@ -413,12 +413,12 @@ export class EventBus implements IEventBus { enhanced.eventId = `${eventType}_${++this.eventIdCounter}`; } if (!enhanced.source) { - enhanced.source = 'EventBus'; + enhanced.source = "EventBus"; } - + return enhanced; } - + /** * 转换EventStats为IEventStats * @param stats EventStats实例 @@ -441,7 +441,7 @@ export class EventBus implements IEventBus { */ export class GlobalEventBus { private static instance: EventBus; - + /** * 获取全局事件总线实例 * @param debugMode 是否启用调试模式 @@ -452,7 +452,7 @@ export class GlobalEventBus { } return this.instance; } - + /** * 重置全局事件总线实例 * @param debugMode 是否启用调试模式 @@ -466,4 +466,3 @@ export class GlobalEventBus { } } - \ No newline at end of file diff --git a/packages/core/src/ECS/Core/EventSystem.ts b/packages/core/src/ECS/Core/EventSystem.ts index 0786e4fe..f252d796 100644 --- a/packages/core/src/ECS/Core/EventSystem.ts +++ b/packages/core/src/ECS/Core/EventSystem.ts @@ -1,4 +1,4 @@ -import { createLogger } from '../../Utils/Logger'; +import {createLogger} from "../../Utils/Logger"; /** * 事件处理器函数类型 @@ -68,7 +68,7 @@ export interface EventBatchConfig { * 支持同步/异步事件、优先级、批处理等功能 */ export class TypeSafeEventSystem { - private static readonly _logger = createLogger('EventSystem'); + private static readonly _logger = createLogger("EventSystem"); private listeners = new Map(); private stats = new Map(); private batchQueue = new Map(); @@ -105,7 +105,7 @@ export class TypeSafeEventSystem { handler: EventHandler, config: EventListenerConfig = {} ): string { - return this.addListener(eventType, handler, { ...config, once: true }); + return this.addListener(eventType, handler, {...config, once: true}); } /** @@ -120,7 +120,7 @@ export class TypeSafeEventSystem { handler: AsyncEventHandler, config: EventListenerConfig = {} ): string { - return this.addListener(eventType, handler, { ...config, async: true }); + return this.addListener(eventType, handler, {...config, async: true}); } /** @@ -133,7 +133,7 @@ export class TypeSafeEventSystem { const listeners = this.listeners.get(eventType); if (!listeners) return false; - const index = listeners.findIndex(l => l.id === listenerId); + const index = listeners.findIndex((l) => l.id === listenerId); if (index === -1) return false; listeners.splice(index, 1); @@ -340,7 +340,7 @@ export class TypeSafeEventSystem { // 检查监听器数量限制 if (listeners.length >= this.maxListeners) { TypeSafeEventSystem._logger.warn(`事件类型 ${eventType} 的监听器数量超过最大限制 (${this.maxListeners})`); - return ''; + return ""; } const listenerId = `listener_${this.nextListenerId++}`; @@ -379,8 +379,8 @@ export class TypeSafeEventSystem { const sortedListeners = this.sortListenersByPriority(listeners); // 分离同步和异步监听器 - const syncListeners = sortedListeners.filter(l => !l.config.async); - const asyncListeners = sortedListeners.filter(l => l.config.async); + const syncListeners = sortedListeners.filter((l) => !l.config.async); + const asyncListeners = sortedListeners.filter((l) => l.config.async); // 执行同步监听器 for (const listener of syncListeners) { @@ -447,7 +447,7 @@ export class TypeSafeEventSystem { if (!listeners) return; for (const id of listenerIds) { - const index = listeners.findIndex(l => l.id === id); + const index = listeners.findIndex((l) => l.id === id); if (index !== -1) { listeners.splice(index, 1); } @@ -578,4 +578,3 @@ export class TypeSafeEventSystem { */ export const GlobalEventSystem = new TypeSafeEventSystem(); - \ 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..575d57b7 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 {EventBus, GlobalEventBus} from "../EventBus"; +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..c2c71d29 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..d0014064 100644 --- a/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts +++ b/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts @@ -1,4 +1,4 @@ -import { Component } from '../../Component'; +import {Component} from "../../Component"; /** * 组件构建器 - 提供流式API创建组件 @@ -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..e4defd60 100644 --- a/packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts +++ b/packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts @@ -1,13 +1,13 @@ -import { Entity } from '../../Entity'; -import { Component } from '../../Component'; -import { IScene } from '../../IScene'; -import { ComponentType } from '../ComponentStorage'; -import { QuerySystem, QueryBuilder } from '../QuerySystem'; -import { TypeSafeEventSystem } from '../EventSystem'; -import { EntityBuilder } from './EntityBuilder'; -import { SceneBuilder } from './SceneBuilder'; -import { ComponentBuilder } from './ComponentBuilder'; -import { EntityBatchOperator } from './EntityBatchOperator'; +import {Entity} from "../../Entity"; +import {Component} from "../../Component"; +import {IScene} from "../../IScene"; +import {ComponentType} from "../ComponentStorage"; +import {QuerySystem, QueryBuilder} from "../QuerySystem"; +import {TypeSafeEventSystem} from "../EventSystem"; +import {EntityBuilder} from "./EntityBuilder"; +import {SceneBuilder} from "./SceneBuilder"; +import {ComponentBuilder} from "./ComponentBuilder"; +import {EntityBatchOperator} from "./EntityBatchOperator"; /** * ECS流式API主入口 @@ -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..30a2c368 100644 --- a/packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts +++ b/packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts @@ -1,6 +1,6 @@ -import { Entity } from '../../Entity'; -import { Component } from '../../Component'; -import { ComponentType } from '../ComponentStorage'; +import {Entity} from "../../Entity"; +import {Component} from "../../Component"; +import {ComponentType} from "../ComponentStorage"; /** * 实体批量操作器 @@ -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..5943344f 100644 --- a/packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts +++ b/packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts @@ -1,7 +1,7 @@ -import { Entity } from '../../Entity'; -import { Component } from '../../Component'; -import { IScene } from '../../IScene'; -import { ComponentType, ComponentStorageManager } from '../ComponentStorage'; +import {Entity} from "../../Entity"; +import {Component} from "../../Component"; +import {IScene} from "../../IScene"; +import {ComponentType, ComponentStorageManager} from "../ComponentStorage"; /** * 实体构建器 - 提供流式API创建和配置实体 @@ -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..95443690 100644 --- a/packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts +++ b/packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts @@ -1,7 +1,7 @@ -import { Entity } from '../../Entity'; -import { Scene } from '../../Scene'; -import { EntitySystem } from '../../Systems/EntitySystem'; -import { EntityBuilder } from './EntityBuilder'; +import {Entity} from "../../Entity"; +import {Scene} from "../../Scene"; +import {EntitySystem} from "../../Systems/EntitySystem"; +import {EntityBuilder} from "./EntityBuilder"; /** * 场景构建器 - 提供流式API创建和配置场景 @@ -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..9a4ba644 100644 --- a/packages/core/src/ECS/Core/FluentAPI/index.ts +++ b/packages/core/src/ECS/Core/FluentAPI/index.ts @@ -1,5 +1,5 @@ -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 {EntityBuilder} from "./EntityBuilder"; +export {SceneBuilder} from "./SceneBuilder"; +export {ComponentBuilder} from "./ComponentBuilder"; +export {EntityBatchOperator} from "./EntityBatchOperator"; +export {ECSFluentAPI, createECSAPI, initializeECS, ECS} from "./ECSFluentAPI"; diff --git a/packages/core/src/ECS/Core/Query/TypedQuery.ts b/packages/core/src/ECS/Core/Query/TypedQuery.ts index 2c7169d4..baf9e086 100644 --- a/packages/core/src/ECS/Core/Query/TypedQuery.ts +++ b/packages/core/src/ECS/Core/Query/TypedQuery.ts @@ -4,9 +4,9 @@ * 提供完整的TypeScript类型推断,在编译时确保类型安全 */ -import type { Entity } from '../../Entity'; -import type { ComponentConstructor } from '../../../Types/TypeHelpers'; -import { Matcher, type QueryCondition } from '../../Utils/Matcher'; +import type {Entity} from "../../Entity"; +import type {ComponentConstructor} from "../../../Types/TypeHelpers"; +import {Matcher, type QueryCondition} from "../../Utils/Matcher"; /** * 类型安全的查询结果 @@ -326,8 +326,8 @@ export class TypedQueryBuilder< all: [...this._all] as ComponentConstructor[], any: [...this._any] as ComponentConstructor[], none: [...this._none] as ComponentConstructor[], - ...(this._tag !== undefined && { tag: this._tag }), - ...(this._name !== undefined && { name: this._name }) + ...(this._tag !== undefined && {tag: this._tag}), + ...(this._name !== undefined && {name: this._name}) }; } diff --git a/packages/core/src/ECS/Core/Query/index.ts b/packages/core/src/ECS/Core/Query/index.ts index 384cd4db..67f73eca 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 +export {QuerySystem} from "../QuerySystem"; +export {ECSFluentAPI, createECSAPI} from "../FluentAPI"; diff --git a/packages/core/src/ECS/Core/QuerySystem.ts b/packages/core/src/ECS/Core/QuerySystem.ts index 80b462c2..0f6756cc 100644 --- a/packages/core/src/ECS/Core/QuerySystem.ts +++ b/packages/core/src/ECS/Core/QuerySystem.ts @@ -1,14 +1,14 @@ -import { Entity } from '../Entity'; -import { Component } from '../Component'; -import { ComponentRegistry, ComponentType } from './ComponentStorage'; -import { BitMask64Utils, BitMask64Data } from '../Utils/BigIntCompatibility'; -import { createLogger } from '../../Utils/Logger'; -import { getComponentTypeName } from '../Decorators'; -import { Archetype, ArchetypeSystem } from './ArchetypeSystem'; -import { ReactiveQuery, ReactiveQueryConfig } from './ReactiveQuery'; -import { QueryCondition, QueryConditionType, QueryResult } from './QueryTypes'; +import {Entity} from "../Entity"; +import {Component} from "../Component"; +import {ComponentRegistry, ComponentType} from "./ComponentStorage"; +import {BitMask64Utils, BitMask64Data} from "../Utils/BigIntCompatibility"; +import {createLogger} from "../../Utils/Logger"; +import {getComponentTypeName} from "../Decorators"; +import {Archetype, ArchetypeSystem} from "./ArchetypeSystem"; +import {ReactiveQuery, ReactiveQueryConfig} from "./ReactiveQuery"; +import {QueryCondition, QueryConditionType, QueryResult} from "./QueryTypes"; -export { QueryCondition, QueryConditionType, QueryResult }; +export {QueryCondition, QueryConditionType, QueryResult}; /** * 实体索引结构 @@ -30,20 +30,20 @@ interface QueryCacheEntry { /** * 高性能实体查询系统 - * + * * 提供快速的实体查询功能,支持按组件类型、标签、名称等多种方式查询实体。 - * + * * @example * ```typescript * // 查询所有包含Position和Velocity组件的实体 * const movingEntities = querySystem.queryAll(PositionComponent, VelocityComponent); - * + * * // 查询特定标签的实体 * const playerEntities = querySystem.queryByTag(PLAYER_TAG); * ``` */ export class QuerySystem { - private _logger = createLogger('QuerySystem'); + private _logger = createLogger("QuerySystem"); private entities: Entity[] = []; private entityIndex: EntityIndex; @@ -92,10 +92,10 @@ export class QuerySystem { /** * 添加单个实体到查询系统 - * + * * 将新实体添加到查询系统中,并自动更新相关索引。 * 为了提高批量添加性能,可以延迟缓存清理。 - * + * * @param entity 要添加的实体 * @param deferCacheClear 是否延迟缓存清理(用于批量操作) */ @@ -121,17 +121,17 @@ export class QuerySystem { /** * 批量添加实体 - * + * * 高效地批量添加多个实体,减少缓存清理次数。 * 使用Set来避免O(n)的重复检查。 - * + * * @param entities 要添加的实体列表 */ public addEntities(entities: Entity[]): void { if (entities.length === 0) return; // 使用Set来快速检查重复 - const existingIds = new Set(this.entities.map(e => e.id)); + const existingIds = new Set(this.entities.map((e) => e.id)); let addedCount = 0; for (const entity of entities) { @@ -155,10 +155,10 @@ export class QuerySystem { /** * 批量添加实体(无重复检查版本) - * + * * 假设所有实体都是新的,跳过重复检查以获得最大性能。 * 仅在确保没有重复实体时使用。 - * + * * @param entities 要添加的实体列表 */ public addEntitiesUnchecked(entities: Entity[]): void { @@ -437,13 +437,13 @@ export class QuerySystem { /** * 按标签查询实体 - * + * * 返回具有指定标签的所有实体。 * 标签查询使用专用索引,具有很高的查询性能。 - * + * * @param tag 要查询的标签值 * @returns 查询结果,包含匹配的实体和性能信息 - * + * * @example * ```typescript * // 查询所有玩家实体 @@ -485,13 +485,13 @@ export class QuerySystem { /** * 按名称查询实体 - * + * * 返回具有指定名称的所有实体。 * 名称查询使用专用索引,适用于查找特定的命名实体。 - * + * * @param name 要查询的实体名称 * @returns 查询结果,包含匹配的实体和性能信息 - * + * * @example * ```typescript * // 查找名为"Player"的实体 @@ -533,13 +533,13 @@ export class QuerySystem { /** * 按单个组件类型查询实体 - * + * * 返回包含指定组件类型的所有实体。 * 这是最基础的查询方法,具有最高的查询性能。 - * + * * @param componentType 要查询的组件类型 * @returns 查询结果,包含匹配的实体和性能信息 - * + * * @example * ```typescript * // 查询所有具有位置组件的实体 @@ -550,7 +550,7 @@ export class QuerySystem { const startTime = performance.now(); this.queryStats.totalQueries++; - const cacheKey = this.generateCacheKey('component', [componentType]); + const cacheKey = this.generateCacheKey("component", [componentType]); // 检查缓存 const cached = this.getFromCache(cacheKey); @@ -627,7 +627,7 @@ export class QuerySystem { // 如果还是太满,移除最少使用的条目 if (this.queryCache.size >= this.cacheMaxSize) { let minHitCount = Infinity; - let oldestKey = ''; + let oldestKey = ""; let oldestTimestamp = Infinity; // 单次遍历找到最少使用或最旧的条目 @@ -679,10 +679,10 @@ export class QuerySystem { } // 多组件查询:使用排序后的类型名称创建键 - const sortKey = componentTypes.map(t => { + const sortKey = componentTypes.map((t) => { const name = getComponentTypeName(t); return name; - }).sort().join(','); + }).sort().join(","); const fullKey = `${prefix}:${sortKey}`; @@ -729,7 +729,7 @@ export class QuerySystem { config?: ReactiveQueryConfig ): ReactiveQuery { if (!componentTypes || componentTypes.length === 0) { - throw new Error('组件类型列表不能为空'); + throw new Error("组件类型列表不能为空"); } const mask = this.createComponentMask(componentTypes); @@ -747,7 +747,7 @@ export class QuerySystem { ); query.initializeWith(initialEntities); - const cacheKey = this.generateCacheKey('all', componentTypes); + const cacheKey = this.generateCacheKey("all", componentTypes); this._reactiveQueries.set(cacheKey, query); for (const type of componentTypes) { @@ -810,9 +810,9 @@ export class QuerySystem { */ private createComponentMask(componentTypes: ComponentType[]): BitMask64Data { // 生成缓存键 - const cacheKey = componentTypes.map(t => { + const cacheKey = componentTypes.map((t) => { return getComponentTypeName(t); - }).sort().join(','); + }).sort().join(","); // 检查缓存 const cached = this.componentMaskCache.get(cacheKey); @@ -821,7 +821,7 @@ export class QuerySystem { } // 使用ComponentRegistry而不是ComponentTypeManager,确保bitIndex一致 - let mask = BitMask64Utils.clone(BitMask64Utils.ZERO); + const mask = BitMask64Utils.clone(BitMask64Utils.ZERO); for (const type of componentTypes) { // 确保组件已注册 if (!ComponentRegistry.isRegistered(type)) { @@ -842,20 +842,40 @@ export class QuerySystem { public get version(): number { return this._version; } - + /** - * 获取所有实体 + * 查询所有实体 + * + * 返回场景中的所有实体,不进行任何过滤。 + * + * @returns 所有实体的只读数组 + * + * @example + * ```typescript + * const allEntities = scene.querySystem.queryAllEntities(); + * console.log(`场景中共有 ${allEntities.length} 个实体`); + * ``` */ - public getAllEntities(): readonly Entity[] { + public queryAllEntities(): readonly Entity[] { return this.entities; } - + + /** + * 获取所有实体 + * + * @deprecated 使用 queryAllEntities() 代替,以保持命名一致性 + * @see {@link queryAllEntities} + */ + public getAllEntities(): readonly Entity[] { + return this.queryAllEntities(); + } + /** * 获取系统统计信息 - * + * * 返回查询系统的详细统计信息,包括实体数量、索引状态、 * 查询性能统计等,用于性能监控和调试。 - * + * * @returns 系统统计信息对象 */ public getStats(): { @@ -881,7 +901,7 @@ export class QuerySystem { size: number; hitRate: string; }; - } { + } { return { entityCount: this.entities.length, indexStats: { @@ -892,19 +912,19 @@ export class QuerySystem { queryStats: { ...this.queryStats, cacheHitRate: this.queryStats.totalQueries > 0 ? - (this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + '%' : '0%' + (this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + "%" : "0%" }, optimizationStats: { - archetypeSystem: this.archetypeSystem.getAllArchetypes().map(a => ({ + archetypeSystem: this.archetypeSystem.getAllArchetypes().map((a) => ({ id: a.id, - componentTypes: a.componentTypes.map(t => getComponentTypeName(t)), + componentTypes: a.componentTypes.map((t) => getComponentTypeName(t)), entityCount: a.entities.size })) }, cacheStats: { size: this._reactiveQueries.size, hitRate: this.queryStats.totalQueries > 0 ? - (this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + '%' : '0%' + (this.queryStats.cacheHits / this.queryStats.totalQueries * 100).toFixed(2) + "%" : "0%" } }; } @@ -1002,7 +1022,7 @@ export class QuerySystem { ): Entity[] { switch (queryType) { case QueryConditionType.ALL: { - const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, 'AND'); + const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, "AND"); const entities: Entity[] = []; for (const archetype of archetypeResult.archetypes) { for (const entity of archetype.entities) { @@ -1012,7 +1032,7 @@ export class QuerySystem { return entities; } case QueryConditionType.ANY: { - const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, 'OR'); + const archetypeResult = this.archetypeSystem.queryArchetypes(componentTypes, "OR"); const entities: Entity[] = []; for (const archetype of archetypeResult.archetypes) { for (const entity of archetype.entities) { @@ -1023,7 +1043,7 @@ export class QuerySystem { } case QueryConditionType.NONE: { const mask = this.createComponentMask(componentTypes); - return this.entities.filter(entity => + return this.entities.filter((entity) => BitMask64Utils.hasNone(entity.componentMask, mask) ); } @@ -1139,10 +1159,10 @@ export class QuerySystem { /** * 查询构建器 - * + * * 提供链式API来构建复杂的实体查询条件。 * 支持组合多种查询条件,创建灵活的查询表达式。 - * + * * @example * ```typescript * const result = new QueryBuilder(querySystem) @@ -1152,7 +1172,7 @@ export class QuerySystem { * ``` */ export class QueryBuilder { - private _logger = createLogger('QueryBuilder'); + private _logger = createLogger("QueryBuilder"); private conditions: QueryCondition[] = []; private querySystem: QuerySystem; @@ -1162,7 +1182,7 @@ export class QueryBuilder { /** * 添加"必须包含所有组件"条件 - * + * * @param componentTypes 必须包含的组件类型 * @returns 查询构建器实例,支持链式调用 */ @@ -1177,7 +1197,7 @@ export class QueryBuilder { /** * 添加"必须包含任意组件"条件 - * + * * @param componentTypes 必须包含其中任意一个的组件类型 * @returns 查询构建器实例,支持链式调用 */ @@ -1192,7 +1212,7 @@ export class QueryBuilder { /** * 添加"不能包含任何组件"条件 - * + * * @param componentTypes 不能包含的组件类型 * @returns 查询构建器实例,支持链式调用 */ @@ -1207,9 +1227,9 @@ export class QueryBuilder { /** * 执行查询并返回结果 - * + * * 根据已添加的查询条件执行实体查询。 - * + * * @returns 查询结果,包含匹配的实体和性能信息 */ public execute(): QueryResult { @@ -1241,7 +1261,7 @@ export class QueryBuilder { * 创建组件掩码 */ private createComponentMask(componentTypes: ComponentType[]): BitMask64Data { - let mask = BitMask64Utils.clone(BitMask64Utils.ZERO); + const mask = BitMask64Utils.clone(BitMask64Utils.ZERO); for (const type of componentTypes) { try { const bitMask = ComponentRegistry.getBitMask(type); @@ -1255,13 +1275,13 @@ export class QueryBuilder { /** * 重置查询构建器 - * + * * 清除所有已添加的查询条件,重新开始构建查询。 - * + * * @returns 查询构建器实例,支持链式调用 */ public reset(): QueryBuilder { this.conditions = []; return this; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/Core/QueryTypes.ts b/packages/core/src/ECS/Core/QueryTypes.ts index 64a5acd5..c934f2bc 100644 --- a/packages/core/src/ECS/Core/QueryTypes.ts +++ b/packages/core/src/ECS/Core/QueryTypes.ts @@ -1,17 +1,17 @@ -import { ComponentType } from './ComponentStorage'; -import { BitMask64Data } from '../Utils/BigIntCompatibility'; -import { Entity } from '../Entity'; +import {ComponentType} from "./ComponentStorage"; +import {BitMask64Data} from "../Utils/BigIntCompatibility"; +import {Entity} from "../Entity"; /** * 查询条件类型 */ export enum QueryConditionType { /** 必须包含所有指定组件 */ - ALL = 'all', + ALL = "all", /** 必须包含任意一个指定组件 */ - ANY = 'any', + ANY = "any", /** 不能包含任何指定组件 */ - NONE = 'none' + NONE = "none" } /** diff --git a/packages/core/src/ECS/Core/ReactiveQuery.ts b/packages/core/src/ECS/Core/ReactiveQuery.ts index 55758480..ee244b1e 100644 --- a/packages/core/src/ECS/Core/ReactiveQuery.ts +++ b/packages/core/src/ECS/Core/ReactiveQuery.ts @@ -1,20 +1,20 @@ -import { Entity } from '../Entity'; -import { QueryCondition, QueryConditionType } from './QueryTypes'; -import { BitMask64Utils } from '../Utils/BigIntCompatibility'; -import { createLogger } from '../../Utils/Logger'; +import {Entity} from "../Entity"; +import {QueryCondition, QueryConditionType} from "./QueryTypes"; +import {BitMask64Utils} from "../Utils/BigIntCompatibility"; +import {createLogger} from "../../Utils/Logger"; -const logger = createLogger('ReactiveQuery'); +const logger = createLogger("ReactiveQuery"); /** * 响应式查询变化类型 */ export enum ReactiveQueryChangeType { /** 实体添加到查询结果 */ - ADDED = 'added', + ADDED = "added", /** 实体从查询结果移除 */ - REMOVED = 'removed', + REMOVED = "removed", /** 查询结果批量更新 */ - BATCH_UPDATE = 'batch_update' + BATCH_UPDATE = "batch_update" } /** @@ -136,9 +136,9 @@ 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(','); + .join(","); return `${typeStr}:${componentsStr}`; } @@ -153,8 +153,8 @@ export class ReactiveQuery { throw new Error(`Cannot subscribe to disposed ReactiveQuery ${this._id}`); } - if (typeof listener !== 'function') { - throw new TypeError('Listener must be a function'); + if (typeof listener !== "function") { + throw new TypeError("Listener must be a function"); } this._listeners.push(listener); @@ -239,7 +239,7 @@ export class ReactiveQuery { // 通知监听器 if (this._config.enableBatchMode) { - this.addToBatch('added', entity); + this.addToBatch("added", entity); } else { this.notifyListeners({ type: ReactiveQueryChangeType.ADDED, @@ -276,7 +276,7 @@ export class ReactiveQuery { // 通知监听器 if (this._config.enableBatchMode) { - this.addToBatch('removed', entity); + this.addToBatch("removed", entity); } else { this.notifyListeners({ type: ReactiveQueryChangeType.REMOVED, @@ -337,8 +337,8 @@ export class ReactiveQuery { /** * 添加到批量变化缓存 */ - private addToBatch(type: 'added' | 'removed', entity: Entity): void { - if (type === 'added') { + private addToBatch(type: "added" | "removed", entity: Entity): void { + if (type === "added") { this._batchChanges.added.push(entity); } else { this._batchChanges.removed.push(entity); diff --git a/packages/core/src/ECS/Core/ReferenceTracker.ts b/packages/core/src/ECS/Core/ReferenceTracker.ts index e884e2d9..128ef2ca 100644 --- a/packages/core/src/ECS/Core/ReferenceTracker.ts +++ b/packages/core/src/ECS/Core/ReferenceTracker.ts @@ -1,6 +1,6 @@ -import { Component } from '../Component'; -import type { Entity } from '../Entity'; -import type { IScene } from '../IScene'; +import {Component} from "../Component"; +import type {Entity} from "../Entity"; +import type {IScene} from "../IScene"; /** * WeakRef 接口定义 @@ -45,9 +45,9 @@ interface IWeakRefConstructor { * 优先使用原生 WeakRef,不支持时降级到 Polyfill */ const WeakRefImpl: IWeakRefConstructor = ( - (typeof globalThis !== 'undefined' && (globalThis as any).WeakRef) || - (typeof global !== 'undefined' && (global as any).WeakRef) || - (typeof window !== 'undefined' && (window as any).WeakRef) || + (typeof globalThis !== "undefined" && (globalThis as any).WeakRef) || + (typeof global !== "undefined" && (global as any).WeakRef) || + (typeof window !== "undefined" && (window as any).WeakRef) || WeakRefPolyfill ) as IWeakRefConstructor; diff --git a/packages/core/src/ECS/Core/SoAStorage.ts b/packages/core/src/ECS/Core/SoAStorage.ts index befce482..797f5160 100644 --- a/packages/core/src/ECS/Core/SoAStorage.ts +++ b/packages/core/src/ECS/Core/SoAStorage.ts @@ -1,6 +1,6 @@ -import { Component } from '../Component'; -import { ComponentType } from './ComponentStorage'; -import { createLogger } from '../../Utils/Logger'; +import {Component} from "../Component"; +import {ComponentType} from "./ComponentStorage"; +import {createLogger} from "../../Utils/Logger"; /** * 启用SoA优化装饰器 @@ -222,23 +222,23 @@ export class TypeInference { } = {}): string { const type = typeof value; - if (type === 'boolean') { - return 'uint8'; // 布尔值使用最小的无符号整数 + if (type === "boolean") { + return "uint8"; // 布尔值使用最小的无符号整数 } - if (type !== 'number') { - return 'float32'; // 非数值类型默认使用Float32 + if (type !== "number") { + return "float32"; // 非数值类型默认使用Float32 } - const { minValue, maxValue, precision, signed } = options; + const {minValue, maxValue, precision, signed} = options; // 如果显式要求精度,使用浮点数 if (precision === true) { // 检查是否需要双精度 if (Math.abs(value) > 3.4028235e+38 || (minValue !== undefined && Math.abs(minValue) > 3.4028235e+38) || (maxValue !== undefined && Math.abs(maxValue) > 3.4028235e+38)) { - return 'float64'; + return "float64"; } - return 'float32'; + return "float32"; } // 如果显式禁用精度,或者是整数值,尝试使用整数数组 @@ -251,48 +251,48 @@ export class TypeInference { if (needsSigned) { // 有符号整数 if (actualMin >= -128 && actualMax <= 127) { - return 'int8'; + return "int8"; } else if (actualMin >= -32768 && actualMax <= 32767) { - return 'int16'; + return "int16"; } else if (actualMin >= -2147483648 && actualMax <= 2147483647) { - return 'int32'; + return "int32"; } else { - return 'float64'; // 超出int32范围,使用双精度浮点 + return "float64"; // 超出int32范围,使用双精度浮点 } } else { // 无符号整数 if (actualMax <= 255) { - return 'uint8'; + return "uint8"; } else if (actualMax <= 65535) { - return 'uint16'; + return "uint16"; } else if (actualMax <= 4294967295) { - return 'uint32'; + return "uint32"; } else { - return 'float64'; // 超出uint32范围,使用双精度浮点 + return "float64"; // 超出uint32范围,使用双精度浮点 } } } // 默认情况:检查是否为小数 if (!Number.isInteger(value)) { - return 'float32'; + return "float32"; } // 整数值,但没有指定范围,根据值的大小选择 if (value >= 0 && value <= 255) { - return 'uint8'; + return "uint8"; } else if (value >= -128 && value <= 127) { - return 'int8'; + return "int8"; } else if (value >= 0 && value <= 65535) { - return 'uint16'; + return "uint16"; } else if (value >= -32768 && value <= 32767) { - return 'int16'; + return "int16"; } else if (value >= 0 && value <= 4294967295) { - return 'uint32'; + return "uint32"; } else if (value >= -2147483648 && value <= 2147483647) { - return 'int32'; + return "int32"; } else { - return 'float64'; + return "float64"; } } @@ -301,15 +301,15 @@ export class TypeInference { */ public static getTypedArrayConstructor(typeName: string): typeof Float32Array | typeof Float64Array | typeof Int32Array | typeof Uint32Array | typeof Int16Array | typeof Uint16Array | typeof Int8Array | typeof Uint8Array | typeof Uint8ClampedArray { switch (typeName) { - case 'float32': return Float32Array; - case 'float64': return Float64Array; - case 'int32': return Int32Array; - case 'uint32': return Uint32Array; - case 'int16': return Int16Array; - case 'uint16': return Uint16Array; - case 'int8': return Int8Array; - case 'uint8': return Uint8Array; - case 'uint8clamped': return Uint8ClampedArray; + case "float32": return Float32Array; + case "float64": return Float64Array; + case "int32": return Int32Array; + case "uint32": return Uint32Array; + case "int16": return Int16Array; + case "uint16": return Uint16Array; + case "int8": return Int8Array; + case "uint8": return Uint8Array; + case "uint8clamped": return Uint8ClampedArray; default: return Float32Array; } } @@ -334,7 +334,7 @@ export type SupportedTypedArray = * 使用Structure of Arrays存储模式,在大规模批量操作时提供优异性能 */ export class SoAStorage { - private static readonly _logger = createLogger('SoAStorage'); + private static readonly _logger = createLogger("SoAStorage"); private fields = new Map(); private stringFields = new Map(); // 专门存储字符串 private serializedFields = new Map(); // 序列化存储Map/Set/Array @@ -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,13 +368,13 @@ 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') { + if (Object.prototype.hasOwnProperty.call(instance, key) && key !== "id") { const value = (instance as any)[key]; const type = typeof value; - - if (type === 'number') { + + if (type === "number") { if (highPrecisionFields.has(key)) { // 标记为高精度,作为复杂对象处理 // 不添加到fields,会在updateComponentAtIndex中自动添加到complexFields @@ -416,7 +416,7 @@ export class SoAStorage { // 默认使用Float32Array this.fields.set(key, new Float32Array(this._capacity)); } - } else if (type === 'boolean') { + } else if (type === "boolean") { // 布尔值默认使用Uint8Array存储为0/1(更节省内存) if (uint8Fields.has(key) || (!float32Fields.has(key) && !float64Fields.has(key))) { this.fields.set(key, new Uint8Array(this._capacity)); @@ -424,10 +424,10 @@ export class SoAStorage { // 兼容性:如果显式指定浮点类型则使用原有方式 this.fields.set(key, new Float32Array(this._capacity)); } - } else if (type === 'string') { + } else if (type === "string") { // 字符串专门处理 this.stringFields.set(key, new Array(this._capacity)); - } else if (type === 'object' && value !== null) { + } else if (type === "object" && value !== null) { // 处理集合类型 if (serializeMapFields.has(key) || serializeSetFields.has(key) || serializeArrayFields.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,14 +470,14 @@ 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') { + if (Object.prototype.hasOwnProperty.call(component, key) && key !== "id") { const value = (component as any)[key]; const type = typeof value; - - if (type === 'number') { + + if (type === "number") { if (highPrecisionFields.has(key) || !this.fields.has(key)) { // 标记为高精度或未在TypedArray中的数值作为复杂对象存储 complexFieldMap.set(key, value); @@ -486,8 +486,8 @@ export class SoAStorage { const array = this.fields.get(key)!; array[index] = value; } - } else if (type === 'boolean' && this.fields.has(key)) { - // 布尔值存储到TypedArray + } else if (type === "boolean" && this.fields.has(key)) { + // 布尔值存储到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字符串 */ @@ -536,17 +536,17 @@ export class SoAStorage { } } catch (error) { SoAStorage._logger.warn(`SoA序列化字段 ${key} 失败:`, error); - return '{}'; + 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,23 +564,23 @@ export class SoAStorage { return null; } } - + /** * 深拷贝对象 */ private deepClone(obj: any): any { - if (obj === null || typeof obj !== 'object') { + 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,46 +596,46 @@ export class SoAStorage { } return cloned; } - + // 普通对象 const cloned: any = {}; for (const key in obj) { - if (obj.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { cloned[key] = this.deepClone(obj[key]); } } 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') { + + 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++) { @@ -854,37 +854,37 @@ export class SoAStorage { if (array instanceof Float32Array) { bytesPerElement = 4; - typeName = 'float32'; + typeName = "float32"; } else if (array instanceof Float64Array) { bytesPerElement = 8; - typeName = 'float64'; + typeName = "float64"; } else if (array instanceof Int32Array) { bytesPerElement = 4; - typeName = 'int32'; + typeName = "int32"; } else if (array instanceof Uint32Array) { bytesPerElement = 4; - typeName = 'uint32'; + typeName = "uint32"; } else if (array instanceof Int16Array) { bytesPerElement = 2; - typeName = 'int16'; + typeName = "int16"; } else if (array instanceof Uint16Array) { bytesPerElement = 2; - typeName = 'uint16'; + typeName = "uint16"; } else if (array instanceof Int8Array) { bytesPerElement = 1; - typeName = 'int8'; + typeName = "int8"; } else if (array instanceof Uint8Array) { bytesPerElement = 1; - typeName = 'uint8'; + typeName = "uint8"; } else if (array instanceof Uint8ClampedArray) { bytesPerElement = 1; - typeName = 'uint8clamped'; + typeName = "uint8clamped"; } else { // 默认回退 bytesPerElement = 4; - typeName = 'unknown'; + 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..f4395c91 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 {ComponentPool, ComponentPoolManager} from "../ComponentPool"; +export {ComponentStorage, ComponentRegistry} from "../ComponentStorage"; +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..078595e7 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..a642c4ba 100644 --- a/packages/core/src/ECS/CoreEvents.ts +++ b/packages/core/src/ECS/CoreEvents.ts @@ -6,75 +6,75 @@ */ export enum ECSEventType { // 实体相关事件 - ENTITY_CREATED = 'entity:created', - ENTITY_DESTROYED = 'entity:destroyed', - ENTITY_ENABLED = 'entity:enabled', - ENTITY_DISABLED = 'entity:disabled', - ENTITY_TAG_ADDED = 'entity:tag:added', - ENTITY_TAG_REMOVED = 'entity:tag:removed', - ENTITY_NAME_CHANGED = 'entity:name:changed', - + ENTITY_CREATED = "entity:created", + ENTITY_DESTROYED = "entity:destroyed", + ENTITY_ENABLED = "entity:enabled", + ENTITY_DISABLED = "entity:disabled", + 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', - + 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', - SYSTEM_ENABLED = 'system:enabled', - SYSTEM_DISABLED = 'system:disabled', - SYSTEM_PROCESSING_START = 'system:processing:start', - SYSTEM_PROCESSING_END = 'system:processing:end', - SYSTEM_ERROR = 'system:error', - + SYSTEM_ADDED = "system:added", + SYSTEM_REMOVED = "system:removed", + SYSTEM_ENABLED = "system:enabled", + SYSTEM_DISABLED = "system:disabled", + SYSTEM_PROCESSING_START = "system:processing:start", + SYSTEM_PROCESSING_END = "system:processing:end", + SYSTEM_ERROR = "system:error", + // 场景相关事件 - SCENE_CREATED = 'scene:created', - SCENE_DESTROYED = 'scene:destroyed', - SCENE_ACTIVATED = 'scene:activated', - SCENE_DEACTIVATED = 'scene:deactivated', - SCENE_PAUSED = 'scene:paused', - SCENE_RESUMED = 'scene:resumed', - + SCENE_CREATED = "scene:created", + SCENE_DESTROYED = "scene:destroyed", + SCENE_ACTIVATED = "scene:activated", + 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', - + 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', - + 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', - + 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', - + 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', - + DIRTY_MARK_ADDED = "dirty:mark:added", + DIRTY_BATCH_PROCESSED = "dirty:batch:processed", + // 错误和警告事件 - ERROR_OCCURRED = 'error:occurred', - WARNING_ISSUED = 'warning:issued', - + ERROR_OCCURRED = "error:occurred", + WARNING_ISSUED = "warning:issued", + // 生命周期事件 - FRAMEWORK_INITIALIZED = 'framework:initialized', - FRAMEWORK_SHUTDOWN = 'framework:shutdown', - + FRAMEWORK_INITIALIZED = "framework:initialized", + FRAMEWORK_SHUTDOWN = "framework:shutdown", + // 调试相关事件 - DEBUG_INFO = 'debug:info', - DEBUG_STATS_UPDATED = 'debug:stats:updated' + 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/EntityRefDecorator.ts b/packages/core/src/ECS/Decorators/EntityRefDecorator.ts index 33bde380..52c4751b 100644 --- a/packages/core/src/ECS/Decorators/EntityRefDecorator.ts +++ b/packages/core/src/ECS/Decorators/EntityRefDecorator.ts @@ -1,19 +1,19 @@ -import type { Entity } from '../Entity'; -import type { Component } from '../Component'; -import { getSceneByEntityId } from '../Core/ReferenceTracker'; -import { createLogger } from '../../Utils/Logger'; +import type {Entity} from "../Entity"; +import type {Component} from "../Component"; +import {getSceneByEntityId} from "../Core/ReferenceTracker"; +import {createLogger} from "../../Utils/Logger"; -const logger = createLogger('EntityRefDecorator'); +const logger = createLogger("EntityRefDecorator"); /** * EntityRef元数据的Symbol键 */ -export const ENTITY_REF_METADATA = Symbol('EntityRefMetadata'); +export const ENTITY_REF_METADATA = Symbol("EntityRefMetadata"); /** * EntityRef值存储的Symbol键 */ -const ENTITY_REF_VALUES = Symbol('EntityRefValues'); +const ENTITY_REF_VALUES = Symbol("EntityRefValues"); /** * EntityRef元数据 @@ -66,7 +66,7 @@ export function EntityRef(): PropertyDecorator { constructor[ENTITY_REF_METADATA] = metadata; } - const propKeyString = typeof propertyKey === 'symbol' ? propertyKey.toString() : propertyKey; + const propKeyString = typeof propertyKey === "symbol" ? propertyKey.toString() : propertyKey; metadata.properties.add(propKeyString); Object.defineProperty(target, propertyKey, { @@ -97,7 +97,7 @@ export function EntityRef(): PropertyDecorator { if (newValue) { if (newValue.scene !== scene) { - logger.error(`Cannot reference Entity from different Scene. Entity: ${newValue.name}, Scene: ${newValue.scene?.name || 'null'}`); + logger.error(`Cannot reference Entity from different Scene. Entity: ${newValue.name}, Scene: ${newValue.scene?.name || "null"}`); return; } @@ -129,7 +129,7 @@ export function getEntityRefMetadata(component: any): EntityRefMetadata | null { return null; } - const constructor = typeof component === 'function' + const constructor = typeof component === "function" ? component : component.constructor; diff --git a/packages/core/src/ECS/Decorators/TypeDecorators.ts b/packages/core/src/ECS/Decorators/TypeDecorators.ts index 285e37fa..ec9ee98d 100644 --- a/packages/core/src/ECS/Decorators/TypeDecorators.ts +++ b/packages/core/src/ECS/Decorators/TypeDecorators.ts @@ -1,21 +1,21 @@ -import type {Component} from '../Component'; -import type {EntitySystem} from '../Systems'; +import type {Component} from "../Component"; +import type {EntitySystem} from "../Systems"; import {ComponentType} from "../../Types"; /** * 存储组件类型名称的Symbol键 */ -export const COMPONENT_TYPE_NAME = Symbol('ComponentTypeName'); +export const COMPONENT_TYPE_NAME = Symbol("ComponentTypeName"); /** * 存储系统类型名称的Symbol键 */ -export const SYSTEM_TYPE_NAME = Symbol('SystemTypeName'); +export const SYSTEM_TYPE_NAME = Symbol("SystemTypeName"); /** * 组件类型装饰器 * 用于为组件类指定固定的类型名称,避免在代码混淆后失效 - * + * * @param typeName 组件类型名称 * @example * ```typescript @@ -28,13 +28,13 @@ export const SYSTEM_TYPE_NAME = Symbol('SystemTypeName'); */ export function ECSComponent(typeName: string) { return function Component>(target: T): T { - if (!typeName || typeof typeName !== 'string') { - throw new Error('ECSComponent装饰器必须提供有效的类型名称'); + if (!typeName || typeof typeName !== "string") { + throw new Error("ECSComponent装饰器必须提供有效的类型名称"); } - + // 在构造函数上存储类型名称 (target as any)[COMPONENT_TYPE_NAME] = typeName; - + return target; }; } @@ -82,8 +82,8 @@ export interface SystemMetadata { */ export function ECSSystem(typeName: string, metadata?: SystemMetadata) { return function EntitySystem>(target: T): T { - if (!typeName || typeof typeName !== 'string') { - throw new Error('ECSSystem装饰器必须提供有效的类型名称'); + if (!typeName || typeof typeName !== "string") { + throw new Error("ECSSystem装饰器必须提供有效的类型名称"); } // 在构造函数上存储类型名称 @@ -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'; + return componentType.name || "UnknownComponent"; } /** * 获取系统类型的名称,优先使用装饰器指定的名称 - * + * * @param systemType 系统构造函数 * @returns 系统类型名称 */ @@ -138,14 +138,14 @@ export function getSystemTypeName( if (decoratorName) { return decoratorName; } - + // 回退到constructor.name - return systemType.name || 'UnknownSystem'; + 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..647ae02b 100644 --- a/packages/core/src/ECS/Decorators/index.ts +++ b/packages/core/src/ECS/Decorators/index.ts @@ -8,15 +8,15 @@ export { getSystemMetadata, COMPONENT_TYPE_NAME, SYSTEM_TYPE_NAME -} from './TypeDecorators'; +} from "./TypeDecorators"; -export type { SystemMetadata } from './TypeDecorators'; +export type {SystemMetadata} from "./TypeDecorators"; export { EntityRef, getEntityRefMetadata, hasEntityRef, ENTITY_REF_METADATA -} from './EntityRefDecorator'; +} 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/Entity.ts b/packages/core/src/ECS/Entity.ts index 28b0c64b..c05b60eb 100644 --- a/packages/core/src/ECS/Entity.ts +++ b/packages/core/src/ECS/Entity.ts @@ -1,20 +1,20 @@ -import { Component } from './Component'; -import { ComponentRegistry, ComponentType } from './Core/ComponentStorage'; -import { EventBus } from './Core/EventBus'; -import { BitMask64Utils, BitMask64Data } from './Utils/BigIntCompatibility'; -import { createLogger } from '../Utils/Logger'; -import { getComponentInstanceTypeName, getComponentTypeName } from './Decorators'; -import type { IScene } from './IScene'; +import {Component} from "./Component"; +import {ComponentRegistry, ComponentType} from "./Core/ComponentStorage"; +import {EventBus} from "./Core/EventBus"; +import {BitMask64Utils, BitMask64Data} from "./Utils/BigIntCompatibility"; +import {createLogger} from "../Utils/Logger"; +import {getComponentInstanceTypeName, getComponentTypeName} from "./Decorators"; +import type {IScene} from "./IScene"; /** * 实体比较器 - * + * * 用于比较两个实体的优先级,首先按更新顺序比较,然后按ID比较。 */ export class EntityComparer { /** * 比较两个实体 - * + * * @param self - 第一个实体 * @param other - 第二个实体 * @returns 比较结果,负数表示self优先级更高,正数表示other优先级更高,0表示相等 @@ -28,28 +28,27 @@ export class EntityComparer { } - /** * 游戏实体类 - * + * * ECS架构中的实体(Entity),作为组件的容器。 * 实体本身不包含游戏逻辑,所有功能都通过组件来实现。 * 支持父子关系,可以构建实体层次结构。 - * + * * @example * ```typescript * // 创建实体 * const entity = new Entity("Player", 1); - * + * * // 添加组件 * const healthComponent = entity.addComponent(new HealthComponent(100)); - * + * * // 获取组件 * const health = entity.getComponent(HealthComponent); - * + * * // 添加位置组件 * entity.addComponent(new PositionComponent(100, 200)); - * + * * // 添加子实体 * const weapon = new Entity("Weapon", 2); * entity.addChild(weapon); @@ -59,13 +58,13 @@ export class Entity { /** * Entity专用日志器 */ - private static _logger = createLogger('Entity'); - + private static _logger = createLogger("Entity"); + /** * 实体比较器实例 */ public static entityComparer: EntityComparer = new EntityComparer(); - + /** * 全局事件总线实例 * 用于发射组件相关事件 @@ -84,17 +83,17 @@ export class Entity { entity.scene.clearSystemEntityCaches(); } } - + /** * 实体名称 */ public name: string; - + /** * 实体唯一标识符 */ public readonly id: number; - + /** * 所属场景引用 */ @@ -103,7 +102,16 @@ export class Entity { /** * 销毁状态标志 */ - public _isDestroyed: boolean = false; + private _destroyed: boolean = false; + + /** + * 设置销毁状态(仅供框架内部使用) + * + * @internal 此方法仅用于批量销毁优化,不应在外部调用 + */ + public setDestroyed(value: boolean): void { + this._destroyed = value; + } /** * 父实体引用 @@ -161,7 +169,7 @@ export class Entity { * @returns 如果实体已被销毁则返回true */ public get isDestroyed(): boolean { - return this._isDestroyed; + return this._destroyed; } /** @@ -218,7 +226,7 @@ export class Entity { /** * 获取子实体数组的只读副本 - * + * * @returns 子实体数组的副本 */ public get children(): readonly Entity[] { @@ -227,7 +235,7 @@ export class Entity { /** * 获取子实体数量 - * + * * @returns 子实体的数量 */ public get childCount(): number { @@ -236,7 +244,7 @@ export class Entity { /** * 获取活跃状态 - * + * * @returns 如果实体处于活跃状态则返回true */ public get active(): boolean { @@ -245,9 +253,9 @@ export class Entity { /** * 设置活跃状态 - * + * * 设置实体的活跃状态,会影响子实体的有效活跃状态。 - * + * * @param value - 新的活跃状态 */ public set active(value: boolean) { @@ -259,9 +267,9 @@ export class Entity { /** * 获取实体的有效活跃状态 - * + * * 考虑父实体的活跃状态,只有当实体本身和所有父实体都处于活跃状态时才返回true。 - * + * * @returns 有效的活跃状态 */ public get activeInHierarchy(): boolean { @@ -272,7 +280,7 @@ export class Entity { /** * 获取实体标签 - * + * * @returns 实体的数字标签 */ public get tag(): number { @@ -281,7 +289,7 @@ export class Entity { /** * 设置实体标签 - * + * * @param value - 新的标签值 */ public set tag(value: number) { @@ -290,7 +298,7 @@ export class Entity { /** * 获取启用状态 - * + * * @returns 如果实体已启用则返回true */ public get enabled(): boolean { @@ -299,7 +307,7 @@ export class Entity { /** * 设置启用状态 - * + * * @param value - 新的启用状态 */ public set enabled(value: boolean) { @@ -308,7 +316,7 @@ export class Entity { /** * 获取更新顺序 - * + * * @returns 实体的更新顺序值 */ public get updateOrder(): number { @@ -317,7 +325,7 @@ export class Entity { /** * 设置更新顺序 - * + * * @param value - 新的更新顺序值 */ public set updateOrder(value: number) { @@ -326,7 +334,7 @@ export class Entity { /** * 获取组件位掩码 - * + * * @returns 实体的组件位掩码 */ public get componentMask(): BitMask64Data { @@ -394,11 +402,11 @@ export class Entity { const componentType = component.constructor as ComponentType; if (!this.scene) { - throw new Error(`Entity must be added to Scene before adding components. Use scene.createEntity() instead of new Entity()`); + throw new Error("Entity must be added to Scene before adding components. Use scene.createEntity() instead of new Entity()"); } if (!this.scene.componentStorageManager) { - throw new Error(`Scene does not have componentStorageManager`); + throw new Error("Scene does not have componentStorageManager"); } if (this.hasComponent(componentType)) { @@ -418,7 +426,7 @@ export class Entity { if (Entity.eventBus) { Entity.eventBus.emitComponentAdded({ timestamp: Date.now(), - source: 'Entity', + source: "Entity", entityId: this.id, entityName: this.name, entityTag: this.tag?.toString(), @@ -465,8 +473,6 @@ export class Entity { } - - /** * 检查实体是否拥有指定类型的组件 * @@ -485,7 +491,7 @@ export class Entity { if (!ComponentRegistry.isRegistered(type)) { return false; } - + const mask = ComponentRegistry.getBitMask(type); return BitMask64Utils.hasAny(this._componentMask, mask); } @@ -555,7 +561,7 @@ export class Entity { if (Entity.eventBus) { Entity.eventBus.emitComponentRemoved({ timestamp: Date.now(), - source: 'Entity', + source: "Entity", entityId: this.id, entityName: this.name, entityTag: this.tag?.toString(), @@ -570,7 +576,7 @@ export class Entity { /** * 移除指定类型的组件 - * + * * @param type - 组件类型 * @returns 被移除的组件实例或null */ @@ -611,13 +617,13 @@ export class Entity { /** * 批量添加组件 - * + * * @param components - 要添加的组件数组 * @returns 添加的组件数组 */ public addComponents(components: T[]): T[] { const addedComponents: T[] = []; - + for (const component of components) { try { addedComponents.push(this.addComponent(component)); @@ -625,28 +631,27 @@ export class Entity { Entity._logger.warn(`添加组件失败 ${getComponentInstanceTypeName(component)}:`, error); } } - + return addedComponents; } /** * 批量移除组件类型 - * + * * @param componentTypes - 要移除的组件类型数组 * @returns 被移除的组件数组 */ public removeComponentsByTypes(componentTypes: ComponentType[]): (T | null)[] { const removedComponents: (T | null)[] = []; - + for (const componentType of componentTypes) { removedComponents.push(this.removeComponentByType(componentType)); } - + return removedComponents; } - /** * 获取所有指定类型的组件 * @@ -694,7 +699,7 @@ export class Entity { /** * 添加子实体 - * + * * @param child - 要添加的子实体 * @returns 添加的子实体 */ @@ -724,7 +729,7 @@ export class Entity { /** * 移除子实体 - * + * * @param child - 要移除的子实体 * @returns 是否成功移除 */ @@ -745,7 +750,7 @@ export class Entity { */ public removeAllChildren(): void { const childrenToRemove = [...this._children]; - + for (const child of childrenToRemove) { this.removeChild(child); } @@ -753,7 +758,7 @@ export class Entity { /** * 根据名称查找子实体 - * + * * @param name - 子实体名称 * @param recursive - 是否递归查找 * @returns 找到的子实体或null @@ -779,7 +784,7 @@ export class Entity { /** * 根据标签查找子实体 - * + * * @param tag - 标签 * @param recursive - 是否递归查找 * @returns 找到的子实体数组 @@ -804,7 +809,7 @@ export class Entity { /** * 获取根实体 - * + * * @returns 层次结构的根实体 */ public getRoot(): Entity { @@ -817,7 +822,7 @@ export class Entity { /** * 检查是否是指定实体的祖先 - * + * * @param entity - 要检查的实体 * @returns 如果是祖先则返回true */ @@ -834,7 +839,7 @@ export class Entity { /** * 检查是否是指定实体的后代 - * + * * @param entity - 要检查的实体 * @returns 如果是后代则返回true */ @@ -844,7 +849,7 @@ export class Entity { /** * 获取层次深度 - * + * * @returns 在层次结构中的深度(根实体为0) */ public getDepth(): number { @@ -859,7 +864,7 @@ export class Entity { /** * 遍历所有子实体(深度优先) - * + * * @param callback - 对每个子实体执行的回调函数 * @param recursive - 是否递归遍历 */ @@ -877,14 +882,14 @@ export class Entity { */ private onActiveChanged(): void { for (const component of this.components) { - if ('onActiveChanged' in component && typeof component.onActiveChanged === 'function') { + if ("onActiveChanged" in component && typeof component.onActiveChanged === "function") { (component as any).onActiveChanged(); } } if (this.scene && this.scene.eventSystem) { - this.scene.eventSystem.emitSync('entity:activeChanged', { - entity: this, + this.scene.eventSystem.emitSync("entity:activeChanged", { + entity: this, active: this._active, activeInHierarchy: this.activeInHierarchy }); @@ -898,11 +903,11 @@ export class Entity { * 移除所有组件、子实体并标记为已销毁 */ public destroy(): void { - if (this._isDestroyed) { + if (this._destroyed) { return; } - this._isDestroyed = true; + this._destroyed = true; if (this.scene && this.scene.referenceTracker) { this.scene.referenceTracker.clearReferencesTo(this.id); @@ -949,7 +954,7 @@ export class Entity { collectChildren(this); for (const entity of toDestroy) { - entity._isDestroyed = true; + entity.setDestroyed(true); } for (const entity of toDestroy) { @@ -970,7 +975,7 @@ export class Entity { /** * 比较实体 - * + * * @param other - 另一个实体 * @returns 比较结果 */ @@ -980,7 +985,7 @@ export class Entity { /** * 获取实体的字符串表示 - * + * * @returns 实体的字符串描述 */ public toString(): string { @@ -989,7 +994,7 @@ export class Entity { /** * 获取实体的调试信息(包含组件缓存信息) - * + * * @returns 包含实体详细信息的对象 */ public getDebugInfo(): { @@ -1007,20 +1012,20 @@ export class Entity { childIds: number[]; depth: number; cacheBuilt: boolean; - } { + } { return { name: this.name, id: this.id, enabled: this._enabled, active: this._active, activeInHierarchy: this.activeInHierarchy, - destroyed: this._isDestroyed, + destroyed: this._destroyed, componentCount: this.components.length, - componentTypes: this.components.map(c => getComponentInstanceTypeName(c)), + componentTypes: this.components.map((c) => getComponentInstanceTypeName(c)), componentMask: BitMask64Utils.toString(this._componentMask, 2), // 二进制表示 parentId: this._parent?.id || null, childCount: this._children.length, - childIds: this._children.map(c => c.id), + childIds: this._children.map((c) => c.id), depth: this.getDepth(), cacheBuilt: this._componentCache !== null }; diff --git a/packages/core/src/ECS/IScene.ts b/packages/core/src/ECS/IScene.ts index 42bcec2d..337da588 100644 --- a/packages/core/src/ECS/IScene.ts +++ b/packages/core/src/ECS/IScene.ts @@ -1,15 +1,15 @@ -import { Entity } from './Entity'; -import { EntityList } from './Utils/EntityList'; -import { IdentifierPool } from './Utils/IdentifierPool'; -import { EntitySystem } from './Systems/EntitySystem'; -import { ComponentStorageManager } from './Core/ComponentStorage'; -import { QuerySystem } from './Core/QuerySystem'; -import { TypeSafeEventSystem } from './Core/EventSystem'; -import type { ReferenceTracker } from './Core/ReferenceTracker'; -import type { ServiceContainer, ServiceType } from '../Core/ServiceContainer'; -import type { TypedQueryBuilder } from './Core/Query/TypedQuery'; -import type { SceneSerializationOptions, SceneDeserializationOptions } from './Serialization/SceneSerializer'; -import type { IncrementalSnapshot, IncrementalSerializationOptions } from './Serialization/IncrementalSerializer'; +import {Entity} from "./Entity"; +import {EntityList} from "./Utils/EntityList"; +import {IdentifierPool} from "./Utils/IdentifierPool"; +import {EntitySystem} from "./Systems/EntitySystem"; +import {ComponentStorageManager} from "./Core/ComponentStorage"; +import {QuerySystem} from "./Core/QuerySystem"; +import {TypeSafeEventSystem} from "./Core/EventSystem"; +import type {ReferenceTracker} from "./Core/ReferenceTracker"; +import type {ServiceContainer, ServiceType} from "../Core/ServiceContainer"; +import type {TypedQueryBuilder} from "./Core/Query/TypedQuery"; +import type {SceneSerializationOptions, SceneDeserializationOptions} from "./Serialization/SceneSerializer"; +import type {IncrementalSnapshot, IncrementalSerializationOptions} from "./Serialization/IncrementalSerializer"; /** * 场景接口定义 @@ -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/Scene.ts b/packages/core/src/ECS/Scene.ts index fd4e619b..b5e1c4f5 100644 --- a/packages/core/src/ECS/Scene.ts +++ b/packages/core/src/ECS/Scene.ts @@ -1,22 +1,22 @@ -import { Entity } from './Entity'; -import { EntityList } from './Utils/EntityList'; -import { IdentifierPool } from './Utils/IdentifierPool'; -import { EntitySystem } from './Systems/EntitySystem'; -import { ComponentStorageManager, ComponentRegistry } from './Core/ComponentStorage'; -import { QuerySystem } from './Core/QuerySystem'; -import { TypeSafeEventSystem } from './Core/EventSystem'; -import { EventBus } from './Core/EventBus'; -import { ReferenceTracker } from './Core/ReferenceTracker'; -import { IScene, ISceneConfig } from './IScene'; -import { getComponentInstanceTypeName, getSystemInstanceTypeName, getSystemMetadata } from "./Decorators"; -import { TypedQueryBuilder } from './Core/Query/TypedQuery'; -import { SceneSerializer, SceneSerializationOptions, SceneDeserializationOptions } from './Serialization/SceneSerializer'; -import { IncrementalSerializer, IncrementalSnapshot, IncrementalSerializationOptions } from './Serialization/IncrementalSerializer'; -import { ComponentPoolManager } from './Core/ComponentPool'; -import { PerformanceMonitor } from '../Utils/PerformanceMonitor'; -import { ServiceContainer, type ServiceType } from '../Core/ServiceContainer'; -import { createInstance, isInjectable, injectProperties } from '../Core/DI'; -import { createLogger } from '../Utils/Logger'; +import {Entity} from "./Entity"; +import {EntityList} from "./Utils/EntityList"; +import {IdentifierPool} from "./Utils/IdentifierPool"; +import {EntitySystem} from "./Systems/EntitySystem"; +import {ComponentStorageManager, ComponentRegistry} from "./Core/ComponentStorage"; +import {QuerySystem} from "./Core/QuerySystem"; +import {TypeSafeEventSystem} from "./Core/EventSystem"; +import {EventBus} from "./Core/EventBus"; +import {ReferenceTracker} from "./Core/ReferenceTracker"; +import {IScene, ISceneConfig} from "./IScene"; +import {getComponentInstanceTypeName, getSystemInstanceTypeName, getSystemMetadata} from "./Decorators"; +import {TypedQueryBuilder} from "./Core/Query/TypedQuery"; +import {SceneSerializer, SceneSerializationOptions, SceneDeserializationOptions} from "./Serialization/SceneSerializer"; +import {IncrementalSerializer, IncrementalSnapshot, IncrementalSerializationOptions} from "./Serialization/IncrementalSerializer"; +import {ComponentPoolManager} from "./Core/ComponentPool"; +import {PerformanceMonitor} from "../Utils/PerformanceMonitor"; +import {ServiceContainer, type ServiceType} from "../Core/ServiceContainer"; +import {createInstance, isInjectable, injectProperties} from "../Core/DI"; +import {createLogger} from "../Utils/Logger"; /** * 游戏场景默认实现类 @@ -45,25 +45,25 @@ export class Scene implements IScene { * 管理场景内所有实体的生命周期。 */ public readonly entities: EntityList; - + /** * 实体ID池 - * + * * 用于分配和回收实体的唯一标识符。 */ public readonly identifierPool: IdentifierPool; /** * 组件存储管理器 - * + * * 高性能的组件存储和查询系统。 */ public readonly componentStorageManager: ComponentStorageManager; /** * 查询系统 - * + * * 基于位掩码的高性能实体查询系统。 */ public readonly querySystem: QuerySystem; @@ -207,7 +207,7 @@ export class Scene implements IScene { this.eventSystem = new TypeSafeEventSystem(); this.referenceTracker = new ReferenceTracker(); this._services = new ServiceContainer(); - this.logger = createLogger('Scene'); + this.logger = createLogger("Scene"); if (config?.name) { this.name = config.name; @@ -219,7 +219,7 @@ export class Scene implements IScene { if (Entity.eventBus) { Entity.eventBus.onComponentAdded((data: unknown) => { - this.eventSystem.emitSync('component:added', data); + this.eventSystem.emitSync("component:added", data); }); } } @@ -239,7 +239,7 @@ export class Scene implements IScene { /** * 初始化场景 - * + * * 在场景创建时调用,子类可以重写此方法来设置初始实体和组件。 */ public initialize(): void { @@ -247,7 +247,7 @@ export class Scene implements IScene { /** * 场景开始运行时的回调 - * + * * 在场景开始运行时调用,可以在此方法中执行场景启动逻辑。 */ public onStart(): void { @@ -255,7 +255,7 @@ export class Scene implements IScene { /** * 场景卸载时的回调 - * + * * 在场景被销毁时调用,可以在此方法中执行清理工作。 */ public unload(): void { @@ -338,10 +338,10 @@ export class Scene implements IScene { * @param name 实体名称 */ public createEntity(name: string) { - let entity = new Entity(name, this.identifierPool.checkOut()); - - this.eventSystem.emitSync('entity:created', { entityName: name, entity, scene: this }); - + const entity = new Entity(name, this.identifierPool.checkOut()); + + this.eventSystem.emitSync("entity:created", {entityName: name, entity, scene: this}); + return this.addEntity(entity); } @@ -373,7 +373,7 @@ export class Scene implements IScene { } // 触发实体添加事件 - this.eventSystem.emitSync('entity:added', { entity, scene: this }); + this.eventSystem.emitSync("entity:added", {entity, scene: this}); return entity; } @@ -386,25 +386,25 @@ export class Scene implements IScene { */ public createEntities(count: number, namePrefix: string = "Entity"): Entity[] { const entities: Entity[] = []; - + // 批量创建实体对象,不立即添加到系统 for (let i = 0; i < count; i++) { const entity = new Entity(`${namePrefix}_${i}`, this.identifierPool.checkOut()); entity.scene = this; entities.push(entity); } - + // 批量添加到实体列表 for (const entity of entities) { this.entities.add(entity); } - + // 批量添加到查询系统(无重复检查,性能最优) this.querySystem.addEntitiesUnchecked(entities); - + // 批量触发事件(可选,减少事件开销) - this.eventSystem.emitSync('entities:batch_added', { entities, scene: this, count }); - + this.eventSystem.emitSync("entities:batch_added", {entities, scene: this, count}); + return entities; } @@ -416,7 +416,7 @@ export class Scene implements IScene { if (entities.length === 0) return; for (const entity of entities) { - entity._isDestroyed = true; + entity.setDestroyed(true); } for (const entity of entities) { @@ -583,7 +583,7 @@ export class Scene implements IScene { let system: T; let constructor: any; - if (typeof systemTypeOrInstance === 'function') { + if (typeof systemTypeOrInstance === "function") { constructor = systemTypeOrInstance; if (this._services.isRegistered(constructor)) { @@ -609,7 +609,7 @@ export class Scene implements IScene { } else { this.logger.warn( `Attempting to register a different instance of ${constructor.name}, ` + - `but type is already registered. Returning existing instance.` + "but type is already registered. Returning existing instance." ); return existingSystem as T; } @@ -750,7 +750,7 @@ export class Scene implements IScene { entityCount: number; processorCount: number; componentStorageStats: Map; - } { + } { return { entityCount: this.entities.count, processorCount: this.systems.length, @@ -779,20 +779,20 @@ export class Scene implements IScene { entityCount: number; }>; componentStats: Map; - } { + } { const systems = this.systems; return { name: this.name || this.constructor.name, entityCount: this.entities.count, processorCount: systems.length, isRunning: this._didSceneBegin, - entities: this.entities.buffer.map(entity => ({ + entities: this.entities.buffer.map((entity) => ({ name: entity.name, id: entity.id, componentCount: entity.components.length, - componentTypes: entity.components.map(c => getComponentInstanceTypeName(c)) + componentTypes: entity.components.map((c) => getComponentInstanceTypeName(c)) })), - processors: systems.map(processor => ({ + processors: systems.map((processor) => ({ name: getSystemInstanceTypeName(processor), updateOrder: processor.updateOrder, entityCount: (processor as any)._entities?.length || 0 @@ -907,7 +907,7 @@ export class Scene implements IScene { */ public serializeIncremental(options?: IncrementalSerializationOptions): IncrementalSnapshot { if (!this._incrementalBaseSnapshot) { - throw new Error('必须先调用 createIncrementalSnapshot() 创建基础快照'); + throw new Error("必须先调用 createIncrementalSnapshot() 创建基础快照"); } return IncrementalSerializer.computeIncremental( @@ -941,7 +941,7 @@ export class Scene implements IScene { incremental: IncrementalSnapshot | string | Uint8Array, componentRegistry?: Map ): void { - const isSerializedData = typeof incremental === 'string' || + const isSerializedData = typeof incremental === "string" || incremental instanceof Uint8Array; const snapshot = isSerializedData @@ -996,4 +996,4 @@ export class Scene implements IScene { public hasIncrementalSnapshot(): boolean { return this._incrementalBaseSnapshot !== undefined; } -} \ No newline at end of file +} diff --git a/packages/core/src/ECS/SceneManager.ts b/packages/core/src/ECS/SceneManager.ts index dd9953b7..a9f7d180 100644 --- a/packages/core/src/ECS/SceneManager.ts +++ b/packages/core/src/ECS/SceneManager.ts @@ -1,10 +1,10 @@ -import { IScene } from './IScene'; -import { ECSFluentAPI, createECSAPI } from './Core/FluentAPI'; -import { Time } from '../Utils/Time'; -import { createLogger } from '../Utils/Logger'; -import type { IService } from '../Core/ServiceContainer'; -import { World } from './World'; -import { PerformanceMonitor } from '../Utils/PerformanceMonitor'; +import {IScene} from "./IScene"; +import {ECSFluentAPI, createECSAPI} from "./Core/FluentAPI"; +import {Time} from "../Utils/Time"; +import {createLogger} from "../Utils/Logger"; +import type {IService} from "../Core/ServiceContainer"; +import {World} from "./World"; +import {PerformanceMonitor} from "../Utils/PerformanceMonitor"; /** * 单场景管理器 @@ -67,7 +67,7 @@ export class SceneManager implements IService { /** * 日志器 */ - private _logger = createLogger('SceneManager'); + private _logger = createLogger("SceneManager"); /** * 场景切换回调函数 @@ -82,10 +82,10 @@ export class SceneManager implements IService { /** * 默认场景ID */ - private static readonly DEFAULT_SCENE_ID = '__main__'; + private static readonly DEFAULT_SCENE_ID = "__main__"; constructor(performanceMonitor?: PerformanceMonitor) { - this._defaultWorld = new World({ name: '__default__' }); + this._defaultWorld = new World({name: "__default__"}); this._defaultWorld.start(); this._performanceMonitor = performanceMonitor || null; } @@ -238,13 +238,13 @@ export class SceneManager implements IService { * 通常在应用程序关闭时调用。 */ public destroy(): void { - this._logger.info('SceneManager destroying'); + this._logger.info("SceneManager destroying"); this._defaultWorld.destroy(); this._nextScene = null; this._ecsAPI = null; - this._logger.info('SceneManager destroyed'); + this._logger.info("SceneManager destroyed"); } /** diff --git a/packages/core/src/ECS/Serialization/ComponentSerializer.ts b/packages/core/src/ECS/Serialization/ComponentSerializer.ts index 777b0c44..12508d66 100644 --- a/packages/core/src/ECS/Serialization/ComponentSerializer.ts +++ b/packages/core/src/ECS/Serialization/ComponentSerializer.ts @@ -4,12 +4,12 @@ * 负责组件的序列化和反序列化操作 */ -import { Component } from '../Component'; -import { ComponentType } from '../Core/ComponentStorage'; -import { getComponentTypeName } from '../Decorators'; +import {Component} from "../Component"; +import {ComponentType} from "../Core/ComponentStorage"; +import {getComponentTypeName} from "../Decorators"; import { getSerializationMetadata -} from './SerializationDecorators'; +} from "./SerializationDecorators"; /** * 可序列化的值类型 @@ -22,9 +22,9 @@ export type SerializableValue = | undefined | SerializableValue[] | { [key: string]: SerializableValue } - | { __type: 'Date'; value: string } - | { __type: 'Map'; value: Array<[SerializableValue, SerializableValue]> } - | { __type: 'Set'; value: SerializableValue[] }; + | { __type: "Date"; value: string } + | { __type: "Map"; value: Array<[SerializableValue, SerializableValue]> } + | { __type: "Set"; value: SerializableValue[] }; /** * 序列化后的组件数据 @@ -70,7 +70,7 @@ export class ComponentSerializer { // 序列化标记的字段 for (const [fieldName, options] of metadata.fields) { - const fieldKey = typeof fieldName === 'symbol' ? fieldName.toString() : fieldName; + const fieldKey = typeof fieldName === "symbol" ? fieldName.toString() : fieldName; const value = (component as unknown as Record)[fieldName]; // 跳过忽略的字段 @@ -125,7 +125,7 @@ export class ComponentSerializer { // 反序列化字段 for (const [fieldName, options] of metadata.fields) { - const fieldKey = typeof fieldName === 'symbol' ? fieldName.toString() : fieldName; + const fieldKey = typeof fieldName === "symbol" ? fieldName.toString() : fieldName; const key = options.alias || fieldKey; const serializedValue = serializedData.data[key]; @@ -198,27 +198,27 @@ export class ComponentSerializer { // 基本类型 const type = typeof value; - if (type === 'string' || type === 'number' || type === 'boolean') { + if (type === "string" || type === "number" || type === "boolean") { return value; } // 日期 if (value instanceof Date) { return { - __type: 'Date', + __type: "Date", value: value.toISOString() }; } // 数组 if (Array.isArray(value)) { - return value.map(item => this.serializeValue(item)); + return value.map((item) => this.serializeValue(item)); } // Map (如果没有使用@SerializeMap装饰器) if (value instanceof Map) { return { - __type: 'Map', + __type: "Map", value: Array.from(value.entries()) }; } @@ -226,13 +226,13 @@ export class ComponentSerializer { // Set if (value instanceof Set) { return { - __type: 'Set', + __type: "Set", value: Array.from(value) }; } // 普通对象 - if (type === 'object' && typeof value === 'object' && !Array.isArray(value)) { + if (type === "object" && typeof value === "object" && !Array.isArray(value)) { const result: Record = {}; const obj = value as Record; for (const key in obj) { @@ -257,30 +257,30 @@ export class ComponentSerializer { // 基本类型直接返回 const type = typeof value; - if (type === 'string' || type === 'number' || type === 'boolean') { + if (type === "string" || type === "number" || type === "boolean") { return value; } // 处理特殊类型标记 - if (type === 'object' && typeof value === 'object' && '__type' in value) { + if (type === "object" && typeof value === "object" && "__type" in value) { const typedValue = value as { __type: string; value: SerializableValue }; switch (typedValue.__type) { - case 'Date': - return { __type: 'Date', value: typeof typedValue.value === 'string' ? typedValue.value : String(typedValue.value) }; - case 'Map': - return { __type: 'Map', value: typedValue.value as Array<[SerializableValue, SerializableValue]> }; - case 'Set': - return { __type: 'Set', value: typedValue.value as SerializableValue[] }; + case "Date": + return {__type: "Date", value: typeof typedValue.value === "string" ? typedValue.value : String(typedValue.value)}; + case "Map": + return {__type: "Map", value: typedValue.value as Array<[SerializableValue, SerializableValue]>}; + case "Set": + return {__type: "Set", value: typedValue.value as SerializableValue[]}; } } // 数组 if (Array.isArray(value)) { - return value.map(item => this.deserializeValue(item)); + return value.map((item) => this.deserializeValue(item)); } // 普通对象 - if (type === 'object' && typeof value === 'object' && !Array.isArray(value)) { + if (type === "object" && typeof value === "object" && !Array.isArray(value)) { const result: Record = {}; const obj = value as Record; for (const key in obj) { @@ -325,7 +325,7 @@ export class ComponentSerializer { if (!metadata) { return { - type: 'unknown', + type: "unknown", version: 0, fields: [], ignoredFields: [], @@ -333,18 +333,18 @@ export class ComponentSerializer { }; } - const componentType = typeof component === 'function' + const componentType = typeof component === "function" ? component : (component.constructor as ComponentType); return { type: metadata.options.typeId || getComponentTypeName(componentType), version: metadata.options.version, - fields: Array.from(metadata.fields.keys()).map(k => - typeof k === 'symbol' ? k.toString() : k + fields: Array.from(metadata.fields.keys()).map((k) => + typeof k === "symbol" ? k.toString() : k ), - ignoredFields: Array.from(metadata.ignoredFields).map(k => - typeof k === 'symbol' ? k.toString() : k + ignoredFields: Array.from(metadata.ignoredFields).map((k) => + typeof k === "symbol" ? k.toString() : k ), isSerializable: true }; diff --git a/packages/core/src/ECS/Serialization/EntitySerializer.ts b/packages/core/src/ECS/Serialization/EntitySerializer.ts index 46aafb5f..c4ea1db2 100644 --- a/packages/core/src/ECS/Serialization/EntitySerializer.ts +++ b/packages/core/src/ECS/Serialization/EntitySerializer.ts @@ -4,10 +4,10 @@ * 负责实体的序列化和反序列化操作 */ -import { Entity } from '../Entity'; -import { ComponentType } from '../Core/ComponentStorage'; -import { ComponentSerializer, SerializedComponent } from './ComponentSerializer'; -import { IScene } from '../IScene'; +import {Entity} from "../Entity"; +import {ComponentType} from "../Core/ComponentStorage"; +import {ComponentSerializer, SerializedComponent} from "./ComponentSerializer"; +import {IScene} from "../IScene"; /** * 序列化后的实体数据 diff --git a/packages/core/src/ECS/Serialization/IncrementalSerializer.ts b/packages/core/src/ECS/Serialization/IncrementalSerializer.ts index 6354f8f2..da86b8c0 100644 --- a/packages/core/src/ECS/Serialization/IncrementalSerializer.ts +++ b/packages/core/src/ECS/Serialization/IncrementalSerializer.ts @@ -5,31 +5,31 @@ * 适用于网络同步、大场景存档、时间回溯等场景 */ -import type { IScene } from '../IScene'; -import { Entity } from '../Entity'; -import { ComponentSerializer, SerializedComponent } from './ComponentSerializer'; -import { SerializedEntity } from './EntitySerializer'; -import { ComponentType } from '../Core/ComponentStorage'; -import { BinarySerializer } from '../../Utils/BinarySerializer'; +import type {IScene} from "../IScene"; +import {Entity} from "../Entity"; +import {ComponentSerializer, SerializedComponent} from "./ComponentSerializer"; +import {SerializedEntity} from "./EntitySerializer"; +import {ComponentType} from "../Core/ComponentStorage"; +import {BinarySerializer} from "../../Utils/BinarySerializer"; /** * 变更操作类型 */ export enum ChangeOperation { /** 添加新实体 */ - EntityAdded = 'entity_added', + EntityAdded = "entity_added", /** 删除实体 */ - EntityRemoved = 'entity_removed', + EntityRemoved = "entity_removed", /** 实体属性更新 */ - EntityUpdated = 'entity_updated', + EntityUpdated = "entity_updated", /** 添加组件 */ - ComponentAdded = 'component_added', + ComponentAdded = "component_added", /** 删除组件 */ - ComponentRemoved = 'component_removed', + ComponentRemoved = "component_removed", /** 组件数据更新 */ - ComponentUpdated = 'component_updated', + ComponentUpdated = "component_updated", /** 场景数据更新 */ - SceneDataUpdated = 'scene_data_updated' + SceneDataUpdated = "scene_data_updated" } /** @@ -120,7 +120,7 @@ interface SceneSnapshot { /** * 增量序列化格式 */ -export type IncrementalSerializationFormat = 'json' | 'binary'; +export type IncrementalSerializationFormat = "json" | "binary"; /** * 增量序列化选项 @@ -203,7 +203,7 @@ export class IncrementalSerializer { active: entity.active, enabled: entity.enabled, updateOrder: entity.updateOrder, - ...(entity.parent && { parentId: entity.parent.id }) + ...(entity.parent && {parentId: entity.parent.id}) }); // 快照组件 @@ -285,7 +285,7 @@ export class IncrementalSerializer { active: entity.active, enabled: entity.enabled, updateOrder: entity.updateOrder, - ...(entity.parent && { parentId: entity.parent.id }), + ...(entity.parent && {parentId: entity.parent.id}), components: [], children: [] } @@ -324,7 +324,7 @@ export class IncrementalSerializer { active: entity.active, enabled: entity.enabled, updateOrder: entity.updateOrder, - ...(entity.parent && { parentId: entity.parent.id }) + ...(entity.parent && {parentId: entity.parent.id}) } }); } @@ -511,7 +511,7 @@ export class IncrementalSerializer { private static applyEntityAdded(scene: IScene, change: EntityChange): void { if (!change.entityData) return; - const entity = new Entity(change.entityName || 'Entity', change.entityId); + const entity = new Entity(change.entityName || "Entity", change.entityId); entity.tag = change.entityData.tag || 0; entity.active = change.entityData.active ?? true; entity.enabled = change.entityData.enabled ?? true; @@ -632,12 +632,12 @@ export class IncrementalSerializer { options?: { format?: IncrementalSerializationFormat; pretty?: boolean } ): string | Uint8Array { const opts = { - format: 'json' as IncrementalSerializationFormat, + format: "json" as IncrementalSerializationFormat, pretty: false, ...options }; - if (opts.format === 'binary') { + if (opts.format === "binary") { return BinarySerializer.encode(incremental); } else { return opts.pretty @@ -662,7 +662,7 @@ export class IncrementalSerializer { * ``` */ public static deserializeIncremental(data: string | Uint8Array): IncrementalSnapshot { - if (typeof data === 'string') { + if (typeof data === "string") { return JSON.parse(data); } else { return BinarySerializer.decode(data) as IncrementalSnapshot; @@ -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..971f5701 100644 --- a/packages/core/src/ECS/Serialization/SceneSerializer.ts +++ b/packages/core/src/ECS/Serialization/SceneSerializer.ts @@ -4,23 +4,23 @@ * 负责整个场景的序列化和反序列化,包括实体、组件等 */ -import type { IScene } from '../IScene'; -import { Entity } from '../Entity'; -import { ComponentType, ComponentRegistry } from '../Core/ComponentStorage'; -import { EntitySerializer, SerializedEntity } from './EntitySerializer'; -import { getComponentTypeName } from '../Decorators'; -import { getSerializationMetadata } from './SerializationDecorators'; -import { BinarySerializer } from '../../Utils/BinarySerializer'; +import type {IScene} from "../IScene"; +import {Entity} from "../Entity"; +import {ComponentType, ComponentRegistry} from "../Core/ComponentStorage"; +import {EntitySerializer, SerializedEntity} from "./EntitySerializer"; +import {getComponentTypeName} from "../Decorators"; +import {getSerializationMetadata} from "./SerializationDecorators"; +import {BinarySerializer} from "../../Utils/BinarySerializer"; /** * 场景序列化格式 */ -export type SerializationFormat = 'json' | 'binary'; +export type SerializationFormat = "json" | "binary"; /** * 场景序列化策略 */ -export type DeserializationStrategy = 'merge' | 'replace'; +export type DeserializationStrategy = "merge" | "replace"; /** * 版本迁移函数 @@ -158,7 +158,7 @@ export class SceneSerializer { public static serialize(scene: IScene, options?: SceneSerializationOptions): string | Uint8Array { const opts: SceneSerializationOptions = { systems: false, - format: 'json', + format: "json", pretty: true, includeMetadata: true, ...options @@ -199,7 +199,7 @@ export class SceneSerializer { }; } - if (opts.format === 'json') { + if (opts.format === "json") { return opts.pretty ? JSON.stringify(serializedScene, null, 2) : JSON.stringify(serializedScene); @@ -221,14 +221,14 @@ export class SceneSerializer { options?: SceneDeserializationOptions ): void { const opts: SceneDeserializationOptions = { - strategy: 'replace', + strategy: "replace", preserveIds: false, ...options }; let serializedScene: SerializedScene; try { - if (typeof saveData === 'string') { + if (typeof saveData === "string") { serializedScene = JSON.parse(saveData); } else { serializedScene = BinarySerializer.decode(saveData) as SerializedScene; @@ -250,7 +250,7 @@ export class SceneSerializer { const componentRegistry = opts.componentRegistry || this.getGlobalComponentRegistry(); // 根据策略处理场景 - if (opts.strategy === 'replace') { + if (opts.strategy === "replace") { // 清空场景 scene.destroyAllEntities(); } @@ -342,35 +342,35 @@ export class SceneSerializer { // 基本类型 const type = typeof value; - if (type === 'string' || type === 'number' || type === 'boolean') { + if (type === "string" || type === "number" || type === "boolean") { return value; } // Date if (value instanceof Date) { - return { __type: 'Date', value: value.toISOString() }; + return {__type: "Date", value: value.toISOString()}; } // Map if (value instanceof Map) { - return { __type: 'Map', value: Array.from(value.entries()) }; + return {__type: "Map", value: Array.from(value.entries())}; } // Set if (value instanceof Set) { - return { __type: 'Set', value: Array.from(value) }; + return {__type: "Set", value: Array.from(value)}; } // 数组 if (Array.isArray(value)) { - return value.map(item => this.serializeValue(item)); + return value.map((item) => this.serializeValue(item)); } // 普通对象 - if (type === 'object') { + if (type === "object") { const result: Record = {}; for (const key in value) { - if (value.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(value, key)) { result[key] = this.serializeValue(value[key]); } } @@ -391,32 +391,32 @@ export class SceneSerializer { // 基本类型 const type = typeof value; - if (type === 'string' || type === 'number' || type === 'boolean') { + if (type === "string" || type === "number" || type === "boolean") { return value; } // 处理特殊类型标记 - if (type === 'object' && value.__type) { + if (type === "object" && value.__type) { switch (value.__type) { - case 'Date': + case "Date": return new Date(value.value); - case 'Map': + case "Map": return new Map(value.value); - case 'Set': + case "Set": return new Set(value.value); } } // 数组 if (Array.isArray(value)) { - return value.map(item => this.deserializeValue(item)); + return value.map((item) => this.deserializeValue(item)); } // 普通对象 - if (type === 'object') { + if (type === "object") { const result: Record = {}; for (const key in value) { - if (value.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(value, key)) { result[key] = this.deserializeValue(value[key]); } } @@ -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) ); }); @@ -499,21 +499,21 @@ export class SceneSerializer { const data = JSON.parse(saveData); if (!data.version) { - errors.push('Missing version field'); + errors.push("Missing version field"); } if (!data.entities || !Array.isArray(data.entities)) { - errors.push('Missing or invalid entities field'); + errors.push("Missing or invalid entities field"); } if (!data.componentTypeRegistry || !Array.isArray(data.componentTypeRegistry)) { - errors.push('Missing or invalid componentTypeRegistry field'); + errors.push("Missing or invalid componentTypeRegistry field"); } return { valid: errors.length === 0, version: data.version, - ...(errors.length > 0 && { errors }) + ...(errors.length > 0 && {errors}) }; } catch (error) { return { @@ -542,7 +542,7 @@ export class SceneSerializer { return { name: data.name, version: data.version, - ...(data.timestamp !== undefined && { timestamp: data.timestamp }), + ...(data.timestamp !== undefined && {timestamp: data.timestamp}), entityCount: data.metadata?.entityCount || data.entities.length, componentTypeCount: data.componentTypeRegistry.length }; diff --git a/packages/core/src/ECS/Serialization/SerializationDecorators.ts b/packages/core/src/ECS/Serialization/SerializationDecorators.ts index e9969e7a..35a444ea 100644 --- a/packages/core/src/ECS/Serialization/SerializationDecorators.ts +++ b/packages/core/src/ECS/Serialization/SerializationDecorators.ts @@ -4,14 +4,14 @@ * 提供组件级别的序列化支持,包括字段级装饰器和类级装饰器 */ -import { Component } from '../Component'; +import {Component} from "../Component"; /** * 序列化元数据的Symbol键 */ -export const SERIALIZABLE_METADATA = Symbol('SerializableMetadata'); -export const SERIALIZE_FIELD = Symbol('SerializeField'); -export const SERIALIZE_OPTIONS = Symbol('SerializeOptions'); +export const SERIALIZABLE_METADATA = Symbol("SerializableMetadata"); +export const SERIALIZE_FIELD = Symbol("SerializeField"); +export const SERIALIZE_OPTIONS = Symbol("SerializeOptions"); /** * 可序列化配置选项 @@ -76,8 +76,8 @@ export interface SerializationMetadata { */ export function Serializable(options: SerializableOptions) { return function Component>(target: T): T { - if (!options || typeof options.version !== 'number') { - throw new Error('Serializable装饰器必须提供有效的版本号'); + if (!options || typeof options.version !== "number") { + throw new Error("Serializable装饰器必须提供有效的版本号"); } // 初始化或获取现有元数据 @@ -121,7 +121,7 @@ export function Serialize(options?: FieldSerializeOptions) { let metadata: SerializationMetadata = constructor[SERIALIZABLE_METADATA]; if (!metadata) { metadata = { - options: { version: 1 }, // 默认版本 + options: {version: 1}, // 默认版本 fields: new Map(), ignoredFields: new Set() }; @@ -212,7 +212,7 @@ export function IgnoreSerialization() { let metadata: SerializationMetadata = constructor[SERIALIZABLE_METADATA]; if (!metadata) { metadata = { - options: { version: 1 }, + options: {version: 1}, fields: new Map(), ignoredFields: new Set() }; @@ -236,7 +236,7 @@ export function getSerializationMetadata(componentClass: any): SerializationMeta } // 如果是实例,获取其构造函数 - const constructor = typeof componentClass === 'function' + const constructor = typeof componentClass === "function" ? componentClass : componentClass.constructor; diff --git a/packages/core/src/ECS/Serialization/VersionMigration.ts b/packages/core/src/ECS/Serialization/VersionMigration.ts index 171410da..ce59f921 100644 --- a/packages/core/src/ECS/Serialization/VersionMigration.ts +++ b/packages/core/src/ECS/Serialization/VersionMigration.ts @@ -4,8 +4,8 @@ * 提供组件和场景数据的版本迁移支持 */ -import { SerializedComponent } from './ComponentSerializer'; -import { SerializedScene } from './SceneSerializer'; +import {SerializedComponent} from "./ComponentSerializer"; +import {SerializedScene} from "./SceneSerializer"; /** * 组件迁移函数 @@ -127,7 +127,7 @@ export class VersionMigrationManager { return component; } - let migratedData = { ...component }; + const migratedData = {...component}; let version = currentVersion; // 执行迁移链 @@ -163,7 +163,7 @@ export class VersionMigrationManager { return scene; // 版本相同,无需迁移 } - let migratedScene = { ...scene }; + let migratedScene = {...scene}; let version = currentVersion; // 执行场景级迁移 @@ -191,14 +191,14 @@ export class VersionMigrationManager { * 迁移场景中所有组件的版本 */ private static migrateSceneComponents(scene: SerializedScene): SerializedScene { - const migratedScene = { ...scene }; + 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/Serialization/index.ts b/packages/core/src/ECS/Serialization/index.ts index 154c9df1..3a0a861d 100644 --- a/packages/core/src/ECS/Serialization/index.ts +++ b/packages/core/src/ECS/Serialization/index.ts @@ -16,24 +16,24 @@ export { SERIALIZABLE_METADATA, SERIALIZE_FIELD, SERIALIZE_OPTIONS -} from './SerializationDecorators'; +} from "./SerializationDecorators"; export type { SerializableOptions, FieldSerializeOptions, SerializationMetadata -} from './SerializationDecorators'; +} from "./SerializationDecorators"; // 组件序列化器 -export { ComponentSerializer } from './ComponentSerializer'; -export type { SerializedComponent } from './ComponentSerializer'; +export {ComponentSerializer} from "./ComponentSerializer"; +export type {SerializedComponent} from "./ComponentSerializer"; // 实体序列化器 -export { EntitySerializer } from './EntitySerializer'; -export type { SerializedEntity } from './EntitySerializer'; +export {EntitySerializer} from "./EntitySerializer"; +export type {SerializedEntity} from "./EntitySerializer"; // 场景序列化器 -export { SceneSerializer } from './SceneSerializer'; +export {SceneSerializer} from "./SceneSerializer"; export type { SerializedScene, SerializationFormat, @@ -41,17 +41,17 @@ export type { MigrationFunction, SceneSerializationOptions, SceneDeserializationOptions -} from './SceneSerializer'; +} from "./SceneSerializer"; // 版本迁移 -export { VersionMigrationManager, MigrationBuilder } from './VersionMigration'; +export {VersionMigrationManager, MigrationBuilder} from "./VersionMigration"; export type { ComponentMigrationFunction, SceneMigrationFunction -} from './VersionMigration'; +} from "./VersionMigration"; // 增量序列化 -export { IncrementalSerializer, ChangeOperation } from './IncrementalSerializer'; +export {IncrementalSerializer, ChangeOperation} from "./IncrementalSerializer"; export type { IncrementalSnapshot, IncrementalSerializationOptions, @@ -59,4 +59,4 @@ export type { EntityChange, ComponentChange, SceneDataChange -} from './IncrementalSerializer'; +} from "./IncrementalSerializer"; diff --git a/packages/core/src/ECS/Systems/EntitySystem.ts b/packages/core/src/ECS/Systems/EntitySystem.ts index c8773122..4df55de9 100644 --- a/packages/core/src/ECS/Systems/EntitySystem.ts +++ b/packages/core/src/ECS/Systems/EntitySystem.ts @@ -1,14 +1,15 @@ -import { Entity } from '../Entity'; -import { PerformanceMonitor } from '../../Utils/PerformanceMonitor'; -import { Matcher, type QueryCondition } from '../Utils/Matcher'; -import type { Scene } from '../Scene'; -import type { ISystemBase } from '../../Types'; -import type { QuerySystem } from '../Core/QuerySystem'; -import { getSystemInstanceTypeName } from '../Decorators'; -import { createLogger } from '../../Utils/Logger'; -import type { EventListenerConfig, TypeSafeEventSystem, EventHandler } from '../Core/EventSystem'; -import type { ComponentConstructor, ComponentInstance } from '../../Types/TypeHelpers'; -import type { IService } from '../../Core/ServiceContainer'; +import {Entity} from "../Entity"; +import {PerformanceMonitor} from "../../Utils/PerformanceMonitor"; +import {Matcher, type QueryCondition} from "../Utils/Matcher"; +import type {Scene} from "../Scene"; +import type {ISystemBase} from "../../Types"; +import type {QuerySystem} from "../Core/QuerySystem"; +import {getSystemInstanceTypeName} from "../Decorators"; +import {createLogger} from "../../Utils/Logger"; +import type {EventListenerConfig, TypeSafeEventSystem, EventHandler} from "../Core/EventSystem"; +import type {ComponentConstructor, ComponentInstance} from "../../Types/TypeHelpers"; +import type {IService} from "../../Core/ServiceContainer"; +import type {ComponentType} from "../Core/ComponentStorage"; /** * 事件监听器记录 @@ -251,7 +252,7 @@ export abstract class EntitySystem< /** * 系统初始化回调 - * + * * 子类可以重写此方法进行初始化操作。 */ protected onInitialize(): void { @@ -259,8 +260,11 @@ export abstract class EntitySystem< } /** - * 清除实体缓存(内部使用) - * 当Scene中的实体发生变化时调用 + * 清除实体缓存 + * + * 当 Scene 中的实体发生变化时调用,使系统的实体缓存失效。 + * + * @internal 框架内部使用,不应在外部代码中直接调用 */ public clearEntityCache(): void { this._entityCache.invalidate(); @@ -299,7 +303,7 @@ export abstract class EntitySystem< // 空条件返回所有实体 if (this._matcher.isEmpty()) { - currentEntities = querySystem.getAllEntities(); + currentEntities = querySystem.queryAllEntities(); } else if (this.isSingleCondition(condition)) { // 单一条件优化查询 currentEntities = this.executeSingleConditionQuery(condition, querySystem); @@ -403,7 +407,7 @@ export abstract class EntitySystem< // 6. 应用none条件 (差集) if (condition.none.length > 0) { if (!resultIds) { - resultIds = this.extractEntityIds(querySystem.getAllEntities()); + resultIds = this.extractEntityIds(querySystem.queryAllEntities()); } const noneResult = querySystem.queryAny(...condition.none); @@ -411,16 +415,23 @@ export abstract class EntitySystem< resultIds = this.differenceIdSets(resultIds, noneIds); } - return resultIds ? this.idSetToEntityArray(resultIds, querySystem.getAllEntities()) : []; + return resultIds ? this.idSetToEntityArray(resultIds, querySystem.queryAllEntities()) : []; } /** * 提取实体ID集合 + * + * 使用位运算 | 0 强制转换为 32 位整数,帮助 JavaScript 引擎的 JIT 编译器 + * 进行整数优化,在大规模实体集合操作时可以提供微小的性能提升。 + * + * @param entities 实体数组 + * @returns 包含所有实体ID的集合 */ private extractEntityIds(entities: readonly Entity[]): Set { const len = entities.length; const idSet = new Set(); + // 使用位运算 | 0 进行整数优化(JIT 友好) for (let i = 0; i < len; i = (i + 1) | 0) { idSet.add(entities[i]!.id | 0); } @@ -482,6 +493,12 @@ export abstract class EntitySystem< /** * 重建实体ID映射 + * + * 重新构建从实体ID到实体引用的映射表。使用位运算优化性能。 + * + * @param allEntities 所有实体的数组 + * @param version QuerySystem 的版本号,用于缓存失效判断 + * @returns 重建后的实体ID映射表 */ private rebuildEntityIdMap(allEntities: readonly Entity[], version: number): Map { let entityMap = this._entityIdMap; @@ -493,6 +510,7 @@ export abstract class EntitySystem< } const len = allEntities.length; + // 使用位运算 | 0 进行整数优化(JIT 友好) for (let i = 0; i < len; i = (i + 1) | 0) { const entity = allEntities[i]!; entityMap.set(entity.id | 0, entity); @@ -506,6 +524,12 @@ export abstract class EntitySystem< /** * 从ID集合构建Entity数组 + * + * 将实体ID集合转换为实体引用数组。跳过无效的实体ID(已被删除的实体)。 + * + * @param idSet 实体ID集合 + * @param allEntities 所有实体的数组(用于构建映射表) + * @returns 实体引用数组 */ private idSetToEntityArray(idSet: Set, allEntities: readonly Entity[]): readonly Entity[] { const entityMap = this.getEntityIdMap(allEntities); @@ -518,10 +542,12 @@ export abstract class EntitySystem< const entity = entityMap.get(id); if (entity !== undefined) { result[index] = entity; + // 使用位运算 | 0 进行整数优化(JIT 友好) index = (index + 1) | 0; } } + // 如果有无效ID,调整数组长度 if (index < size) { result.length = index; } @@ -531,7 +557,7 @@ export abstract class EntitySystem< /** * 执行复合查询 - * + * * 使用基于ID集合的单次扫描算法进行复杂查询 */ private executeComplexQuery(condition: QueryCondition, querySystem: QuerySystem): readonly Entity[] { @@ -590,7 +616,7 @@ export abstract class EntitySystem< /** * 在系统处理开始前调用 - * + * * 子类可以重写此方法进行预处理操作。 */ protected onBegin(): void { @@ -599,9 +625,9 @@ export abstract class EntitySystem< /** * 处理实体列表 - * + * * 系统的核心逻辑,子类必须实现此方法来定义具体的处理逻辑。 - * + * * @param entities 要处理的实体列表 */ protected process(_entities: readonly Entity[]): void { @@ -610,9 +636,9 @@ export abstract class EntitySystem< /** * 后期处理实体列表 - * + * * 在主要处理逻辑之后执行,子类可以重写此方法。 - * + * * @param entities 要处理的实体列表 */ protected lateProcess(_entities: readonly Entity[]): void { @@ -621,7 +647,7 @@ export abstract class EntitySystem< /** * 系统处理完毕后调用 - * + * * 子类可以重写此方法进行后处理操作。 */ protected onEnd(): void { @@ -630,10 +656,10 @@ export abstract class EntitySystem< /** * 检查系统是否需要处理 - * + * * 在启用系统时有用,但仅偶尔需要处理。 * 这只影响处理,不影响事件或订阅列表。 - * + * * @returns 如果系统应该处理,则为true,如果不处理则为false */ protected onCheckProcessing(): boolean { @@ -667,13 +693,13 @@ export abstract class EntitySystem< /** * 获取系统信息的字符串表示 - * + * * @returns 系统信息字符串 */ public toString(): string { const entityCount = this.entities.length; const perfData = this.getPerformanceData(); - const perfInfo = perfData ? ` (${perfData.executionTime.toFixed(2)}ms)` : ''; + const perfInfo = perfData ? ` (${perfData.executionTime.toFixed(2)}ms)` : ""; return `${this._systemName}[${entityCount} entities]${perfInfo}`; } @@ -711,9 +737,9 @@ export abstract class EntitySystem< /** * 当实体被添加到系统时调用 - * + * * 子类可以重写此方法来处理实体添加事件。 - * + * * @param entity 被添加的实体 */ protected onAdded(_entity: Entity): void { @@ -803,7 +829,7 @@ export abstract class EntitySystem< handler: EventHandler ): void { const listenerIndex = this._eventListeners.findIndex( - listener => listener.eventType === eventType && listener.handler === handler + (listener) => listener.eventType === eventType && listener.handler === handler ); if (listenerIndex >= 0) { @@ -891,7 +917,7 @@ export abstract class EntitySystem< entity: Entity, componentType: T ): ComponentInstance { - const component = entity.getComponent(componentType as any); + const component = entity.getComponent(componentType as ComponentType); if (!component) { throw new Error( `Component ${componentType.name} not found on entity ${entity.name} in ${this.systemName}` @@ -929,7 +955,7 @@ export abstract class EntitySystem< ): { [K in keyof T]: ComponentInstance } { return components.map((type) => this.requireComponent(entity, type) - ) as any; + ) as { [K in keyof T]: ComponentInstance }; } /** diff --git a/packages/core/src/ECS/Systems/IntervalSystem.ts b/packages/core/src/ECS/Systems/IntervalSystem.ts index 89a6a6a8..dba9ebcf 100644 --- a/packages/core/src/ECS/Systems/IntervalSystem.ts +++ b/packages/core/src/ECS/Systems/IntervalSystem.ts @@ -1,6 +1,6 @@ -import { EntitySystem } from './EntitySystem'; -import { Matcher } from '../Utils/Matcher'; -import { Time } from '../../Utils/Time'; +import {EntitySystem} from "./EntitySystem"; +import {Matcher} from "../Utils/Matcher"; +import {Time} from "../../Utils/Time"; /** * 间隔系统抽象类 @@ -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..9cc103c6 100644 --- a/packages/core/src/ECS/Systems/PassiveSystem.ts +++ b/packages/core/src/ECS/Systems/PassiveSystem.ts @@ -1,6 +1,6 @@ -import { EntitySystem } from './EntitySystem'; -import { Entity } from '../Entity'; -import { Matcher } from '../Utils/Matcher'; +import {EntitySystem} from "./EntitySystem"; +import {Entity} from "../Entity"; +import {Matcher} from "../Utils/Matcher"; /** * 被动实体系统 @@ -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..1291378f 100644 --- a/packages/core/src/ECS/Systems/ProcessingSystem.ts +++ b/packages/core/src/ECS/Systems/ProcessingSystem.ts @@ -1,6 +1,6 @@ -import { EntitySystem } from './EntitySystem'; -import { Entity } from '../Entity'; -import { Matcher } from '../Utils/Matcher'; +import {EntitySystem} from "./EntitySystem"; +import {Entity} from "../Entity"; +import {Matcher} from "../Utils/Matcher"; /** * 处理系统抽象类 @@ -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..29c7d069 100644 --- a/packages/core/src/ECS/Systems/WorkerEntitySystem.ts +++ b/packages/core/src/ECS/Systems/WorkerEntitySystem.ts @@ -1,10 +1,10 @@ -import { Entity } from '../Entity'; -import { EntitySystem } from './EntitySystem'; -import { Matcher } from '../Utils/Matcher'; -import { Time } from '../../Utils/Time'; -import { PlatformManager } from '../../Platform/PlatformManager'; -import type { IPlatformAdapter, PlatformWorker } from '../../Platform/IPlatformAdapter'; -import { getSystemInstanceTypeName } from '../Decorators'; +import {Entity} from "../Entity"; +import {EntitySystem} from "./EntitySystem"; +import {Matcher} from "../Utils/Matcher"; +import {Time} from "../../Utils/Time"; +import {PlatformManager} from "../../Platform/PlatformManager"; +import type {IPlatformAdapter, PlatformWorker} from "../../Platform/IPlatformAdapter"; +import {getSystemInstanceTypeName} from "../Decorators"; /** * Worker处理函数类型 @@ -188,7 +188,7 @@ export type SharedArrayBufferProcessFunction = ( * ``` */ export abstract class WorkerEntitySystem extends EntitySystem { - protected config: Required> & { + protected config: Required> & { systemConfig?: any; entitiesPerWorker?: number; }; @@ -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); @@ -219,7 +219,7 @@ export abstract class WorkerEntitySystem extends EntitySystem enableWorker: config.enableWorker ?? true, workerCount: validatedWorkerCount, systemConfig: config.systemConfig, - ...(config.entitiesPerWorker !== undefined && { entitiesPerWorker: config.entitiesPerWorker }), + ...(config.entitiesPerWorker !== undefined && {entitiesPerWorker: config.entitiesPerWorker}), useSharedArrayBuffer: config.useSharedArrayBuffer ?? this.isSharedArrayBufferSupported(), entityDataSize: config.entityDataSize ?? this.getDefaultEntityDataSize(), maxEntities: config.maxEntities ?? 10000 @@ -305,7 +305,7 @@ export abstract class WorkerEntitySystem extends EntitySystem // 在WorkerEntitySystem中处理平台相关逻辑 const workers: PlatformWorker[] = []; const platformConfig = this.platformAdapter.getPlatformConfig(); - const fullScript = (platformConfig.workerScriptPrefix || '') + script; + const fullScript = (platformConfig.workerScriptPrefix || "") + script; for (let i = 0; i < this.config.workerCount; i++) { try { @@ -336,7 +336,7 @@ export abstract class WorkerEntitySystem extends EntitySystem // 提取函数体部分(去掉方法签名) const functionBodyMatch = methodStr.match(/\{([\s\S]*)\}/); if (!functionBodyMatch) { - throw new Error('无法解析workerProcess方法'); + throw new Error("无法解析workerProcess方法"); } const functionBody = functionBodyMatch[1]; @@ -344,13 +344,13 @@ export abstract class WorkerEntitySystem extends EntitySystem // 获取SharedArrayBuffer处理函数的字符串 const sharedProcessMethod = this.getSharedArrayBufferProcessFunction?.() || null; - let sharedProcessFunctionBody = ''; + let sharedProcessFunctionBody = ""; if (sharedProcessMethod) { const sharedMethodStr = sharedProcessMethod.toString(); const sharedFunctionBodyMatch = sharedMethodStr.match(/\{([\s\S]*)\}/); if (sharedFunctionBodyMatch) { - sharedProcessFunctionBody = sharedFunctionBodyMatch[1] ?? ''; + sharedProcessFunctionBody = sharedFunctionBodyMatch[1] ?? ""; } } @@ -414,7 +414,7 @@ export abstract class WorkerEntitySystem extends EntitySystem ${sharedProcessFunctionBody} }; userProcessFunction(sharedFloatArray, startIndex, endIndex, deltaTime, systemConfig); - ` : ``} + ` : ""} } `; } @@ -465,7 +465,7 @@ export abstract class WorkerEntitySystem extends EntitySystem */ private async processWithSharedArrayBuffer(entities: readonly Entity[]): Promise { if (!this.sharedFloatArray) { - throw new Error('SharedArrayBuffer not initialized'); + throw new Error("SharedArrayBuffer not initialized"); } // 1. 将实体数据写入SharedArrayBuffer @@ -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; @@ -533,8 +533,8 @@ export abstract class WorkerEntitySystem extends EntitySystem // 3. 结果应用阶段 // 处理Promise返回值 - if (results && typeof (results as any).then === 'function') { - (results as Promise).then(finalResults => { + if (results && typeof (results as any).then === "function") { + (results as Promise).then((finalResults) => { entities.forEach((entity, index) => { this.applyResult(entity, finalResults[index]!); }); @@ -721,7 +721,7 @@ export abstract class WorkerEntitySystem extends EntitySystem * 更新Worker配置 */ public updateConfig(newConfig: Partial): void { - const oldConfig = { ...this.config }; + const oldConfig = {...this.config}; // 如果更新了workerCount,需要验证并调整 if (newConfig.workerCount !== undefined) { @@ -812,22 +812,22 @@ export abstract class WorkerEntitySystem extends EntitySystem isProcessing: boolean; sharedArrayBufferSupported: boolean; sharedArrayBufferEnabled: boolean; - currentMode: 'shared-buffer' | 'worker' | 'sync'; - } { - let currentMode: 'shared-buffer' | 'worker' | 'sync' = 'sync'; + currentMode: "shared-buffer" | "worker" | "sync"; + } { + let currentMode: "shared-buffer" | "worker" | "sync" = "sync"; if (this.config.enableWorker && this.workerPool) { if (this.config.useSharedArrayBuffer && this.sharedFloatArray && this.isSharedArrayBufferSupported()) { - currentMode = 'shared-buffer'; + currentMode = "shared-buffer"; } else { - currentMode = 'worker'; + currentMode = "worker"; } } return { enabled: this.config.enableWorker, workerCount: this.config.workerCount, - ...(this.config.entitiesPerWorker !== undefined && { entitiesPerWorker: this.config.entitiesPerWorker }), + ...(this.config.entitiesPerWorker !== undefined && {entitiesPerWorker: this.config.entitiesPerWorker}), maxSystemWorkerCount: this.getMaxSystemWorkerCount(), isProcessing: this.isProcessing, sharedArrayBufferSupported: this.isSharedArrayBufferSupported(), @@ -890,7 +890,7 @@ class PlatformWorkerPool { return new Promise((resolve, reject) => { const task = { id: `shared-task-${++this.taskCounter}`, - data: { ...data, type: 'shared' }, + data: {...data, type: "shared"}, resolve: () => resolve(), // SharedArrayBuffer不需要返回数据 reject }; diff --git a/packages/core/src/ECS/Systems/index.ts b/packages/core/src/ECS/Systems/index.ts index 0f3cd186..68c7f85e 100644 --- a/packages/core/src/ECS/Systems/index.ts +++ b/packages/core/src/ECS/Systems/index.ts @@ -1,13 +1,13 @@ // ECS系统导出 -export { EntitySystem } from './EntitySystem'; -export { ProcessingSystem } from './ProcessingSystem'; -export { PassiveSystem } from './PassiveSystem'; -export { IntervalSystem } from './IntervalSystem'; -export { WorkerEntitySystem } from './WorkerEntitySystem'; +export {EntitySystem} from "./EntitySystem"; +export {ProcessingSystem} from "./ProcessingSystem"; +export {PassiveSystem} from "./PassiveSystem"; +export {IntervalSystem} from "./IntervalSystem"; +export {WorkerEntitySystem} from "./WorkerEntitySystem"; // Worker系统相关类型导出 export type { WorkerProcessFunction, WorkerSystemConfig, SharedArrayBufferProcessFunction -} from './WorkerEntitySystem'; \ No newline at end of file +} from "./WorkerEntitySystem"; diff --git a/packages/core/src/ECS/TypedEntity.ts b/packages/core/src/ECS/TypedEntity.ts index a61d3763..effa1336 100644 --- a/packages/core/src/ECS/TypedEntity.ts +++ b/packages/core/src/ECS/TypedEntity.ts @@ -4,10 +4,10 @@ * 提供类型安全的组件操作工具函数,无需修改Entity类 */ -import { Entity } from './Entity'; -import type { Component } from './Component'; -import type { ComponentType } from './Core/ComponentStorage'; -import type { ComponentConstructor, ComponentInstance } from '../Types/TypeHelpers'; +import {Entity} from "./Entity"; +import type {Component} from "./Component"; +import type {ComponentType} from "./Core/ComponentStorage"; +import type {ComponentConstructor, ComponentInstance} from "../Types/TypeHelpers"; /** * 获取组件,如果不存在则抛出错误 diff --git a/packages/core/src/ECS/Utils/BigIntCompatibility.ts b/packages/core/src/ECS/Utils/BigIntCompatibility.ts index a7637937..c6b9fff7 100644 --- a/packages/core/src/ECS/Utils/BigIntCompatibility.ts +++ b/packages/core/src/ECS/Utils/BigIntCompatibility.ts @@ -25,7 +25,7 @@ export interface BitMask64Data { export class BitMask64Utils { /** 零掩码常量,所有位都为0 */ - public static readonly ZERO: Readonly = { base: [0, 0] }; + public static readonly ZERO: Readonly = {base: [0, 0]}; /** * 根据位索引创建64位掩码 @@ -37,7 +37,7 @@ export class BitMask64Utils { if (bitIndex < 0) { throw new Error(`Bit index ${bitIndex} out of range [0, ∞)`); } - const mask: BitMask64Data = { base: [0, 0] }; + const mask: BitMask64Data = {base: [0, 0]}; BitMask64Utils.setBit(mask, bitIndex); return mask; } @@ -48,7 +48,7 @@ export class BitMask64Utils { * @returns 低32位为输入值、高32位为0的掩码 */ public static fromNumber(value: number): BitMask64Data { - return { base: [value >>> 0, 0] }; + return {base: [value >>> 0, 0]}; } /** @@ -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)}) }; } @@ -396,7 +396,7 @@ export class BitMask64Utils { public static toString(mask: BitMask64Data, radix: 2 | 16 = 2, printHead: boolean = false): string { if(radix != 2 && radix != 16) radix = 2; const totalLength = mask.segments?.length ?? 0; - let result: string = ''; + let result: string = ""; if(printHead){ let paddingLength = 0; if(radix === 2){ @@ -405,38 +405,38 @@ export class BitMask64Utils { paddingLength = 16 + 2 + 1; } for (let i = 0; i <= totalLength; i++) { - const title = i === 0 ? '0 (Base):' : `${i} (${64 * i}):`; + const title = i === 0 ? "0 (Base):" : `${i} (${64 * i}):`; result += title.toString().padEnd(paddingLength); } - result += '\n'; + result += "\n"; } for (let i = -1; i < totalLength; i++) { - let segResult = ''; + 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'); - segResult = hiBits + '_' + loBits; //高低位之间使用_隔离 + const hiBits = hi.toString(2).padStart(32, "0"); + const loBits = lo.toString(2).padStart(32, "0"); + segResult = hiBits + "_" + loBits; //高低位之间使用_隔离 }else{ - let hiBits = hi ? hi.toString(16).toUpperCase() : ''; + let hiBits = hi ? hi.toString(16).toUpperCase() : ""; if(printHead){ // 存在标头,则输出高位之前需要补齐位数 - hiBits = hiBits.padStart(8, '0'); + hiBits = hiBits.padStart(8, "0"); } let loBits = lo.toString(16).toUpperCase(); if(hiBits){ // 存在高位 则输出低位之前需要补齐位数 - loBits = loBits.padStart(8, '0'); + loBits = loBits.padStart(8, "0"); } - segResult = '0x' + hiBits + loBits; + segResult = "0x" + hiBits + loBits; } if(i === -1) result += segResult; else - result += ' ' + segResult; // 不同段之间使用空格隔离 + result += " " + segResult; // 不同段之间使用空格隔离 } return result; } @@ -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..0456ca2f 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..f586e839 100644 --- a/packages/core/src/ECS/Utils/Bits.ts +++ b/packages/core/src/ECS/Utils/Bits.ts @@ -1,4 +1,4 @@ -import { SegmentPart, BitMask64Data, BitMask64Utils } from './BigIntCompatibility'; +import {SegmentPart, BitMask64Data, BitMask64Utils} from "./BigIntCompatibility"; /** * 位集合类,用于高效的位操作 @@ -13,11 +13,11 @@ export class Bits { * @param initialValue 初始值,可以是BitMask64Data对象、数字或字符串 */ constructor(initialValue?: BitMask64Data | number | string) { - if (initialValue && typeof initialValue === 'object') { + if (initialValue && typeof initialValue === "object") { this._value = BitMask64Utils.clone(initialValue); - } else if (typeof initialValue === 'number') { + } else if (typeof initialValue === "number") { this._value = BitMask64Utils.fromNumber(initialValue); - } else if (typeof initialValue === 'string') { + } else if (typeof initialValue === "string") { const num = parseInt(initialValue, 10); this._value = BitMask64Utils.fromNumber(num); } else { @@ -33,7 +33,7 @@ export class Bits { */ public set(index: number): void { if (index < 0) { - throw new Error('Bit index cannot be negative'); + throw new Error("Bit index cannot be negative"); } BitMask64Utils.setBit(this._value, index); @@ -46,7 +46,7 @@ export class Bits { */ public clear(index: number): void { if (index < 0) { - throw new Error('Bit index cannot be negative'); + throw new Error("Bit index cannot be negative"); } BitMask64Utils.clearBit(this._value, index); @@ -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; } @@ -207,9 +207,9 @@ export class Bits { * @param value 新值,可以是BitMask64Data对象、数字或字符串 */ public setValue(value: BitMask64Data | number | string): void { - if (typeof value === 'object') { + if (typeof value === "object") { BitMask64Utils.copy(value, this._value); - } else if (typeof value === 'number') { + } else if (typeof value === "number") { this._value = BitMask64Utils.fromNumber(value); } else { const num = parseInt(value, 10); @@ -228,7 +228,7 @@ export class Bits { bits.push(i.toString()); } } - return `Bits[${bits.join(', ')}]`; + return `Bits[${bits.join(", ")}]`; } /** @@ -240,11 +240,11 @@ export class Bits { if(maxBits == 0){ maxBits = 64 + (this._value.segments ? this._value.segments.length * 64 : 0); } - let result = ''; + let result = ""; for (let i = maxBits - 1; i >= 0; i--) { - result += this.get(i) ? '1' : '0'; + result += this.get(i) ? "1" : "0"; if (i % 8 === 0 && i > 0) { - result += ' '; + result += " "; } } return result; @@ -264,17 +264,17 @@ export class Bits { * @returns 新的位集合对象 */ public static fromBinaryString(binaryString: string): Bits { - const cleanString = binaryString.replace(/\s/g, ''); + const cleanString = binaryString.replace(/\s/g, ""); let data: BitMask64Data; if (cleanString.length <= 32) { const num = parseInt(cleanString, 2); - data = { base: [num >>> 0, 0] }; + data = {base: [num >>> 0, 0]}; } else { const loBits = cleanString.substring(cleanString.length - 32); const hiBits = cleanString.substring(0, cleanString.length - 32); const lo = parseInt(loBits, 2); const hi = parseInt(hiBits, 2); - data = { base: [lo >>> 0, hi >>> 0] }; + data = {base: [lo >>> 0, hi >>> 0]}; } return new Bits(data); } @@ -285,17 +285,17 @@ export class Bits { * @returns 新的位集合对象 */ public static fromHexString(hexString: string): Bits { - const cleanString = hexString.replace(/^0x/i, ''); + const cleanString = hexString.replace(/^0x/i, ""); let data: BitMask64Data; if (cleanString.length <= 8) { const num = parseInt(cleanString, 16); - data = { base: [num >>> 0, 0] }; + data = {base: [num >>> 0, 0]}; } else { const loBits = cleanString.substring(cleanString.length - 8); const hiBits = cleanString.substring(0, cleanString.length - 8); const lo = parseInt(loBits, 16); const hi = parseInt(hiBits, 16); - data = { base: [lo >>> 0, hi >>> 0] }; + data = {base: [lo >>> 0, hi >>> 0]}; } return new Bits(data); } @@ -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..e4f247f5 100644 --- a/packages/core/src/ECS/Utils/ComponentSparseSet.ts +++ b/packages/core/src/ECS/Utils/ComponentSparseSet.ts @@ -1,20 +1,20 @@ -import { Entity } from '../Entity'; -import { ComponentType, ComponentRegistry } from '../Core/ComponentStorage'; -import { BitMask64Utils, BitMask64Data } from './BigIntCompatibility'; -import { SparseSet } from './SparseSet'; -import { Pool } from '../../Utils/Pool/Pool'; -import { IPoolable } from '../../Utils/Pool/IPoolable'; +import {Entity} from "../Entity"; +import {ComponentType, ComponentRegistry} from "../Core/ComponentStorage"; +import {BitMask64Utils, BitMask64Data} from "./BigIntCompatibility"; +import {SparseSet} from "./SparseSet"; +import {Pool} from "../../Utils/Pool/Pool"; +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,45 @@ export class ComponentSparseSet { } return this._componentMasks[entityIndex]; } - + /** - * 获取所有实体 - * + * 查询所有实体 + * + * 返回拥有此组件的所有实体。 + * * @returns 所有实体的数组 */ - public getAllEntities(): Entity[] { + public queryAllEntities(): Entity[] { return this._entities.toArray(); } - + + /** + * 获取所有实体 + * + * @deprecated 使用 queryAllEntities() 代替,以保持命名一致性 + * @see {@link queryAllEntities} + */ + public getAllEntities(): Entity[] { + return this.queryAllEntities(); + } + /** * 获取实体数量 */ 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 +316,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 +339,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 +355,7 @@ export class ComponentSparseSet { totalMemory: entitiesStats.totalMemory + masksMemory + mappingsMemory }; } - + /** * 验证数据结构完整性 */ @@ -352,12 +364,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 +377,17 @@ export class ComponentSparseSet { allMappedEntities.add(entity); } } - + // 验证映射中的实体都在稀疏集合中 for (const entity of allMappedEntities) { if (!this._entities.has(entity)) { return false; } } - + return true; } - + /** * 获取实体的组件类型集合 */ @@ -386,18 +398,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 +427,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..7cee2cb3 100644 --- a/packages/core/src/ECS/Utils/EntityList.ts +++ b/packages/core/src/ECS/Utils/EntityList.ts @@ -1,5 +1,5 @@ -import { Entity } from '../Entity'; -import { Component } from '../Component'; +import {Entity} from "../Entity"; +import {Component} from "../Component"; /** * 高性能实体列表管理器 @@ -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..088b495f 100644 --- a/packages/core/src/ECS/Utils/EntityProcessorList.ts +++ b/packages/core/src/ECS/Utils/EntityProcessorList.ts @@ -1,13 +1,13 @@ -import { EntitySystem } from '../Systems/EntitySystem'; -import { createLogger } from '../../Utils/Logger'; -import { getSystemInstanceTypeName } from '../Decorators'; +import {EntitySystem} from "../Systems/EntitySystem"; +import {createLogger} from "../../Utils/Logger"; +import {getSystemInstanceTypeName} from "../Decorators"; /** * 实体处理器列表管理器 * 管理场景中的所有实体系统 */ export class EntityProcessorList { - private static readonly _logger = createLogger('EntityProcessorList'); + private static readonly _logger = createLogger("EntityProcessorList"); private _processors: EntitySystem[] = []; private _isDirty = false; @@ -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..27fb4c76 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..feffb887 100644 --- a/packages/core/src/ECS/Utils/Matcher.ts +++ b/packages/core/src/ECS/Utils/Matcher.ts @@ -1,5 +1,5 @@ -import { ComponentType } from '../Core/ComponentStorage'; -import { getComponentTypeName } from '../Decorators'; +import {ComponentType} from "../Core/ComponentStorage"; +import {getComponentTypeName} from "../Decorators"; /** * 查询条件类型 @@ -15,15 +15,15 @@ export interface QueryCondition { /** * 实体匹配条件描述符 - * + * * 用于描述实体查询条件,不执行实际查询 - * + * * @example * ```typescript * const matcher = Matcher.all(Position, Velocity) * .any(Health, Shield) * .none(Dead); - * + * * // 获取查询条件 * const condition = matcher.getCondition(); * ``` @@ -209,9 +209,9 @@ export class Matcher { all: [...this.condition.all], any: [...this.condition.any], none: [...this.condition.none], - ...(this.condition.tag !== undefined && { tag: this.condition.tag }), - ...(this.condition.name !== undefined && { name: this.condition.name }), - ...(this.condition.component !== undefined && { component: this.condition.component }) + ...(this.condition.tag !== undefined && {tag: this.condition.tag}), + ...(this.condition.name !== undefined && {name: this.condition.name}), + ...(this.condition.component !== undefined && {component: this.condition.component}) }; } @@ -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(' & ')}]`; + + 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..af6fe921 100644 --- a/packages/core/src/ECS/Utils/index.ts +++ b/packages/core/src/ECS/Utils/index.ts @@ -1,9 +1,9 @@ // ECS工具类导出 -export { EntityList } from './EntityList'; -export { EntityProcessorList } from './EntityProcessorList'; -export { IdentifierPool } from './IdentifierPool'; -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 {EntityList} from "./EntityList"; +export {EntityProcessorList} from "./EntityProcessorList"; +export {IdentifierPool} from "./IdentifierPool"; +export {Matcher} from "./Matcher"; +export {Bits} from "./Bits"; +export {BitMask64Utils, BitMask64Data} from "./BigIntCompatibility"; +export {SparseSet} from "./SparseSet"; +export {ComponentSparseSet} from "./ComponentSparseSet"; diff --git a/packages/core/src/ECS/World.ts b/packages/core/src/ECS/World.ts index 6e018f29..e648f4fa 100644 --- a/packages/core/src/ECS/World.ts +++ b/packages/core/src/ECS/World.ts @@ -1,8 +1,8 @@ -import { IScene } from './IScene'; -import { Scene } from './Scene'; -import { createLogger } from '../Utils/Logger'; +import {IScene} from "./IScene"; +import {Scene} from "./Scene"; +import {createLogger} from "../Utils/Logger"; -const logger = createLogger('World'); +const logger = createLogger("World"); /** * 全局系统接口 @@ -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); * ``` @@ -93,13 +93,13 @@ export class World { constructor(config: IWorldConfig = {}) { this._config = { - name: 'World', + name: "World", debug: false, maxScenes: 10, autoCleanup: true, ...config }; - + this.name = this._config.name!; this._createdAt = Date.now(); } @@ -120,12 +120,12 @@ export class World { // 如果没有提供Scene实例,创建默认Scene const scene = sceneInstance || (new Scene() as unknown as T); - + // 设置Scene的标识 - if ('id' in scene) { + if ("id" in scene) { (scene as any).id = sceneId; } - if ('name' in scene && !scene.name) { + if ("name" in scene && !scene.name) { scene.name = 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}`); } @@ -407,8 +407,8 @@ export class World { activeSceneCount: this._activeScenes.size, globalSystemCount: this._globalSystems.length, createdAt: this._createdAt, - config: { ...this._config }, - scenes: Array.from(this._scenes.keys()).map(sceneId => ({ + config: {...this._config}, + 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..431c3049 100644 --- a/packages/core/src/ECS/WorldManager.ts +++ b/packages/core/src/ECS/WorldManager.ts @@ -1,8 +1,8 @@ -import { World, IWorldConfig } from './World'; -import { createLogger } from '../Utils/Logger'; -import type { IService } from '../Core/ServiceContainer'; +import {World, IWorldConfig} from "./World"; +import {createLogger} from "../Utils/Logger"; +import type {IService} from "../Core/ServiceContainer"; -const logger = createLogger('WorldManager'); +const logger = createLogger("WorldManager"); /** * WorldManager配置接口 @@ -12,17 +12,17 @@ export interface IWorldManagerConfig { * 最大World数量 */ maxWorlds?: number; - + /** * 是否自动清理空World */ autoCleanup?: boolean; - + /** * 清理间隔(毫秒) */ cleanupInterval?: number; - + /** * 是否启用调试模式 */ @@ -81,7 +81,7 @@ export class WorldManager implements IService { // 默认启动运行状态 this._isRunning = true; - logger.info('WorldManager已初始化', { + logger.info("WorldManager已初始化", { maxWorlds: this._config.maxWorlds, autoCleanup: this._config.autoCleanup, cleanupInterval: this._config.cleanupInterval @@ -96,8 +96,8 @@ export class WorldManager implements IService { * 创建新World */ public createWorld(worldId: string, config?: IWorldConfig): World { - if (!worldId || typeof worldId !== 'string' || worldId.trim() === '') { - throw new Error('World ID不能为空'); + if (!worldId || typeof worldId !== "string" || worldId.trim() === "") { + throw new Error("World ID不能为空"); } if (this._worlds.has(worldId)) { @@ -110,9 +110,9 @@ export class WorldManager implements IService { const worldConfig: IWorldConfig = { name: worldId, - ...(this._config.debug !== undefined && { debug: this._config.debug }), - ...(config?.maxScenes !== undefined && { maxScenes: config.maxScenes }), - ...(config?.autoCleanup !== undefined && { autoCleanup: config.autoCleanup }) + ...(this._config.debug !== undefined && {debug: this._config.debug}), + ...(config?.maxScenes !== undefined && {maxScenes: config.maxScenes}), + ...(config?.autoCleanup !== undefined && {autoCleanup: config.autoCleanup}) }; const world = new World(worldConfig); @@ -242,12 +242,12 @@ 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'); + + logger.info("启动所有World"); } /** @@ -255,12 +255,12 @@ export class WorldManager implements IService { */ public stopAll(): void { this._isRunning = false; - + for (const worldId of this._activeWorlds) { this.setWorldActive(worldId, false); } - - logger.info('停止所有World'); + + logger.info("停止所有World"); } /** @@ -302,7 +302,7 @@ export class WorldManager implements IService { totalSystems: 0, memoryUsage: 0, isRunning: this._isRunning, - config: { ...this._config }, + config: {...this._config}, worlds: [] as any[] }; @@ -367,7 +367,7 @@ export class WorldManager implements IService { * 销毁WorldManager */ public destroy(): void { - logger.info('正在销毁WorldManager...'); + logger.info("正在销毁WorldManager..."); // 停止清理定时器 this.stopCleanupTimer(); @@ -385,7 +385,7 @@ export class WorldManager implements IService { this._activeWorlds.clear(); this._isRunning = false; - logger.info('WorldManager已销毁'); + logger.info("WorldManager已销毁"); } /** @@ -420,7 +420,7 @@ export class WorldManager implements IService { if (this._cleanupTimer) { clearInterval(this._cleanupTimer); this._cleanupTimer = null; - logger.debug('停止World清理定时器'); + logger.debug("停止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 ); @@ -483,6 +483,6 @@ export class WorldManager implements IService { * 获取配置 */ public get config(): IWorldManagerConfig { - return { ...this._config }; + 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..6fd38040 100644 --- a/packages/core/src/ECS/index.ts +++ b/packages/core/src/ECS/index.ts @@ -1,20 +1,20 @@ -export { Entity } from './Entity'; -export { Component } from './Component'; -export { ECSEventType, EventPriority, EVENT_TYPES, EventTypeValidator } from './CoreEvents'; -export * from './Systems'; -export * from './Utils'; -export * from './Decorators'; -export { Scene } from './Scene'; -export { IScene, ISceneFactory, ISceneConfig } from './IScene'; -export { SceneManager } from './SceneManager'; -export { World, IWorldConfig } from './World'; -export { WorldManager, IWorldManagerConfig } from './WorldManager'; -export * from './Core/Events'; -export * from './Core/Query'; -export * from './Core/Storage'; -export * from './Core/StorageDecorators'; -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 {Entity} from "./Entity"; +export {Component} from "./Component"; +export {ECSEventType, EventPriority, EVENT_TYPES, EventTypeValidator} from "./CoreEvents"; +export * from "./Systems"; +export * from "./Utils"; +export * from "./Decorators"; +export {Scene} from "./Scene"; +export {IScene, ISceneFactory, ISceneConfig} from "./IScene"; +export {SceneManager} from "./SceneManager"; +export {World, IWorldConfig} from "./World"; +export {WorldManager, IWorldManagerConfig} from "./WorldManager"; +export * from "./Core/Events"; +export * from "./Core/Query"; +export * from "./Core/Storage"; +export * from "./Core/StorageDecorators"; +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"; diff --git a/packages/core/src/Platform/IPlatformAdapter.ts b/packages/core/src/Platform/IPlatformAdapter.ts index 45a86b82..a0e5387d 100644 --- a/packages/core/src/Platform/IPlatformAdapter.ts +++ b/packages/core/src/Platform/IPlatformAdapter.ts @@ -64,12 +64,12 @@ export interface WorkerCreationOptions { /** * Worker类型 */ - type?: 'classic' | 'module'; + type?: "classic" | "module"; /** * 凭据模式 */ - credentials?: 'omit' | 'same-origin' | 'include'; + credentials?: "omit" | "same-origin" | "include"; /** * Worker名称(用于调试) @@ -104,7 +104,7 @@ export interface PlatformWorker { /** * Worker状态 */ - readonly state: 'running' | 'terminated'; + readonly state: "running" | "terminated"; } /** @@ -179,7 +179,7 @@ export interface PlatformDetectionResult { /** * 平台类型 */ - platform: 'browser' | 'wechat-minigame' | 'bytedance-minigame' | 'alipay-minigame' | 'baidu-minigame' | 'nodejs' | 'unknown'; + platform: "browser" | "wechat-minigame" | "bytedance-minigame" | "alipay-minigame" | "baidu-minigame" | "nodejs" | "unknown"; /** * 是否确定检测结果 diff --git a/packages/core/src/Platform/PlatformDetector.ts b/packages/core/src/Platform/PlatformDetector.ts index ddd3fc48..20588304 100644 --- a/packages/core/src/Platform/PlatformDetector.ts +++ b/packages/core/src/Platform/PlatformDetector.ts @@ -1,4 +1,4 @@ -import type { PlatformDetectionResult } from './IPlatformAdapter'; +import type {PlatformDetectionResult} from "./IPlatformAdapter"; /** * 平台检测器 @@ -10,96 +10,96 @@ export class PlatformDetector { */ public static detect(): PlatformDetectionResult { const features: string[] = []; - let platform: PlatformDetectionResult['platform'] = 'unknown'; + let platform: PlatformDetectionResult["platform"] = "unknown"; let confident = false; let adapterClass: string | undefined; // 检查全局对象和API - if (typeof globalThis !== 'undefined') { - features.push('globalThis'); + if (typeof globalThis !== "undefined") { + features.push("globalThis"); } - if (typeof window !== 'undefined') { - features.push('window'); + if (typeof window !== "undefined") { + features.push("window"); } - if (typeof self !== 'undefined') { - features.push('self'); + if (typeof self !== "undefined") { + features.push("self"); } // 检测Node.js环境(优先级最高,因为Node.js可能包含全局对象模拟) if (this.isNodeJS()) { - platform = 'nodejs'; + platform = "nodejs"; confident = true; - adapterClass = 'NodeAdapter'; - features.push('nodejs', 'process', 'require'); + adapterClass = "NodeAdapter"; + features.push("nodejs", "process", "require"); } // 检测微信小游戏环境 else if (this.isWeChatMiniGame()) { - platform = 'wechat-minigame'; + platform = "wechat-minigame"; confident = true; - adapterClass = 'WeChatMiniGameAdapter'; - features.push('wx', 'wechat-minigame'); + adapterClass = "WeChatMiniGameAdapter"; + features.push("wx", "wechat-minigame"); } // 检测字节跳动小游戏环境 else if (this.isByteDanceMiniGame()) { - platform = 'bytedance-minigame'; + platform = "bytedance-minigame"; confident = true; - adapterClass = 'ByteDanceMiniGameAdapter'; - features.push('tt', 'bytedance-minigame'); + adapterClass = "ByteDanceMiniGameAdapter"; + features.push("tt", "bytedance-minigame"); } // 检测支付宝小游戏环境 else if (this.isAlipayMiniGame()) { - platform = 'alipay-minigame'; + platform = "alipay-minigame"; confident = true; - adapterClass = 'AlipayMiniGameAdapter'; - features.push('my', 'alipay-minigame'); + adapterClass = "AlipayMiniGameAdapter"; + features.push("my", "alipay-minigame"); } // 检测百度小游戏环境 else if (this.isBaiduMiniGame()) { - platform = 'baidu-minigame'; + platform = "baidu-minigame"; confident = true; - adapterClass = 'BaiduMiniGameAdapter'; - features.push('swan', 'baidu-minigame'); + adapterClass = "BaiduMiniGameAdapter"; + features.push("swan", "baidu-minigame"); } // 检测浏览器环境 else if (this.isBrowser()) { - platform = 'browser'; + platform = "browser"; confident = true; - adapterClass = 'BrowserAdapter'; - features.push('browser'); + adapterClass = "BrowserAdapter"; + features.push("browser"); } // 添加功能检测特征 - if (typeof Worker !== 'undefined') { - features.push('Worker'); + if (typeof Worker !== "undefined") { + features.push("Worker"); } - if (typeof SharedArrayBuffer !== 'undefined') { - features.push('SharedArrayBuffer'); + if (typeof SharedArrayBuffer !== "undefined") { + features.push("SharedArrayBuffer"); } - if (typeof navigator !== 'undefined' && navigator.hardwareConcurrency) { - features.push('hardwareConcurrency'); + if (typeof navigator !== "undefined" && navigator.hardwareConcurrency) { + features.push("hardwareConcurrency"); } - if (typeof performance !== 'undefined' && typeof performance.now === 'function') { - features.push('performance.now'); + if (typeof performance !== "undefined" && typeof performance.now === "function") { + features.push("performance.now"); } - if (typeof Blob !== 'undefined') { - features.push('Blob'); + if (typeof Blob !== "undefined") { + features.push("Blob"); } - if (typeof URL !== 'undefined' && typeof URL.createObjectURL === 'function') { - features.push('URL.createObjectURL'); + if (typeof URL !== "undefined" && typeof URL.createObjectURL === "function") { + features.push("URL.createObjectURL"); } return { platform, confident, features, - ...(adapterClass && { adapterClass }) + ...(adapterClass && {adapterClass}) }; } @@ -108,7 +108,7 @@ export class PlatformDetector { */ private static isWeChatMiniGame(): boolean { // 检查wx全局对象 - if (typeof (globalThis as any).wx !== 'undefined') { + if (typeof (globalThis as any).wx !== "undefined") { const wx = (globalThis as any).wx; // 检查微信小游戏特有的API return !!(wx.getSystemInfo && wx.createCanvas && wx.createImage); @@ -121,7 +121,7 @@ export class PlatformDetector { */ private static isByteDanceMiniGame(): boolean { // 检查tt全局对象 - if (typeof (globalThis as any).tt !== 'undefined') { + if (typeof (globalThis as any).tt !== "undefined") { const tt = (globalThis as any).tt; // 检查字节跳动小游戏特有的API return !!(tt.getSystemInfo && tt.createCanvas && tt.createImage); @@ -136,15 +136,15 @@ export class PlatformDetector { try { // 检查Node.js特有的全局对象和模块 return !!( - typeof process !== 'undefined' && + typeof process !== "undefined" && process.versions && process.versions.node && - typeof require !== 'undefined' && - typeof module !== 'undefined' && - typeof exports !== 'undefined' && + typeof require !== "undefined" && + typeof module !== "undefined" && + typeof exports !== "undefined" && // 确保不是在浏览器环境中的Node.js模拟 - typeof window === 'undefined' && - typeof document === 'undefined' + typeof window === "undefined" && + typeof document === "undefined" ); } catch { return false; @@ -156,7 +156,7 @@ export class PlatformDetector { */ private static isAlipayMiniGame(): boolean { // 检查my全局对象 - if (typeof (globalThis as any).my !== 'undefined') { + if (typeof (globalThis as any).my !== "undefined") { const my = (globalThis as any).my; // 检查支付宝小游戏特有的API return !!(my.getSystemInfo && my.createCanvas); @@ -169,7 +169,7 @@ export class PlatformDetector { */ private static isBaiduMiniGame(): boolean { // 检查swan全局对象 - if (typeof (globalThis as any).swan !== 'undefined') { + if (typeof (globalThis as any).swan !== "undefined") { const swan = (globalThis as any).swan; // 检查百度小游戏特有的API return !!(swan.getSystemInfo && swan.createCanvas); @@ -182,9 +182,9 @@ export class PlatformDetector { */ private static isBrowser(): boolean { // 检查浏览器特有的对象和API - return typeof window !== 'undefined' && - typeof document !== 'undefined' && - typeof navigator !== 'undefined' && + return typeof window !== "undefined" && + typeof document !== "undefined" && + typeof navigator !== "undefined" && window.location !== undefined; } @@ -195,44 +195,44 @@ export class PlatformDetector { const info: Record = {}; // 基础检测 - info['userAgent'] = typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown'; - info['platform'] = typeof navigator !== 'undefined' ? navigator.platform : 'unknown'; + info["userAgent"] = typeof navigator !== "undefined" ? navigator.userAgent : "unknown"; + info["platform"] = typeof navigator !== "undefined" ? navigator.platform : "unknown"; // 全局对象检测 - info['globalObjects'] = { - window: typeof window !== 'undefined', - document: typeof document !== 'undefined', - navigator: typeof navigator !== 'undefined', - wx: typeof (globalThis as any).wx !== 'undefined', - tt: typeof (globalThis as any).tt !== 'undefined', - my: typeof (globalThis as any).my !== 'undefined', - swan: typeof (globalThis as any).swan !== 'undefined' + info["globalObjects"] = { + window: typeof window !== "undefined", + document: typeof document !== "undefined", + navigator: typeof navigator !== "undefined", + wx: typeof (globalThis as any).wx !== "undefined", + tt: typeof (globalThis as any).tt !== "undefined", + my: typeof (globalThis as any).my !== "undefined", + swan: typeof (globalThis as any).swan !== "undefined" }; // Worker相关检测 - info['workerSupport'] = { - Worker: typeof Worker !== 'undefined', - SharedWorker: typeof SharedWorker !== 'undefined', - ServiceWorker: typeof navigator !== 'undefined' && 'serviceWorker' in navigator, - SharedArrayBuffer: typeof SharedArrayBuffer !== 'undefined', - crossOriginIsolated: typeof self !== 'undefined' ? self.crossOriginIsolated : false + info["workerSupport"] = { + Worker: typeof Worker !== "undefined", + SharedWorker: typeof SharedWorker !== "undefined", + ServiceWorker: typeof navigator !== "undefined" && "serviceWorker" in navigator, + SharedArrayBuffer: typeof SharedArrayBuffer !== "undefined", + crossOriginIsolated: typeof self !== "undefined" ? self.crossOriginIsolated : false }; // 性能相关检测 - info['performance'] = { - performanceNow: typeof performance !== 'undefined' && typeof performance.now === 'function', - hardwareConcurrency: typeof navigator !== 'undefined' ? navigator.hardwareConcurrency : undefined + info["performance"] = { + performanceNow: typeof performance !== "undefined" && typeof performance.now === "function", + hardwareConcurrency: typeof navigator !== "undefined" ? navigator.hardwareConcurrency : undefined }; // 其他API检测 - info['apiSupport'] = { - Blob: typeof Blob !== 'undefined', - URL: typeof URL !== 'undefined', - createObjectURL: typeof URL !== 'undefined' && typeof URL.createObjectURL === 'function', - ArrayBuffer: typeof ArrayBuffer !== 'undefined', - TypedArrays: typeof Float32Array !== 'undefined' + info["apiSupport"] = { + Blob: typeof Blob !== "undefined", + URL: typeof URL !== "undefined", + createObjectURL: typeof URL !== "undefined" && typeof URL.createObjectURL === "function", + ArrayBuffer: typeof ArrayBuffer !== "undefined", + TypedArrays: typeof Float32Array !== "undefined" }; 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..86e168ad 100644 --- a/packages/core/src/Platform/PlatformManager.ts +++ b/packages/core/src/Platform/PlatformManager.ts @@ -1,5 +1,5 @@ -import type { IPlatformAdapter } from './IPlatformAdapter'; -import { createLogger, type ILogger } from '../Utils/Logger'; +import type {IPlatformAdapter} from "./IPlatformAdapter"; +import {createLogger, type ILogger} from "../Utils/Logger"; /** * 平台管理器 @@ -11,7 +11,7 @@ export class PlatformManager { private readonly logger: ILogger; private constructor() { - this.logger = createLogger('PlatformManager'); + this.logger = createLogger("PlatformManager"); } /** @@ -29,7 +29,7 @@ export class PlatformManager { */ public getAdapter(): IPlatformAdapter { if (!this.adapter) { - throw new Error('平台适配器未注册,请调用 registerAdapter() 注册适配器'); + throw new Error("平台适配器未注册,请调用 registerAdapter() 注册适配器"); } return this.adapter; } @@ -70,19 +70,19 @@ export class PlatformManager { /** * 检查当前平台是否支持特定功能 */ - public supportsFeature(feature: 'worker' | 'shared-array-buffer' | 'transferable-objects' | 'module-worker'): boolean { + public supportsFeature(feature: "worker" | "shared-array-buffer" | "transferable-objects" | "module-worker"): boolean { if (!this.adapter) return false; const config = this.adapter.getPlatformConfig(); switch (feature) { - case 'worker': + case "worker": return this.adapter.isWorkerSupported(); - case 'shared-array-buffer': + case "shared-array-buffer": return this.adapter.isSharedArrayBufferSupported(); - case 'transferable-objects': + case "transferable-objects": return config.supportsTransferableObjects; - case 'module-worker': + case "module-worker": return config.supportsModuleWorker; default: return false; @@ -98,7 +98,7 @@ export class PlatformManager { platformSupportsSharedArrayBuffer: boolean; platformMaxWorkerCount: number; platformLimitations: any; - } { + } { if (!this.adapter) { return { platformSupportsWorker: false, @@ -123,15 +123,15 @@ export class PlatformManager { */ public async getFullPlatformConfig(): Promise { if (!this.adapter) { - throw new Error('平台适配器未注册'); + throw new Error("平台适配器未注册"); } // 如果适配器支持异步获取配置,使用异步方法 - if (typeof this.adapter.getPlatformConfigAsync === 'function') { + if (typeof this.adapter.getPlatformConfigAsync === "function") { return await this.adapter.getPlatformConfigAsync(); } // 否则返回同步配置 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..28db5c4a 100644 --- a/packages/core/src/Platform/index.ts +++ b/packages/core/src/Platform/index.ts @@ -9,17 +9,17 @@ export type { WorkerCreationOptions, PlatformConfig, PlatformDetectionResult -} from './IPlatformAdapter'; +} from "./IPlatformAdapter"; // 平台检测器 -export { PlatformDetector } from './PlatformDetector'; +export {PlatformDetector} from "./PlatformDetector"; // 平台管理器 -export { PlatformManager } from './PlatformManager'; +export {PlatformManager} from "./PlatformManager"; // 内部导入用于便利函数 -import { PlatformManager } from './PlatformManager'; -import type { IPlatformAdapter } from './IPlatformAdapter'; +import {PlatformManager} from "./PlatformManager"; +import type {IPlatformAdapter} from "./IPlatformAdapter"; // 便利函数 export function registerPlatformAdapter(adapter: IPlatformAdapter) { @@ -38,10 +38,10 @@ export function getFullPlatformConfig() { return PlatformManager.getInstance().getFullPlatformConfig(); } -export function supportsFeature(feature: 'worker' | 'shared-array-buffer' | 'transferable-objects' | 'module-worker') { +export function supportsFeature(feature: "worker" | "shared-array-buffer" | "transferable-objects" | "module-worker") { return PlatformManager.getInstance().supportsFeature(feature); } 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..4a40d12e 100644 --- a/packages/core/src/Plugins/DebugPlugin.ts +++ b/packages/core/src/Plugins/DebugPlugin.ts @@ -1,15 +1,15 @@ -import type { Core } from '../Core'; -import type { ServiceContainer } from '../Core/ServiceContainer'; -import { IPlugin } from '../Core/Plugin'; -import { createLogger } from '../Utils/Logger'; -import type { IScene } from '../ECS/IScene'; -import type { Entity } from '../ECS/Entity'; -import type { EntitySystem } from '../ECS/Systems/EntitySystem'; -import { WorldManager } from '../ECS/WorldManager'; -import { Injectable } from '../Core/DI/Decorators'; -import type { IService } from '../Core/ServiceContainer'; +import type {Core} from "../Core"; +import type {ServiceContainer} from "../Core/ServiceContainer"; +import {IPlugin} from "../Core/Plugin"; +import {createLogger} from "../Utils/Logger"; +import type {IScene} from "../ECS/IScene"; +import type {Entity} from "../ECS/Entity"; +import type {EntitySystem} from "../ECS/Systems/EntitySystem"; +import {WorldManager} from "../ECS/WorldManager"; +import {Injectable} from "../Core/DI/Decorators"; +import type {IService} from "../Core/ServiceContainer"; -const logger = createLogger('DebugPlugin'); +const logger = createLogger("DebugPlugin"); /** * ECS 调试插件统计信息 @@ -91,8 +91,8 @@ export interface ComponentDebugInfo { */ @Injectable() export class DebugPlugin implements IPlugin, IService { - readonly name = '@esengine/debug-plugin'; - readonly version = '1.0.0'; + readonly name = "@esengine/debug-plugin"; + readonly version = "1.0.0"; private worldManager: WorldManager | null = null; private updateInterval: number; @@ -115,7 +115,7 @@ export class DebugPlugin implements IPlugin, IService { async install(_core: Core, services: ServiceContainer): Promise { this.worldManager = services.resolve(WorldManager); - logger.info('ECS Debug Plugin installed'); + logger.info("ECS Debug Plugin installed"); if (this.autoStart) { this.start(); @@ -129,7 +129,7 @@ export class DebugPlugin implements IPlugin, IService { this.stop(); this.worldManager = null; - logger.info('ECS Debug Plugin uninstalled'); + logger.info("ECS Debug Plugin uninstalled"); } /** @@ -145,11 +145,11 @@ export class DebugPlugin implements IPlugin, IService { */ public start(): void { if (this.updateTimer) { - logger.warn('Debug monitoring already started'); + logger.warn("Debug monitoring already started"); return; } - logger.info('Starting debug monitoring'); + logger.info("Starting debug monitoring"); this.updateTimer = setInterval(() => { this.logStats(); @@ -163,7 +163,7 @@ export class DebugPlugin implements IPlugin, IService { if (this.updateTimer) { clearInterval(this.updateTimer); this.updateTimer = null; - logger.info('Debug monitoring stopped'); + logger.info("Debug monitoring stopped"); } } @@ -172,7 +172,7 @@ export class DebugPlugin implements IPlugin, IService { */ public getStats(): ECSDebugStats { if (!this.worldManager) { - throw new Error('Plugin not installed'); + throw new Error("Plugin not installed"); } const scenes: SceneDebugInfo[] = []; @@ -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)) }; } @@ -230,7 +230,7 @@ export class DebugPlugin implements IPlugin, IService { enabled: system.enabled, updateOrder: system.updateOrder, entityCount: system.entities.length, - ...(performance !== undefined && { performance }) + ...(performance !== undefined && {performance}) }; } @@ -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)) }; } @@ -258,15 +258,15 @@ export class DebugPlugin implements IPlugin, IService { const data: any = {}; for (const key of Object.keys(component)) { - if (!key.startsWith('_')) { + if (!key.startsWith("_")) { const value = component[key]; - if (typeof value !== 'function') { + if (typeof value !== "function") { data[key] = value; } } } - return { type, data }; + return {type, data}; } /** @@ -281,7 +281,7 @@ export class DebugPlugin implements IPlugin, IService { hasComponent?: string; }): EntityDebugInfo[] { if (!this.worldManager) { - throw new Error('Plugin not installed'); + throw new Error("Plugin not installed"); } const results: EntityDebugInfo[] = []; @@ -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; @@ -325,7 +325,7 @@ export class DebugPlugin implements IPlugin, IService { private logStats(): void { const stats = this.getStats(); - logger.info('=== ECS Debug Stats ==='); + logger.info("=== ECS Debug Stats ==="); logger.info(`Total Entities: ${stats.totalEntities}`); logger.info(`Total Systems: ${stats.totalSystems}`); logger.info(`Scenes: ${stats.scenes.length}`); @@ -338,14 +338,14 @@ export class DebugPlugin implements IPlugin, IService { for (const system of scene.systems) { const perfStr = system.performance ? ` | Avg: ${system.performance.avgExecutionTime.toFixed(2)}ms, Max: ${system.performance.maxExecutionTime.toFixed(2)}ms` - : ''; + : ""; logger.info( - ` - ${system.name} (${system.enabled ? 'enabled' : 'disabled'}) | Entities: ${system.entityCount}${perfStr}` + ` - ${system.name} (${system.enabled ? "enabled" : "disabled"}) | Entities: ${system.entityCount}${perfStr}` ); } } - logger.info('========================\n'); + logger.info("========================\n"); } /** diff --git a/packages/core/src/Plugins/index.ts b/packages/core/src/Plugins/index.ts index 90bac8a8..0ff9e25c 100644 --- a/packages/core/src/Plugins/index.ts +++ b/packages/core/src/Plugins/index.ts @@ -1 +1 @@ -export * from './DebugPlugin'; +export * from "./DebugPlugin"; diff --git a/packages/core/src/Types/IUpdatable.ts b/packages/core/src/Types/IUpdatable.ts index e5c50a2b..1d99cd12 100644 --- a/packages/core/src/Types/IUpdatable.ts +++ b/packages/core/src/Types/IUpdatable.ts @@ -16,5 +16,5 @@ export interface IUpdatable { * 检查对象是否实现了IUpdatable接口 */ export function isUpdatable(obj: any): obj is IUpdatable { - return obj && typeof obj.update === 'function'; + return obj && typeof obj.update === "function"; } diff --git a/packages/core/src/Types/TypeHelpers.ts b/packages/core/src/Types/TypeHelpers.ts index b86577d5..1884827e 100644 --- a/packages/core/src/Types/TypeHelpers.ts +++ b/packages/core/src/Types/TypeHelpers.ts @@ -4,8 +4,8 @@ * 提供高级类型推断和类型安全的工具类型 */ -import type { IComponent } from './index'; -import { Component } from '../ECS/Component'; +import type {IComponent} from "./index"; +import {Component} from "../ECS/Component"; /** * 组件类型提取器 @@ -240,7 +240,7 @@ export interface TypedQueryCondition< export function isComponentType( value: any ): value is ComponentConstructor { - return typeof value === 'function' && value.prototype instanceof Component; + return typeof value === "function" && value.prototype instanceof Component; } /** diff --git a/packages/core/src/Types/index.ts b/packages/core/src/Types/index.ts index 28ab3a11..63e7f594 100644 --- a/packages/core/src/Types/index.ts +++ b/packages/core/src/Types/index.ts @@ -2,11 +2,11 @@ * 框架核心类型定义 */ -import type { IWorldManagerConfig } from '../ECS'; +import type {IWorldManagerConfig} from "../ECS"; // 导出TypeScript类型增强工具 -export * from './TypeHelpers'; -export * from './IUpdatable'; +export * from "./TypeHelpers"; +export * from "./IUpdatable"; /** * 组件接口 @@ -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/BinarySerializer.ts b/packages/core/src/Utils/BinarySerializer.ts index 63884004..eaca519b 100644 --- a/packages/core/src/Utils/BinarySerializer.ts +++ b/packages/core/src/Utils/BinarySerializer.ts @@ -1,4 +1,4 @@ -import { strToU8, strFromU8, zlibSync, unzlibSync } from 'fflate'; +import {strToU8, strFromU8, zlibSync, unzlibSync} from "fflate"; /** * 二进制序列化器 diff --git a/packages/core/src/Utils/Debug/ComponentDataCollector.ts b/packages/core/src/Utils/Debug/ComponentDataCollector.ts index 4e7072cd..b4bf7ec2 100644 --- a/packages/core/src/Utils/Debug/ComponentDataCollector.ts +++ b/packages/core/src/Utils/Debug/ComponentDataCollector.ts @@ -1,7 +1,7 @@ -import { IComponentDebugData } from '../../Types'; -import { ComponentPoolManager } from '../../ECS/Core/ComponentPool'; -import { getComponentInstanceTypeName } from '../../ECS/Decorators'; -import { IScene } from '../../ECS/IScene'; +import {IComponentDebugData} from "../../Types"; +import {ComponentPoolManager} from "../../ECS/Core/ComponentPool"; +import {getComponentInstanceTypeName} from "../../ECS/Decorators"; +import {IScene} from "../../ECS/IScene"; /** * 组件数据收集器 @@ -38,7 +38,7 @@ export class ComponentDataCollector { if (entity.components) { entity.components.forEach((component: any) => { const typeName = getComponentInstanceTypeName(component); - const stats = componentStats.get(typeName) || { count: 0, entities: 0 }; + const stats = componentStats.get(typeName) || {count: 0, entities: 0}; stats.count++; totalInstances++; componentStats.set(typeName, stats); @@ -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,51 +116,51 @@ 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; - + 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) { + 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++) { const key = keys[i]; - if (!key || key === 'entity' || key === '_entity' || key === 'constructor') continue; + if (!key || key === "entity" || key === "_entity" || key === "constructor") continue; const value = item[key]; itemSize += key.length * 2; - - if (typeof value === 'string') { + + if (typeof value === "string") { itemSize += Math.min(value.length * 2, 200); - } else if (typeof value === 'number') { + } else if (typeof value === "number") { itemSize += 8; - } else if (typeof value === 'boolean') { + } else if (typeof value === "boolean") { itemSize += 4; - } else if (typeof value === 'object' && value !== null) { + } else if (typeof value === "object" && value !== null) { itemSize += calculate(value, depth + 1); } } } 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,23 +201,23 @@ 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': + case "boolean": size = 4; break; - case 'number': + case "number": size = 8; break; - case 'string': + case "string": size = 24 + Math.min(obj.length * 2, 1000); break; - case 'object': + case "object": visited.add(obj); - + if (Array.isArray(obj)) { size = 40 + (obj.length * 8); const maxElements = Math.min(obj.length, 50); @@ -226,21 +226,21 @@ 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; - if (key === 'constructor' || - key === '__proto__' || - key === 'entity' || - key === '_entity' || - key.startsWith('_cc_') || - key.startsWith('__')) { + if (key === "constructor" || + key === "__proto__" || + key === "entity" || + key === "_entity" || + key.startsWith("_cc_") || + key.startsWith("__")) { 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/DebugConfigService.ts b/packages/core/src/Utils/Debug/DebugConfigService.ts index a15d8d6f..0f5b8801 100644 --- a/packages/core/src/Utils/Debug/DebugConfigService.ts +++ b/packages/core/src/Utils/Debug/DebugConfigService.ts @@ -1,6 +1,6 @@ -import { IECSDebugConfig } from '../../Types'; -import { Injectable } from '../../Core/DI/Decorators'; -import type { IService } from '../../Core/ServiceContainer'; +import {IECSDebugConfig} from "../../Types"; +import {Injectable} from "../../Core/DI/Decorators"; +import type {IService} from "../../Core/ServiceContainer"; /** * 调试配置服务 @@ -14,7 +14,7 @@ export class DebugConfigService implements IService { constructor() { this._config = { enabled: false, - websocketUrl: '', + websocketUrl: "", debugFrameRate: 30, autoReconnect: true, channels: { diff --git a/packages/core/src/Utils/Debug/DebugManager.ts b/packages/core/src/Utils/Debug/DebugManager.ts index a752657b..19fdf72e 100644 --- a/packages/core/src/Utils/Debug/DebugManager.ts +++ b/packages/core/src/Utils/Debug/DebugManager.ts @@ -1,20 +1,20 @@ -import { IECSDebugConfig, IECSDebugData } from '../../Types'; -import { EntityDataCollector } from './EntityDataCollector'; -import { SystemDataCollector } from './SystemDataCollector'; -import { PerformanceDataCollector } from './PerformanceDataCollector'; -import { ComponentDataCollector } from './ComponentDataCollector'; -import { SceneDataCollector } from './SceneDataCollector'; -import { WebSocketManager } from './WebSocketManager'; -import { Component } from '../../ECS/Component'; -import { ComponentPoolManager } from '../../ECS/Core/ComponentPool'; -import { Pool } from '../../Utils/Pool'; -import { getComponentInstanceTypeName, getSystemInstanceTypeName } from '../../ECS/Decorators'; -import type { IService } from '../../Core/ServiceContainer'; -import type { IUpdatable } from '../../Types/IUpdatable'; -import { SceneManager } from '../../ECS/SceneManager'; -import { PerformanceMonitor } from '../PerformanceMonitor'; -import { Injectable, Inject, Updatable } from '../../Core/DI/Decorators'; -import { DebugConfigService } from './DebugConfigService'; +import {IECSDebugConfig, IECSDebugData} from "../../Types"; +import {EntityDataCollector} from "./EntityDataCollector"; +import {SystemDataCollector} from "./SystemDataCollector"; +import {PerformanceDataCollector} from "./PerformanceDataCollector"; +import {ComponentDataCollector} from "./ComponentDataCollector"; +import {SceneDataCollector} from "./SceneDataCollector"; +import {WebSocketManager} from "./WebSocketManager"; +import {Component} from "../../ECS/Component"; +import {ComponentPoolManager} from "../../ECS/Core/ComponentPool"; +import {Pool} from "../../Utils/Pool"; +import {getComponentInstanceTypeName, getSystemInstanceTypeName} from "../../ECS/Decorators"; +import type {IService} from "../../Core/ServiceContainer"; +import type {IUpdatable} from "../../Types/IUpdatable"; +import {SceneManager} from "../../ECS/SceneManager"; +import {PerformanceMonitor} from "../PerformanceMonitor"; +import {Injectable, Inject, Updatable} from "../../Core/DI/Decorators"; +import {DebugConfigService} from "./DebugConfigService"; /** * 调试管理器 @@ -106,27 +106,27 @@ export class DebugManager implements IService, IUpdatable { */ private interceptConsole(): void { console.log = (...args: unknown[]) => { - this.sendLog('info', this.formatLogMessage(args)); + this.sendLog("info", this.formatLogMessage(args)); this.originalConsole.log(...args); }; console.debug = (...args: unknown[]) => { - this.sendLog('debug', this.formatLogMessage(args)); + this.sendLog("debug", this.formatLogMessage(args)); this.originalConsole.debug(...args); }; console.info = (...args: unknown[]) => { - this.sendLog('info', this.formatLogMessage(args)); + this.sendLog("info", this.formatLogMessage(args)); this.originalConsole.info(...args); }; console.warn = (...args: unknown[]) => { - this.sendLog('warn', this.formatLogMessage(args)); + this.sendLog("warn", this.formatLogMessage(args)); this.originalConsole.warn(...args); }; console.error = (...args: unknown[]) => { - this.sendLog('error', this.formatLogMessage(args)); + this.sendLog("error", this.formatLogMessage(args)); this.originalConsole.error(...args); }; } @@ -135,12 +135,12 @@ export class DebugManager implements IService, IUpdatable { * 格式化日志消息 */ private formatLogMessage(args: unknown[]): string { - return args.map(arg => { - if (typeof arg === 'string') return 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'; - if (arg === undefined) return 'undefined'; - if (typeof arg === 'object') { + if (arg === null) return "null"; + if (arg === undefined) return "undefined"; + if (typeof arg === "object") { try { return this.safeStringify(arg, 6); } catch { @@ -148,7 +148,7 @@ export class DebugManager implements IService, IUpdatable { } } return String(arg); - }).join(' '); + }).join(" "); } /** @@ -160,20 +160,20 @@ export class DebugManager implements IService, IUpdatable { const stringify = (value: any, depth: number): any => { if (value === null) return null; if (value === undefined) return undefined; - if (typeof value !== 'object') return value; + if (typeof value !== "object") return value; if (depth >= maxDepth) { - return '[Max Depth Reached]'; + return "[Max Depth Reached]"; } if (seen.has(value)) { - return '[Circular]'; + return "[Circular]"; } 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; } @@ -201,7 +201,7 @@ export class DebugManager implements IService, IUpdatable { try { this.webSocketManager.send({ - type: 'log', + type: "log", data: { level, message, @@ -263,35 +263,35 @@ export class DebugManager implements IService, IUpdatable { private handleMessage(message: any): void { try { switch (message.type) { - case 'capture_memory_snapshot': + case "capture_memory_snapshot": this.handleMemorySnapshotRequest(); break; - case 'config_update': + case "config_update": if (message.config) { - this.updateConfig({ ...this.config, ...message.config }); + this.updateConfig({...this.config, ...message.config}); } break; - case 'expand_lazy_object': + case "expand_lazy_object": this.handleExpandLazyObjectRequest(message); break; - case 'get_component_properties': + case "get_component_properties": this.handleGetComponentPropertiesRequest(message); break; - case 'get_raw_entity_list': + case "get_raw_entity_list": this.handleGetRawEntityListRequest(message); break; - case 'get_entity_details': + case "get_entity_details": this.handleGetEntityDetailsRequest(message); break; - case 'ping': + case "ping": this.webSocketManager.send({ - type: 'pong', + type: "pong", timestamp: Date.now() }); break; @@ -304,7 +304,7 @@ export class DebugManager implements IService, IUpdatable { // console.error('[ECS Debug] 处理消息失败:', error); if (message.requestId) { this.webSocketManager.send({ - type: 'error_response', + type: "error_response", requestId: message.requestId, error: error instanceof Error ? error.message : String(error) }); @@ -317,13 +317,13 @@ export class DebugManager implements IService, IUpdatable { */ private handleExpandLazyObjectRequest(message: any): void { try { - const { entityId, componentIndex, propertyPath, requestId } = message; + const {entityId, componentIndex, propertyPath, requestId} = message; if (entityId === undefined || componentIndex === undefined || !propertyPath) { this.webSocketManager.send({ - type: 'expand_lazy_object_response', + type: "expand_lazy_object_response", requestId, - error: '缺少必要参数' + error: "缺少必要参数" }); return; } @@ -332,13 +332,13 @@ export class DebugManager implements IService, IUpdatable { const expandedData = this.entityCollector.expandLazyObject(entityId, componentIndex, propertyPath, scene); this.webSocketManager.send({ - type: 'expand_lazy_object_response', + type: "expand_lazy_object_response", requestId, data: expandedData }); } catch (error) { this.webSocketManager.send({ - type: 'expand_lazy_object_response', + type: "expand_lazy_object_response", requestId: message.requestId, error: error instanceof Error ? error.message : String(error) }); @@ -350,13 +350,13 @@ export class DebugManager implements IService, IUpdatable { */ private handleGetComponentPropertiesRequest(message: any): void { try { - const { entityId, componentIndex, requestId } = message; + const {entityId, componentIndex, requestId} = message; if (entityId === undefined || componentIndex === undefined) { this.webSocketManager.send({ - type: 'get_component_properties_response', + type: "get_component_properties_response", requestId, - error: '缺少必要参数' + error: "缺少必要参数" }); return; } @@ -365,13 +365,13 @@ export class DebugManager implements IService, IUpdatable { const properties = this.entityCollector.getComponentProperties(entityId, componentIndex, scene); this.webSocketManager.send({ - type: 'get_component_properties_response', + type: "get_component_properties_response", requestId, data: properties }); } catch (error) { this.webSocketManager.send({ - type: 'get_component_properties_response', + type: "get_component_properties_response", requestId: message.requestId, error: error instanceof Error ? error.message : String(error) }); @@ -383,19 +383,19 @@ export class DebugManager implements IService, IUpdatable { */ private handleGetRawEntityListRequest(message: any): void { try { - const { requestId } = message; + const {requestId} = message; const scene = this.sceneManager.currentScene; const rawEntityList = this.entityCollector.getRawEntityList(scene); this.webSocketManager.send({ - type: 'get_raw_entity_list_response', + type: "get_raw_entity_list_response", requestId, data: rawEntityList }); } catch (error) { this.webSocketManager.send({ - type: 'get_raw_entity_list_response', + type: "get_raw_entity_list_response", requestId: message.requestId, error: error instanceof Error ? error.message : String(error) }); @@ -407,13 +407,13 @@ export class DebugManager implements IService, IUpdatable { */ private handleGetEntityDetailsRequest(message: any): void { try { - const { entityId, requestId } = message; + const {entityId, requestId} = message; if (entityId === undefined) { this.webSocketManager.send({ - type: 'get_entity_details_response', + type: "get_entity_details_response", requestId, - error: '缺少实体ID参数' + error: "缺少实体ID参数" }); return; } @@ -422,13 +422,13 @@ export class DebugManager implements IService, IUpdatable { const entityDetails = this.entityCollector.getEntityDetails(entityId, scene); this.webSocketManager.send({ - type: 'get_entity_details_response', + type: "get_entity_details_response", requestId, data: entityDetails }); } catch (error) { this.webSocketManager.send({ - type: 'get_entity_details_response', + type: "get_entity_details_response", requestId: message.requestId, error: error instanceof Error ? error.message : String(error) }); @@ -436,9 +436,6 @@ export class DebugManager implements IService, IUpdatable { } - - - /** * 处理内存快照请求 */ @@ -446,13 +443,13 @@ export class DebugManager implements IService, IUpdatable { try { const memorySnapshot = this.captureMemorySnapshot(); this.webSocketManager.send({ - type: 'memory_snapshot_response', + type: "memory_snapshot_response", data: memorySnapshot }); } catch (error) { this.webSocketManager.send({ - type: 'memory_snapshot_error', - error: error instanceof Error ? error.message : '内存快照捕获失败' + type: "memory_snapshot_error", + error: error instanceof Error ? error.message : "内存快照捕获失败" }); } } @@ -469,7 +466,7 @@ export class DebugManager implements IService, IUpdatable { // 使用专门的内存计算方法收集实体数据 const entityData = this.entityCollector.collectEntityDataWithMemory(scene); - const componentMemoryStats = scene?.entities ? this.collectComponentMemoryStats(scene.entities) : { totalMemory: 0, componentTypes: 0, totalInstances: 0, breakdown: [] }; + const componentMemoryStats = scene?.entities ? this.collectComponentMemoryStats(scene.entities) : {totalMemory: 0, componentTypes: 0, totalInstances: 0, breakdown: []}; const systemMemoryStats = this.collectSystemMemoryStats(); const poolMemoryStats = this.collectPoolMemoryStats(); const performanceStats = this.collectPerformanceStats(); @@ -479,7 +476,7 @@ export class DebugManager implements IService, IUpdatable { return { timestamp, - version: '2.0', + version: "2.0", summary: { totalEntities: entityData.totalEntities, totalMemoryUsage: baseMemoryInfo.usedMemory, @@ -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<{ @@ -720,7 +716,7 @@ export class DebugManager implements IService, IUpdatable { } private calculateQuickSystemSize(system: unknown): number { - if (!system || typeof system !== 'object') return 64; + if (!system || typeof system !== "object") return 64; let size = 128; @@ -728,20 +724,20 @@ export class DebugManager implements IService, IUpdatable { const keys = Object.keys(system); for (let i = 0; i < Math.min(keys.length, 15); i++) { const key = keys[i]; - if (!key || key === 'entities' || key === 'scene' || key === 'constructor') continue; + if (!key || key === "entities" || key === "scene" || key === "constructor") continue; const value = (system as Record)[key]; size += key.length * 2; - if (typeof value === 'string') { + if (typeof value === "string") { size += Math.min(value.length * 2, 100); - } else if (typeof value === 'number') { + } else if (typeof value === "number") { size += 8; - } else if (typeof value === 'boolean') { + } else if (typeof value === "boolean") { size += 4; } else if (Array.isArray(value)) { size += 40 + Math.min(value.length * 8, 200); - } else if (typeof value === 'object' && value !== null) { + } else if (typeof value === "object" && value !== null) { size += 64; } } @@ -766,7 +762,7 @@ export class DebugManager implements IService, IUpdatable { utilization: number; hitRate?: number; }>; - } { + } { let totalPoolMemory = 0; const poolBreakdown: Array<{ typeName: string; @@ -845,10 +841,10 @@ export class DebugManager implements IService, IUpdatable { samples: number; }>; error?: string; - } { + } { try { if (!this.performanceMonitor) { - return { enabled: false }; + return {enabled: false}; } const stats = this.performanceMonitor.getAllSystemStats(); @@ -869,7 +865,7 @@ export class DebugManager implements IService, IUpdatable { }).sort((a, b) => b.averageTime - a.averageTime).slice(0, 5) }; } catch (error: unknown) { - return { enabled: false, error: error instanceof Error ? error.message : String(error) }; + return {enabled: false, error: error instanceof Error ? error.message : String(error)}; } } @@ -883,10 +879,10 @@ export class DebugManager implements IService, IUpdatable { const debugData: IECSDebugData = { timestamp: currentTime, - frameworkVersion: '1.0.0', // 可以从package.json读取 + frameworkVersion: "1.0.0", // 可以从package.json读取 isRunning: this.isRunning, frameworkLoaded: true, - currentScene: scene?.name || 'Unknown' + currentScene: scene?.name || "Unknown" }; // 根据配置收集各种数据 @@ -937,7 +933,7 @@ export class DebugManager implements IService, IUpdatable { const debugData = this.getDebugData(); // 包装成调试面板期望的消息格式 const message = { - type: 'debug_data', + type: "debug_data", data: debugData }; this.webSocketManager.send(message); @@ -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 99aab88f..4a38be53 100644 --- a/packages/core/src/Utils/Debug/EntityDataCollector.ts +++ b/packages/core/src/Utils/Debug/EntityDataCollector.ts @@ -1,8 +1,8 @@ -import { IEntityDebugData } from '../../Types'; -import { Entity } from '../../ECS/Entity'; -import { Component } from '../../ECS/Component'; -import { getComponentInstanceTypeName } from '../../ECS/Decorators'; -import { IScene } from '../../ECS/IScene'; +import {IEntityDebugData} from "../../Types"; +import {Entity} from "../../ECS/Entity"; +import {Component} from "../../ECS/Component"; +import {getComponentInstanceTypeName} from "../../ECS/Decorators"; +import {IScene} from "../../ECS/IScene"; /** * 实体数据收集器 @@ -39,7 +39,7 @@ export class EntityDataCollector { } const archetypeData = this.collectArchetypeData(scene); - + return { totalEntities: stats.totalEntities, activeEntities: stats.activeEntities, @@ -129,7 +129,7 @@ export class EntityDataCollector { } catch (error) { return { error: `获取实体详情失败: ${error instanceof Error ? error.message : String(error)}`, - scene: '获取失败', + scene: "获取失败", components: [], componentCount: 0, componentTypes: [] @@ -138,29 +138,29 @@ export class EntityDataCollector { } private getSceneInfo(scene: any): { name: string; type: string } { - let sceneName = '当前场景'; - let sceneType = 'Scene'; - + let sceneName = "当前场景"; + let sceneType = "Scene"; + try { - if (scene.name && typeof scene.name === 'string' && scene.name.trim()) { + if (scene.name && typeof scene.name === "string" && scene.name.trim()) { sceneName = scene.name.trim(); } else if (scene.constructor && scene.constructor.name) { sceneName = scene.constructor.name; sceneType = scene.constructor.name; - } else if (scene._name && typeof scene._name === 'string' && scene._name.trim()) { + } else if (scene._name && typeof scene._name === "string" && scene._name.trim()) { sceneName = scene._name.trim(); } else { const sceneClassName = Object.getPrototypeOf(scene)?.constructor?.name; - if (sceneClassName && sceneClassName !== 'Object') { + if (sceneClassName && sceneClassName !== "Object") { sceneName = sceneClassName; sceneType = sceneClassName; } } } catch (error) { - sceneName = '场景名获取失败'; + sceneName = "场景名获取失败"; } - - return { name: sceneName, type: sceneType }; + + return {name: sceneName, type: sceneType}; } @@ -182,20 +182,20 @@ export class EntityDataCollector { try { stats = entityList.getStats ? entityList.getStats() : this.calculateFallbackEntityStats(entityList); } catch (error) { - return { - totalEntities: 0, - activeEntities: 0, - pendingAdd: 0, - pendingRemove: 0, - entitiesPerArchetype: [], - topEntitiesByComponents: [], - entityHierarchy: [], - entityDetailsMap: {} - }; - } + return { + totalEntities: 0, + activeEntities: 0, + pendingAdd: 0, + pendingRemove: 0, + entitiesPerArchetype: [], + topEntitiesByComponents: [], + entityHierarchy: [], + entityDetailsMap: {} + }; + } const archetypeData = this.collectArchetypeDataWithMemory(scene); - + return { totalEntities: stats.totalEntities, activeEntities: stats.activeEntities, @@ -213,11 +213,11 @@ export class EntityDataCollector { distribution: Array<{ signature: string; count: number; memory: number }>; topEntities: Array<{ id: string; name: string; componentCount: number; memory: number }>; } { - if (scene && scene.archetypeSystem && typeof scene.archetypeSystem.getAllArchetypes === 'function') { + if (scene && scene.archetypeSystem && typeof scene.archetypeSystem.getAllArchetypes === "function") { return this.extractArchetypeStatistics(scene.archetypeSystem); } - const entityContainer = { entities: scene.entities?.buffer || [] }; + const entityContainer = {entities: scene.entities?.buffer || []}; return { distribution: this.getArchetypeDistributionFast(entityContainer), topEntities: this.getTopEntitiesByComponentsFast(entityContainer) @@ -230,13 +230,13 @@ export class EntityDataCollector { if (entityContainer && entityContainer.entities) { entityContainer.entities.forEach((entity: any) => { const componentTypes = entity.components?.map((comp: any) => getComponentInstanceTypeName(comp)) || []; - const signature = componentTypes.length > 0 ? componentTypes.sort().join(', ') : '无组件'; + const signature = componentTypes.length > 0 ? componentTypes.sort().join(", ") : "无组件"; const existing = distribution.get(signature); if (existing) { existing.count++; } else { - distribution.set(signature, { count: 1, componentTypes }); + distribution.set(signature, {count: 1, componentTypes}); } }); } @@ -271,11 +271,11 @@ export class EntityDataCollector { distribution: Array<{ signature: string; count: number; memory: number }>; topEntities: Array<{ id: string; name: string; componentCount: number; memory: number }>; } { - if (scene && scene.archetypeSystem && typeof scene.archetypeSystem.getAllArchetypes === 'function') { + if (scene && scene.archetypeSystem && typeof scene.archetypeSystem.getAllArchetypes === "function") { return this.extractArchetypeStatisticsWithMemory(scene.archetypeSystem); } - const entityContainer = { entities: scene.entities?.buffer || [] }; + const entityContainer = {entities: scene.entities?.buffer || []}; return { distribution: this.getArchetypeDistributionWithMemory(entityContainer), topEntities: this.getTopEntitiesByComponentsWithMemory(entityContainer) @@ -292,9 +292,9 @@ export class EntityDataCollector { const topEntities: Array<{ id: string; name: string; componentCount: number; memory: number }> = []; archetypes.forEach((archetype: any) => { - const signature = archetype.componentTypes?.map((type: any) => type.name).join(',') || 'Unknown'; + const signature = archetype.componentTypes?.map((type: any) => type.name).join(",") || "Unknown"; const entityCount = archetype.entities?.length || 0; - + distribution.push({ signature, count: entityCount, @@ -316,7 +316,7 @@ export class EntityDataCollector { distribution.sort((a, b) => b.count - a.count); topEntities.sort((a, b) => b.componentCount - a.componentCount); - return { distribution, topEntities }; + return {distribution, topEntities}; } @@ -329,18 +329,18 @@ export class EntityDataCollector { const topEntities: Array<{ id: string; name: string; componentCount: number; memory: number }> = []; archetypes.forEach((archetype: any) => { - const signature = archetype.componentTypes?.map((type: any) => type.name).join(',') || 'Unknown'; + const signature = archetype.componentTypes?.map((type: any) => type.name).join(",") || "Unknown"; const entityCount = archetype.entities?.length || 0; let actualMemory = 0; if (archetype.entities && archetype.entities.length > 0) { const sampleSize = Math.min(5, archetype.entities.length); let sampleMemory = 0; - + for (let i = 0; i < sampleSize; i++) { sampleMemory += this.estimateEntityMemoryUsage(archetype.entities[i]); } - + actualMemory = (sampleMemory / sampleSize) * entityCount; } @@ -365,18 +365,17 @@ export class EntityDataCollector { distribution.sort((a, b) => b.count - a.count); topEntities.sort((a, b) => b.componentCount - a.componentCount); - return { distribution, topEntities }; + return {distribution, topEntities}; } - private getArchetypeDistributionWithMemory(entityContainer: any): Array<{ signature: string; count: number; memory: number }> { const distribution = new Map(); if (entityContainer && entityContainer.entities) { entityContainer.entities.forEach((entity: any) => { const componentTypes = entity.components?.map((comp: any) => getComponentInstanceTypeName(comp)) || []; - const signature = componentTypes.length > 0 ? componentTypes.sort().join(', ') : '无组件'; + const signature = componentTypes.length > 0 ? componentTypes.sort().join(", ") : "无组件"; const existing = distribution.get(signature); let memory = this.estimateEntityMemoryUsage(entity); @@ -389,7 +388,7 @@ export class EntityDataCollector { existing.count++; existing.memory += memory; } else { - distribution.set(signature, { count: 1, memory, componentTypes }); + distribution.set(signature, {count: 1, memory, componentTypes}); } }); } @@ -437,7 +436,7 @@ export class EntityDataCollector { private calculateFallbackEntityStats(entityList: any): any { const allEntities = entityList.buffer || []; const activeEntities = allEntities.filter((entity: any) => - entity.enabled && !entity._isDestroyed + entity.enabled && !entity.isDestroyed ); return { @@ -454,14 +453,14 @@ export class EntityDataCollector { try { let totalSize = 0; - const entitySize = this.calculateObjectSize(entity, ['components', 'children', 'parent']); + const entitySize = this.calculateObjectSize(entity, ["components", "children", "parent"]); if (!isNaN(entitySize) && entitySize > 0) { totalSize += entitySize; } if (entity.components && Array.isArray(entity.components)) { entity.components.forEach((component: any) => { - const componentSize = this.calculateObjectSize(component, ['entity']); + const componentSize = this.calculateObjectSize(component, ["entity"]); if (!isNaN(componentSize) && componentSize > 0) { totalSize += componentSize; } @@ -475,57 +474,57 @@ export class EntityDataCollector { } public calculateObjectSize(obj: any, excludeKeys: string[] = []): number { - if (!obj || typeof obj !== 'object') return 0; - + if (!obj || typeof obj !== "object") return 0; + const visited = new WeakSet(); const maxDepth = 2; - + const calculate = (item: any, depth: number = 0): number => { - if (!item || typeof item !== 'object' || depth >= maxDepth) { + if (!item || typeof item !== "object" || depth >= maxDepth) { return 0; } - + if (visited.has(item)) return 0; visited.add(item); - + let itemSize = 32; - + try { const keys = Object.keys(item); const maxKeys = Math.min(keys.length, 20); - + for (let i = 0; i < maxKeys; i++) { const key = keys[i]; if (!key || excludeKeys.includes(key) || - key === 'constructor' || - key === '__proto__' || - key.startsWith('_cc_') || - key.startsWith('__')) { + key === "constructor" || + key === "__proto__" || + key.startsWith("_cc_") || + key.startsWith("__")) { continue; } const value = item[key]; itemSize += key.length * 2; - - if (typeof value === 'string') { + + if (typeof value === "string") { itemSize += Math.min(value.length * 2, 200); - } else if (typeof value === 'number') { + } else if (typeof value === "number") { itemSize += 8; - } else if (typeof value === 'boolean') { + } else if (typeof value === "boolean") { itemSize += 4; } else if (Array.isArray(value)) { itemSize += 40 + Math.min(value.length * 8, 160); - } else if (typeof value === 'object' && value !== null) { + } else if (typeof value === "object" && value !== null) { itemSize += calculate(value, depth + 1); } } } catch (error) { return 64; } - + return itemSize; }; - + try { const size = calculate(obj); return Math.max(size, 32); @@ -596,7 +595,7 @@ export class EntityDataCollector { } // 优先使用Entity的getDebugInfo方法 - if (typeof entity.getDebugInfo === 'function') { + if (typeof entity.getDebugInfo === "function") { const debugInfo = entity.getDebugInfo(); node = { ...node, @@ -630,7 +629,7 @@ export class EntityDataCollector { entity.getDebugInfo() : this.buildFallbackEntityInfo(entity, scene); - const componentCacheStats = (entity as any).getComponentCacheStats ? + const componentCacheStats = (entity as any).getComponentCacheStats ? (entity as any).getComponentCacheStats() : null; const componentDetails = this.extractComponentDetails(entity.components); @@ -639,7 +638,7 @@ export class EntityDataCollector { ...baseDebugInfo, parentName: entity.parent?.name || null, components: componentDetails, - componentTypes: baseDebugInfo.componentTypes || + componentTypes: baseDebugInfo.componentTypes || componentDetails.map((comp) => comp.typeName), cachePerformance: componentCacheStats ? { hitRate: componentCacheStats.cacheStats.hitRate, @@ -658,7 +657,7 @@ export class EntityDataCollector { */ private buildFallbackEntityInfo(entity: Entity, scene?: IScene | null): any { const sceneInfo = this.getSceneInfo(scene); - + return { name: entity.name || `Entity_${entity.id}`, id: entity.id, @@ -671,7 +670,7 @@ export class EntityDataCollector { sceneType: sceneInfo.type, componentCount: entity.components.length, componentTypes: entity.components.map((component: Component) => getComponentInstanceTypeName(component)), - componentMask: entity.componentMask?.toString() || '0', + componentMask: entity.componentMask?.toString() || "0", parentId: entity.parent?.id || null, childCount: entity.children?.length || 0, childIds: entity.children.map((child: Entity) => child.id) || [], @@ -691,28 +690,28 @@ export class EntityDataCollector { return components.map((component: Component) => { const typeName = getComponentInstanceTypeName(component); const properties: Record = {}; - + try { const propertyKeys = Object.keys(component); - propertyKeys.forEach(propertyKey => { - if (!propertyKey.startsWith('_') && propertyKey !== 'entity' && propertyKey !== 'constructor') { + propertyKeys.forEach((propertyKey) => { + if (!propertyKey.startsWith("_") && propertyKey !== "entity" && propertyKey !== "constructor") { const propertyValue = (component as any)[propertyKey]; if (propertyValue !== undefined && propertyValue !== null) { properties[propertyKey] = this.formatPropertyValue(propertyValue); } } }); - + // 如果没有找到任何属性,添加一些调试信息 if (Object.keys(properties).length === 0) { - properties['_info'] = '该组件没有公开属性'; - properties['_componentId'] = getComponentInstanceTypeName(component); + properties["_info"] = "该组件没有公开属性"; + properties["_componentId"] = getComponentInstanceTypeName(component); } } catch (error) { - properties['_error'] = '属性提取失败'; - properties['_componentId'] = getComponentInstanceTypeName(component); + properties["_error"] = "属性提取失败"; + properties["_componentId"] = getComponentInstanceTypeName(component); } - + return { typeName: typeName, properties: properties @@ -739,20 +738,20 @@ export class EntityDataCollector { const component = entity.components[componentIndex]; const properties: Record = {}; - const propertyKeys = Object.keys(component); - propertyKeys.forEach(propertyKey => { - if (!propertyKey.startsWith('_') && propertyKey !== 'entity') { - const propertyValue = (component as any)[propertyKey]; - if (propertyValue !== undefined && propertyValue !== null) { + const propertyKeys = Object.keys(component); + propertyKeys.forEach((propertyKey) => { + if (!propertyKey.startsWith("_") && propertyKey !== "entity") { + const propertyValue = (component as any)[propertyKey]; + if (propertyValue !== undefined && propertyValue !== null) { properties[propertyKey] = this.formatPropertyValue(propertyValue); } - } - }); + } + }); return properties; - } catch (error) { - return { _error: '属性提取失败' }; - } + } catch (error) { + return {_error: "属性提取失败"}; + } } /** @@ -763,8 +762,8 @@ export class EntityDataCollector { return value; } - if (typeof value !== 'object') { - if (typeof value === 'string' && value.length > 200) { + if (typeof value !== "object") { + if (typeof value === "string" && value.length > 200) { return `[长字符串: ${value.length}字符] ${value.substring(0, 100)}...`; } return value; @@ -786,7 +785,7 @@ export class EntityDataCollector { if (obj.length === 0) return []; if (obj.length > 10) { - const sample = obj.slice(0, 3).map(item => this.formatPropertyValue(item, 1)); + const sample = obj.slice(0, 3).map((item) => this.formatPropertyValue(item, 1)); return { _isLazyArray: true, _arrayLength: obj.length, @@ -795,7 +794,7 @@ export class EntityDataCollector { }; } - return obj.map(item => this.formatPropertyValue(item, 1)); + return obj.map((item) => this.formatPropertyValue(item, 1)); } const keys = Object.keys(obj); @@ -813,7 +812,7 @@ export class EntityDataCollector { break; } - if (key.startsWith('_') || key.startsWith('$') || typeof obj[key] === 'function') { + if (key.startsWith("_") || key.startsWith("$") || typeof obj[key] === "function") { continue; } @@ -840,10 +839,10 @@ export class EntityDataCollector { */ private createLazyLoadPlaceholder(obj: any): any { try { - const typeName = obj.constructor?.name || 'Object'; + const typeName = obj.constructor?.name || "Object"; const summary = this.getObjectSummary(obj, typeName); - - return { + + return { _isLazyObject: true, _typeName: typeName, _summary: summary, @@ -852,7 +851,7 @@ export class EntityDataCollector { } catch (error) { return { _isLazyObject: true, - _typeName: 'Unknown', + _typeName: "Unknown", _summary: `无法分析的对象: ${error instanceof Error ? error.message : String(error)}`, _objectId: Math.random().toString(36).substr(2, 9) }; @@ -864,28 +863,28 @@ export class EntityDataCollector { */ private getObjectSummary(obj: any, typeName: string): string { try { - if (typeName.toLowerCase().includes('vec') || typeName.toLowerCase().includes('vector')) { + if (typeName.toLowerCase().includes("vec") || typeName.toLowerCase().includes("vector")) { if (obj.x !== undefined && obj.y !== undefined) { - const z = obj.z !== undefined ? obj.z : ''; - return `${typeName}(${obj.x}, ${obj.y}${z ? ', ' + z : ''})`; + const z = obj.z !== undefined ? obj.z : ""; + return `${typeName}(${obj.x}, ${obj.y}${z ? ", " + z : ""})`; } } - if (typeName.toLowerCase().includes('color')) { + if (typeName.toLowerCase().includes("color")) { if (obj.r !== undefined && obj.g !== undefined && obj.b !== undefined) { const a = obj.a !== undefined ? obj.a : 1; return `${typeName}(${obj.r}, ${obj.g}, ${obj.b}, ${a})`; } } - if (typeName.toLowerCase().includes('node')) { - const name = obj.name || obj._name || '未命名'; + if (typeName.toLowerCase().includes("node")) { + const name = obj.name || obj._name || "未命名"; return `${typeName}: ${name}`; } - if (typeName.toLowerCase().includes('component')) { - const nodeName = obj.node?.name || obj.node?._name || ''; - return `${typeName}${nodeName ? ` on ${nodeName}` : ''}`; + if (typeName.toLowerCase().includes("component")) { + const nodeName = obj.node?.name || obj.node?._name || ""; + return `${typeName}${nodeName ? ` on ${nodeName}` : ""}`; } const keys = Object.keys(obj); @@ -956,16 +955,16 @@ export class EntityDataCollector { private getObjectByPath(root: any, path: string): any { if (!path) return root; - const parts = path.split('.'); + const parts = path.split("."); let current = root; for (const part of parts) { if (current === null || current === undefined) return null; // 处理数组索引 - if (part.includes('[') && part.includes(']')) { - const arrayName = part.substring(0, part.indexOf('[')); - const index = parseInt(part.substring(part.indexOf('[') + 1, part.indexOf(']'))); + if (part.includes("[") && part.includes("]")) { + const arrayName = part.substring(0, part.indexOf("[")); + const index = parseInt(part.substring(part.indexOf("[") + 1, part.indexOf("]"))); if (arrayName) { current = current[arrayName]; @@ -983,4 +982,4 @@ export class EntityDataCollector { return current; } -} \ No newline at end of file +} diff --git a/packages/core/src/Utils/Debug/PerformanceDataCollector.ts b/packages/core/src/Utils/Debug/PerformanceDataCollector.ts index 5b1e8f98..742030cc 100644 --- a/packages/core/src/Utils/Debug/PerformanceDataCollector.ts +++ b/packages/core/src/Utils/Debug/PerformanceDataCollector.ts @@ -1,5 +1,5 @@ -import { IPerformanceDebugData } from '../../Types'; -import { Time } from '../Time'; +import {IPerformanceDebugData} from "../../Types"; +import {Time} from "../Time"; /** * 性能数据收集器 @@ -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; @@ -61,7 +61,7 @@ export class PerformanceDataCollector { private getECSPerformanceData(performanceMonitor: any): { totalExecutionTime: number; systemBreakdown: Array } { // 检查性能监视器是否存在 if (!performanceMonitor) { - return { totalExecutionTime: 0, systemBreakdown: [] }; + return {totalExecutionTime: 0, systemBreakdown: []}; } if (!performanceMonitor.enabled) { @@ -71,26 +71,26 @@ export class PerformanceDataCollector { } catch (error) { // 如果无法启用,返回默认值 } - return { totalExecutionTime: 0, systemBreakdown: [] }; + return {totalExecutionTime: 0, systemBreakdown: []}; } try { let totalTime = 0; const systemBreakdown = []; - + const stats = performanceMonitor.getAllSystemStats(); - + if (stats.size === 0) { - return { totalExecutionTime: 0, systemBreakdown: [] }; + 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,21 +98,21 @@ 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 }; } catch (error) { - return { totalExecutionTime: 0, systemBreakdown: [] }; + return {totalExecutionTime: 0, 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; @@ -202,21 +202,21 @@ export class PerformanceDataCollector { private updateGCCount(): number { try { // 尝试使用PerformanceObserver来检测GC - if (typeof PerformanceObserver !== 'undefined') { + if (typeof PerformanceObserver !== "undefined") { // 这是一个简化的GC检测方法 // 实际的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..04503a1f 100644 --- a/packages/core/src/Utils/Debug/SceneDataCollector.ts +++ b/packages/core/src/Utils/Debug/SceneDataCollector.ts @@ -1,5 +1,5 @@ -import { ISceneDebugData } from '../../Types'; -import { IScene } from '../../ECS/IScene'; +import {ISceneDebugData} from "../../Types"; +import {IScene} from "../../ECS/IScene"; /** * 场景数据收集器 @@ -14,7 +14,7 @@ export class SceneDataCollector { public collectSceneData(scene?: IScene | null): ISceneDebugData { if (!scene) { return { - currentSceneName: 'No Scene', + currentSceneName: "No Scene", isInitialized: false, sceneRunTime: 0, sceneEntityCount: 0, @@ -31,7 +31,7 @@ export class SceneDataCollector { const entityProcessors = (scene as any).entityProcessors; return { - currentSceneName: (scene as any).name || 'Unnamed Scene', + currentSceneName: (scene as any).name || "Unnamed Scene", isInitialized: (scene as any)._didSceneBegin || false, sceneRunTime: runTime, sceneEntityCount: entityList?.buffer?.length || 0, @@ -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..1fbda787 100644 --- a/packages/core/src/Utils/Debug/SystemDataCollector.ts +++ b/packages/core/src/Utils/Debug/SystemDataCollector.ts @@ -1,6 +1,6 @@ -import { ISystemDebugData } from '../../Types'; -import { getSystemInstanceTypeName } from '../../ECS/Decorators'; -import { IScene } from '../../ECS/IScene'; +import {ISystemDebugData} from "../../Types"; +import {getSystemInstanceTypeName} from "../../ECS/Decorators"; +import {IScene} from "../../ECS/IScene"; /** * 系统数据收集器 @@ -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..f55597e5 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(); @@ -80,7 +80,7 @@ export class WebSocketManager { } try { - const message = typeof data === 'string' ? data : JSON.stringify(data); + const message = typeof data === "string" ? data : JSON.stringify(data); this.ws.send(message); } catch (error) { } @@ -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..234e9d6e 100644 --- a/packages/core/src/Utils/Debug/index.ts +++ b/packages/core/src/Utils/Debug/index.ts @@ -1,8 +1,8 @@ -export { EntityDataCollector } from './EntityDataCollector'; -export { SystemDataCollector } from './SystemDataCollector'; -export { PerformanceDataCollector } from './PerformanceDataCollector'; -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 {EntityDataCollector} from "./EntityDataCollector"; +export {SystemDataCollector} from "./SystemDataCollector"; +export {PerformanceDataCollector} from "./PerformanceDataCollector"; +export {ComponentDataCollector} from "./ComponentDataCollector"; +export {SceneDataCollector} from "./SceneDataCollector"; +export {WebSocketManager} from "./WebSocketManager"; +export {DebugManager} from "./DebugManager"; +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..dce4d102 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 {TypeUtils} from "./TypeUtils"; +export {NumberExtension} from "./NumberExtension"; diff --git a/packages/core/src/Utils/Logger/ConsoleLogger.ts b/packages/core/src/Utils/Logger/ConsoleLogger.ts index 18700b5f..1dd27a4d 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"; /** @@ -12,7 +12,7 @@ export class ConsoleLogger implements ILogger { this._config = { level: LogLevel.Info, enableTimestamp: true, - enableColors: typeof window === 'undefined', + enableColors: typeof window === "undefined", ...config }; } @@ -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..e04f22fe 100644 --- a/packages/core/src/Utils/Logger/Constants.ts +++ b/packages/core/src/Utils/Logger/Constants.ts @@ -15,27 +15,27 @@ export enum LogLevel { */ export const Colors = { // 基础颜色 - BLACK: '\x1b[30m', - RED: '\x1b[31m', - GREEN: '\x1b[32m', - YELLOW: '\x1b[33m', - BLUE: '\x1b[34m', - MAGENTA: '\x1b[35m', - CYAN: '\x1b[36m', - WHITE: '\x1b[37m', - + BLACK: "\x1b[30m", + RED: "\x1b[31m", + GREEN: "\x1b[32m", + YELLOW: "\x1b[33m", + BLUE: "\x1b[34m", + MAGENTA: "\x1b[35m", + CYAN: "\x1b[36m", + WHITE: "\x1b[37m", + // 亮色版本 - BRIGHT_BLACK: '\x1b[90m', - BRIGHT_RED: '\x1b[91m', - BRIGHT_GREEN: '\x1b[92m', - BRIGHT_YELLOW: '\x1b[93m', - BRIGHT_BLUE: '\x1b[94m', - BRIGHT_MAGENTA: '\x1b[95m', - BRIGHT_CYAN: '\x1b[96m', - BRIGHT_WHITE: '\x1b[97m', - + BRIGHT_BLACK: "\x1b[90m", + BRIGHT_RED: "\x1b[91m", + BRIGHT_GREEN: "\x1b[92m", + BRIGHT_YELLOW: "\x1b[93m", + BRIGHT_BLUE: "\x1b[94m", + BRIGHT_MAGENTA: "\x1b[95m", + BRIGHT_CYAN: "\x1b[96m", + BRIGHT_WHITE: "\x1b[97m", + // 特殊 - RESET: '\x1b[0m', - BOLD: '\x1b[1m', - UNDERLINE: '\x1b[4m' + RESET: "\x1b[0m", + BOLD: "\x1b[1m", + UNDERLINE: "\x1b[4m" } as const; diff --git a/packages/core/src/Utils/Logger/LoggerManager.ts b/packages/core/src/Utils/Logger/LoggerManager.ts index 6bf9506f..68799a3d 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"; /** * 日志管理器 @@ -26,7 +26,7 @@ export class LoggerManager { if (this._loggerFactory) { return this._loggerFactory(); } - return new ConsoleLogger({ level: this._defaultLevel }); + return new ConsoleLogger({level: this._defaultLevel}); } /** @@ -53,7 +53,7 @@ export class LoggerManager { if (!this._loggers.has(name)) { const logger = this._loggerFactory ? this._loggerFactory(name) - : new ConsoleLogger({ prefix: name, level: this._defaultLevel }); + : new ConsoleLogger({prefix: name, level: this._defaultLevel}); this._loggers.set(name, logger); } @@ -136,8 +136,8 @@ export class LoggerManager { public setLoggerFactory(factory: (name?: string) => ILogger): void { if (this._defaultLogger || this._loggers.size > 0) { console.warn( - '[LoggerManager] setLoggerFactory 应该在导入 ECS 模块之前调用。' + - '已创建的 logger 引用不会被更新。' + "[LoggerManager] setLoggerFactory 应该在导入 ECS 模块之前调用。" + + "已创建的 logger 引用不会被更新。" ); } @@ -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..c92148a6 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/Logger/index.ts b/packages/core/src/Utils/Logger/index.ts index 361f0d8a..bd2a02cb 100644 --- a/packages/core/src/Utils/Logger/index.ts +++ b/packages/core/src/Utils/Logger/index.ts @@ -1,4 +1,4 @@ -export * from './ConsoleLogger'; -export * from './Constants'; -export * from './LoggerManager'; -export * from './Types'; +export * from "./ConsoleLogger"; +export * from "./Constants"; +export * from "./LoggerManager"; +export * from "./Types"; diff --git a/packages/core/src/Utils/PerformanceMonitor.ts b/packages/core/src/Utils/PerformanceMonitor.ts index c13d9dd4..f6ac134a 100644 --- a/packages/core/src/Utils/PerformanceMonitor.ts +++ b/packages/core/src/Utils/PerformanceMonitor.ts @@ -46,12 +46,12 @@ export interface PerformanceStats { * 性能警告类型 */ export enum PerformanceWarningType { - HIGH_EXECUTION_TIME = 'high_execution_time', - HIGH_MEMORY_USAGE = 'high_memory_usage', - HIGH_CPU_USAGE = 'high_cpu_usage', - FREQUENT_GC = 'frequent_gc', - LOW_FPS = 'low_fps', - HIGH_ENTITY_COUNT = 'high_entity_count' + HIGH_EXECUTION_TIME = "high_execution_time", + HIGH_MEMORY_USAGE = "high_memory_usage", + HIGH_CPU_USAGE = "high_cpu_usage", + FREQUENT_GC = "frequent_gc", + LOW_FPS = "low_fps", + HIGH_ENTITY_COUNT = "high_entity_count" } /** @@ -61,7 +61,7 @@ export interface PerformanceWarning { type: PerformanceWarningType; systemName: string; message: string; - severity: 'low' | 'medium' | 'high' | 'critical'; + severity: "low" | "medium" | "high" | "critical"; timestamp: number; value: number; threshold: number; @@ -99,7 +99,7 @@ export interface PerformanceThresholds { }; } -import type { IService } from '../Core/ServiceContainer'; +import type {IService} from "../Core/ServiceContainer"; /** * 高性能监控器 @@ -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; } @@ -289,28 +289,28 @@ 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(""); } // 总体统计 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}`); - return lines.join('\n'); + return lines.join("\n"); } /** @@ -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..5d14f9e4 100644 --- a/packages/core/src/Utils/Pool/Pool.ts +++ b/packages/core/src/Utils/Pool/Pool.ts @@ -1,12 +1,14 @@ -import { IPoolable, PoolStats } from './IPoolable'; +import {IPoolable, PoolStats} from "./IPoolable"; + +type Constructor = new (...args: unknown[]) => T; /** * 高性能通用对象池 * 支持任意类型的对象池化,包含详细的统计信息 */ export class Pool { - private static _pools = new Map>(); - + private static _pools = new Map>(); + private _objects: T[] = []; private _createFn: () => T; private _maxSize: number; @@ -42,17 +44,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 +64,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 +72,7 @@ export class Pool { this._updateMemoryUsage(); return obj; } - + // 池中没有可用对象,创建新对象 this._stats.totalCreated++; this._updateHitRate(); @@ -83,9 +85,9 @@ export class Pool { */ public release(obj: T): void { if (!obj) return; - + this._stats.totalReleased++; - + // 如果池未满,将对象放回池中 if (this._stats.size < this._maxSize) { // 重置对象状态 @@ -102,7 +104,7 @@ export class Pool { * @returns 统计信息对象 */ public getStats(): Readonly { - return { ...this._stats }; + return {...this._stats}; } /** @@ -113,7 +115,7 @@ export class Pool { for (const obj of this._objects) { obj.reset(); } - + this._objects.length = 0; this._stats.size = 0; this._updateMemoryUsage(); @@ -125,7 +127,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 +135,7 @@ export class Pool { this._stats.size--; } } - + this._updateMemoryUsage(); } @@ -143,7 +145,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 +153,7 @@ export class Pool { this._stats.totalCreated++; this._stats.size++; } - + this._updateMemoryUsage(); } @@ -162,7 +164,7 @@ export class Pool { public setMaxSize(maxSize: number): void { this._maxSize = maxSize; this._stats.maxSize = maxSize; - + // 如果当前池大小超过新的最大值,进行压缩 if (this._objects.length > maxSize) { this.compact(maxSize); @@ -197,7 +199,7 @@ export class Pool { * 获取所有已注册的池类型 * @returns 所有池类型的数组 */ - public static getAllPoolTypes(): Function[] { + public static getAllPoolTypes(): Constructor[] { return Array.from(this._pools.keys()); } @@ -207,12 +209,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; } @@ -241,13 +243,13 @@ export class Pool { */ public static getGlobalStatsString(): string { const stats = this.getAllPoolStats(); - const lines: string[] = ['=== Object Pool Global Statistics ===', '']; - + const lines: string[] = ["=== Object Pool Global Statistics ===", ""]; + if (Object.keys(stats).length === 0) { - lines.push('No pools registered'); - return lines.join('\n'); + 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}`); @@ -255,10 +257,10 @@ export class Pool { lines.push(` Total Created: ${stat.totalCreated}`); lines.push(` Total Obtained: ${stat.totalObtained}`); lines.push(` Memory: ${(stat.estimatedMemoryUsage / 1024).toFixed(1)} KB`); - lines.push(''); + lines.push(""); } - - return lines.join('\n'); + + return lines.join("\n"); } /** @@ -279,4 +281,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..ec3f058b 100644 --- a/packages/core/src/Utils/Pool/PoolManager.ts +++ b/packages/core/src/Utils/Pool/PoolManager.ts @@ -1,6 +1,6 @@ -import { IPoolable, PoolStats } from './IPoolable'; -import { Pool } from './Pool'; -import type { IService } from '../../Core/ServiceContainer'; +import {IPoolable, PoolStats} from "./IPoolable"; +import {Pool} from "./Pool"; +import type {IService} from "../../Core/ServiceContainer"; /** * 池管理器 @@ -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, @@ -173,29 +173,29 @@ export class PoolManager implements IService { * @returns 格式化字符串 */ public getStatsString(): string { - const lines: string[] = ['=== Pool Manager Statistics ===', '']; - + const lines: string[] = ["=== Pool Manager Statistics ===", ""]; + if (this.pools.size === 0) { - lines.push('No pools registered'); - return lines.join('\n'); + 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(''); - + lines.push(""); + for (const [name, pool] of this.pools) { const stats = pool.getStats(); lines.push(`${name}:`); lines.push(` Size: ${stats.size}/${stats.maxSize}`); lines.push(` Hit Rate: ${(stats.hitRate * 100).toFixed(1)}%`); lines.push(` Memory: ${(stats.estimatedMemoryUsage / 1024).toFixed(1)} KB`); - lines.push(''); + lines.push(""); } - - return lines.join('\n'); + + 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..dbf89afb 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 "./IPoolable"; +export * from "./Pool"; +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..e2266d7f 100644 --- a/packages/core/src/Utils/Timers/Timer.ts +++ b/packages/core/src/Utils/Timers/Timer.ts @@ -1,5 +1,5 @@ -import { ITimer } from './ITimer'; -import { Time } from '../Time'; +import {ITimer} from "./ITimer"; +import {Time} from "../Time"; /** * 私有类隐藏ITimer的实现 @@ -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..f0a27686 100644 --- a/packages/core/src/Utils/Timers/TimerManager.ts +++ b/packages/core/src/Utils/Timers/TimerManager.ts @@ -1,8 +1,8 @@ -import { Timer } from './Timer'; -import { ITimer } from './ITimer'; -import type { IService } from '../../Core/ServiceContainer'; -import type { IUpdatable } from '../../Types/IUpdatable'; -import { Updatable } from '../../Core/DI'; +import {Timer} from "./Timer"; +import {ITimer} from "./ITimer"; +import type {IService} from "../../Core/ServiceContainer"; +import type {IUpdatable} from "../../Types/IUpdatable"; +import {Updatable} from "../../Core/DI"; /** * 定时器管理器 @@ -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..a9ae40e9 100644 --- a/packages/core/src/Utils/index.ts +++ b/packages/core/src/Utils/index.ts @@ -1,9 +1,9 @@ -export * from './Extensions'; -export * from './Pool'; -export * from './Emitter'; -export * from './GlobalManager'; -export * from './PerformanceMonitor'; -export { Time } from './Time'; -export * from './Debug'; -export * from './Logger'; -export * from './BinarySerializer'; +export * from "./Extensions"; +export * from "./Pool"; +export * from "./Emitter"; +export * from "./GlobalManager"; +export * from "./PerformanceMonitor"; +export {Time} from "./Time"; +export * from "./Debug"; +export * from "./Logger"; +export * from "./BinarySerializer"; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 2ef87b2d..3bafaa76 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -4,17 +4,17 @@ */ // 核心模块 -export { Core } from './Core'; -export { ServiceContainer, ServiceLifetime } from './Core/ServiceContainer'; -export type { IService, ServiceType } from './Core/ServiceContainer'; +export {Core} from "./Core"; +export {ServiceContainer, ServiceLifetime} from "./Core/ServiceContainer"; +export type {IService, ServiceType} from "./Core/ServiceContainer"; // 插件系统 -export { PluginManager } from './Core/PluginManager'; -export { PluginState } from './Core/Plugin'; -export type { IPlugin, IPluginMetadata } from './Core/Plugin'; +export {PluginManager} from "./Core/PluginManager"; +export {PluginState} from "./Core/Plugin"; +export type {IPlugin, IPluginMetadata} from "./Core/Plugin"; // 内置插件 -export * from './Plugins'; +export * from "./Plugins"; // 依赖注入 export { @@ -25,43 +25,43 @@ export { createInstance, isUpdatable, getUpdatableMetadata -} from './Core/DI'; -export type { InjectableMetadata, UpdatableMetadata } from './Core/DI'; +} from "./Core/DI"; +export type {InjectableMetadata, UpdatableMetadata} from "./Core/DI"; // 核心管理器 -export { Emitter, FuncPack } from './Utils/Emitter'; -export { GlobalManager } from './Utils/GlobalManager'; -export { TimerManager } from './Utils/Timers/TimerManager'; -export { ITimer } from './Utils/Timers/ITimer'; -export { Timer } from './Utils/Timers/Timer'; +export {Emitter, FuncPack} from "./Utils/Emitter"; +export {GlobalManager} from "./Utils/GlobalManager"; +export {TimerManager} from "./Utils/Timers/TimerManager"; +export {ITimer} from "./Utils/Timers/ITimer"; +export {Timer} from "./Utils/Timers/Timer"; // 日志系统 -export { - LoggerManager, - ConsoleLogger, - Logger, - createLogger, +export { + LoggerManager, + ConsoleLogger, + Logger, + createLogger, setGlobalLogLevel, - LogLevel -} from './Utils/Logger'; -export type { ILogger, LoggerConfig } from './Utils/Logger'; + LogLevel +} from "./Utils/Logger"; +export type {ILogger, LoggerConfig} from "./Utils/Logger"; // ECS核心组件 -export * from './ECS'; +export * from "./ECS"; // TypeScript类型增强API -export * from './ECS/TypedEntity'; -export * from './ECS/Core/Query/TypedQuery'; +export * from "./ECS/TypedEntity"; +export * from "./ECS/Core/Query/TypedQuery"; // 事件系统 -export { ECSEventType, EventPriority, EVENT_TYPES, EventTypeValidator } from './ECS/CoreEvents'; +export {ECSEventType, EventPriority, EVENT_TYPES, EventTypeValidator} from "./ECS/CoreEvents"; // 工具类和类型定义 -export * from './Utils'; -export * from './Types'; +export * from "./Utils"; +export * from "./Types"; // 显式导出ComponentPool类(解决与Types中ComponentPool接口的命名冲突) -export { ComponentPool, ComponentPoolManager } from './ECS/Core/Storage'; +export {ComponentPool, ComponentPoolManager} from "./ECS/Core/Storage"; // 平台适配 -export * from './Platform'; \ No newline at end of file +export * from "./Platform"; diff --git a/packages/core/tests/ECS/Component.test.ts b/packages/core/tests/ECS/Component.test.ts index 99529fe0..a3bf208a 100644 --- a/packages/core/tests/ECS/Component.test.ts +++ b/packages/core/tests/ECS/Component.test.ts @@ -27,7 +27,6 @@ describe('Component - 组件基类测试', () => { let scene: Scene; beforeEach(() => { - Component._idGenerator = 0; component = new TestComponent(); scene = new Scene(); entity = scene.createEntity('TestEntity'); @@ -51,7 +50,7 @@ describe('Component - 组件基类测试', () => { }); test('组件ID应该递增分配', () => { - const startId = Component._idGenerator; + const startId = Component.nextComponentId; const component1 = new TestComponent(); const component2 = new TestComponent();