From 87dd564a12860b4d7053656fb888a4ef2a3b2e2a Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Fri, 8 Aug 2025 11:16:00 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E7=BB=9F=E4=B8=80=E6=94=B9?= =?UTF-8?q?=E7=94=A8Logger=E6=8E=A7=E5=88=B6=E7=AE=A1=E7=90=86=20=E6=8B=86?= =?UTF-8?q?=E5=88=86pool=E7=B1=BB=E5=92=8CFluentAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lerna.json | 3 +- package-lock.json | 2 +- packages/core/jest.config.cjs | 2 +- packages/core/package.json | 10 + packages/core/src/Core.ts | 24 +- .../core/src/ECS/Core/ComponentStorage.ts | 5 +- .../ComponentStorage/ComponentRegistry.ts | 196 ++++++ .../core/src/ECS/Core/DirtyTrackingSystem.ts | 8 +- packages/core/src/ECS/Core/EventBus.ts | 16 +- packages/core/src/ECS/Core/EventSystem.ts | 11 +- packages/core/src/ECS/Core/FluentAPI.ts | 649 +----------------- .../ECS/Core/FluentAPI/ComponentBuilder.ts | 55 ++ .../src/ECS/Core/FluentAPI/ECSFluentAPI.ts | 210 ++++++ .../ECS/Core/FluentAPI/EntityBatchOperator.ts | 98 +++ .../src/ECS/Core/FluentAPI/EntityBuilder.ts | 200 ++++++ .../src/ECS/Core/FluentAPI/SceneBuilder.ts | 90 +++ packages/core/src/ECS/Core/FluentAPI/index.ts | 5 + packages/core/src/ECS/Core/QuerySystem.ts | 13 +- packages/core/src/ECS/Core/SoAStorage.ts | 6 +- packages/core/src/ECS/Entity.ts | 8 +- .../core/src/ECS/Utils/EntityProcessorList.ts | 4 +- .../src/Core => core/src/Utils}/Logger.ts | 100 ++- packages/core/src/Utils/Pool.ts | 565 --------------- packages/core/src/Utils/Pool/IPoolable.ts | 29 + packages/core/src/Utils/Pool/Pool.ts | 282 ++++++++ packages/core/src/Utils/Pool/PoolManager.ts | 231 +++++++ packages/core/src/Utils/Pool/index.ts | 3 + packages/core/src/Utils/index.ts | 3 +- packages/core/src/index.ts | 11 + packages/network/package.json | 2 +- packages/network/src/Core/NetworkClient.ts | 22 +- .../network/src/Core/NetworkConnection.ts | 16 +- .../network/src/Core/NetworkEnvironment.ts | 14 +- packages/network/src/Core/NetworkIdentity.ts | 27 +- packages/network/src/Core/NetworkManager.ts | 18 +- .../src/Core/NetworkPerformanceMonitor.ts | 18 +- packages/network/src/Core/NetworkServer.ts | 44 +- packages/network/src/Core/index.ts | 14 +- .../network/src/Messaging/MessageHandler.ts | 20 +- packages/network/src/NetworkComponent.ts | 10 +- .../src/Serialization/ProtobufSerializer.ts | 14 +- .../network/src/Snapshot/SnapshotManager.ts | 20 +- .../network/src/SyncVar/SyncVarDecorator.ts | 12 +- .../network/src/SyncVar/SyncVarFactory.ts | 5 +- .../network/src/SyncVar/SyncVarManager.ts | 40 +- .../src/SyncVar/SyncVarMessageHandler.ts | 45 +- .../network/src/SyncVar/SyncVarOptimizer.ts | 10 +- packages/network/src/SyncVar/SyncVarProxy.ts | 20 +- .../src/SyncVar/SyncVarSyncScheduler.ts | 31 +- packages/network/src/types/global.d.ts | 52 +- packages/network/tsconfig.json | 11 +- 51 files changed, 1813 insertions(+), 1491 deletions(-) create mode 100644 packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts create mode 100644 packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts create mode 100644 packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts create mode 100644 packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts create mode 100644 packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts create mode 100644 packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts create mode 100644 packages/core/src/ECS/Core/FluentAPI/index.ts rename packages/{network/src/Core => core/src/Utils}/Logger.ts (73%) delete mode 100644 packages/core/src/Utils/Pool.ts create mode 100644 packages/core/src/Utils/Pool/IPoolable.ts create mode 100644 packages/core/src/Utils/Pool/Pool.ts create mode 100644 packages/core/src/Utils/Pool/PoolManager.ts create mode 100644 packages/core/src/Utils/Pool/index.ts diff --git a/lerna.json b/lerna.json index 9270060a..08a54168 100644 --- a/lerna.json +++ b/lerna.json @@ -20,6 +20,5 @@ }, "packages": [ "packages/*" - ], - "useWorkspaces": true + ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4577decc..a3287ab0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11427,7 +11427,7 @@ "ws": "^8.18.0" }, "devDependencies": { - "@esengine/ecs-framework": "file:../core", + "@esengine/ecs-framework": "*", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-terser": "^0.4.4", diff --git a/packages/core/jest.config.cjs b/packages/core/jest.config.cjs index 50fbd5c2..12ac9b24 100644 --- a/packages/core/jest.config.cjs +++ b/packages/core/jest.config.cjs @@ -42,7 +42,7 @@ module.exports = { verbose: true, transform: { '^.+\\.tsx?$': ['ts-jest', { - tsconfig: 'tsconfig.test.json', + tsconfig: 'tsconfig.json', }], }, moduleNameMapper: { diff --git a/packages/core/package.json b/packages/core/package.json index 7b02ae1f..cea731e4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -5,6 +5,16 @@ "type": "module", "main": "bin/index.js", "types": "bin/index.d.ts", + "exports": { + ".": { + "types": "./bin/index.d.ts", + "import": "./bin/index.js", + "development": { + "types": "./src/index.ts", + "import": "./src/index.ts" + } + } + }, "files": [ "bin/**/*", "README.md", diff --git a/packages/core/src/Core.ts b/packages/core/src/Core.ts index ed65ff09..4ec3c06d 100644 --- a/packages/core/src/Core.ts +++ b/packages/core/src/Core.ts @@ -4,12 +4,13 @@ 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'; +import { PoolManager } from './Utils/Pool/PoolManager'; import { ECSFluentAPI, createECSAPI } from './ECS/Core/FluentAPI'; import { Scene } from './ECS/Scene'; import { DebugManager } from './Utils/Debug'; import { ICoreConfig, IECSDebugConfig } from './Types'; import { BigIntFactory, EnvironmentInfo } from './ECS/Utils/BigIntCompatibility'; +import { createLogger } from './Utils/Logger'; /** * 游戏引擎核心类 @@ -33,7 +34,7 @@ import { BigIntFactory, EnvironmentInfo } from './ECS/Utils/BigIntCompatibility' * * // 调度定时器 * Core.schedule(1.0, false, null, (timer) => { - * console.log("1秒后执行"); + * Core._logger.info("1秒后执行"); * }); * ``` */ @@ -49,6 +50,11 @@ export class Core { * 全局核心实例 */ private static _instance: Core; + + /** + * Core专用日志器 + */ + private static _logger = createLogger('Core'); /** * 实体系统启用状态 @@ -265,7 +271,7 @@ export class Core { */ public static update(deltaTime: number): void { if (!this._instance) { - console.warn("Core实例未创建,请先调用Core.create()"); + Core._logger.warn("Core实例未创建,请先调用Core.create()"); return; } @@ -341,7 +347,7 @@ export class Core { */ public static enableDebug(config: IECSDebugConfig): void { if (!this._instance) { - console.warn("Core实例未创建,请先调用Core.create()"); + Core._logger.warn("Core实例未创建,请先调用Core.create()"); return; } @@ -449,13 +455,13 @@ export class Core { private logCompatibilityInfo(): void { const info = this._environmentInfo; - console.log('ECS Framework 兼容性检测结果:'); - console.log(` 环境: ${info.environment}`); - console.log(` JavaScript引擎: ${info.jsEngine}`); - console.log(` BigInt支持: ${info.supportsBigInt ? '支持' : '不支持'}`); + Core._logger.info('ECS Framework 兼容性检测结果:'); + Core._logger.info(` 环境: ${info.environment}`); + Core._logger.info(` JavaScript引擎: ${info.jsEngine}`); + Core._logger.info(` BigInt支持: ${info.supportsBigInt ? '支持' : '不支持'}`); if (!info.supportsBigInt) { - console.warn('BigInt兼容模式已启用'); + Core._logger.warn('BigInt兼容模式已启用'); } } diff --git a/packages/core/src/ECS/Core/ComponentStorage.ts b/packages/core/src/ECS/Core/ComponentStorage.ts index 68f72926..70164316 100644 --- a/packages/core/src/ECS/Core/ComponentStorage.ts +++ b/packages/core/src/ECS/Core/ComponentStorage.ts @@ -1,6 +1,7 @@ import { Component } from '../Component'; import { IBigIntLike, BigIntFactory } from '../Utils/BigIntCompatibility'; import { SoAStorage, EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy } from './SoAStorage'; +import { createLogger } from '../../Utils/Logger'; // 重新导出装饰器 export { EnableSoA, HighPrecision, Float64, Int32, SerializeMap, SerializeSet, SerializeArray, DeepCopy }; @@ -15,6 +16,7 @@ export type ComponentType = new (...args: unkno * 管理组件类型的位掩码分配 */ export class ComponentRegistry { + protected static readonly _logger = createLogger('ComponentStorage'); private static componentTypes = new Map(); private static componentNameToType = new Map(); private static componentNameToId = new Map(); @@ -400,6 +402,7 @@ export class ComponentStorage { * 管理所有组件类型的存储器 */ export class ComponentStorageManager { + private static readonly _logger = createLogger('ComponentStorage'); private storages = new Map | SoAStorage>(); /** @@ -417,7 +420,7 @@ export class ComponentStorageManager { if (enableSoA) { // 使用SoA优化存储 storage = new SoAStorage(componentType); - console.log(`[SoA] 为 ${componentType.name} 启用SoA优化(适用于大规模批量操作)`); + ComponentStorageManager._logger.info(`为 ${componentType.name} 启用SoA优化(适用于大规模批量操作)`); } else { // 默认使用原始存储 storage = new ComponentStorage(componentType); diff --git a/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts b/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts new file mode 100644 index 00000000..da5832e7 --- /dev/null +++ b/packages/core/src/ECS/Core/ComponentStorage/ComponentRegistry.ts @@ -0,0 +1,196 @@ +import { Component } from '../../Component'; +import { IBigIntLike, BigIntFactory } from '../../Utils/BigIntCompatibility'; +import { createLogger } from '../../../Utils/Logger'; + +/** + * 组件类型定义 + */ +export type ComponentType = new (...args: unknown[]) => T; + +/** + * 组件注册表 + * 管理组件类型的位掩码分配 + */ +export class ComponentRegistry { + protected static readonly _logger = createLogger('ComponentStorage'); + private static componentTypes = new Map(); + private static componentNameToType = new Map(); + private static componentNameToId = new Map(); + private static maskCache = new Map(); + private static nextBitIndex = 0; + private static maxComponents = 64; // 支持最多64种组件类型 + + /** + * 注册组件类型并分配位掩码 + * @param componentType 组件类型 + * @returns 分配的位索引 + */ + public static register(componentType: ComponentType): number { + if (this.componentTypes.has(componentType)) { + return this.componentTypes.get(componentType)!; + } + + if (this.nextBitIndex >= this.maxComponents) { + throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`); + } + + const bitIndex = this.nextBitIndex++; + this.componentTypes.set(componentType, bitIndex); + this.componentNameToType.set(componentType.name, componentType); + this.componentNameToId.set(componentType.name, bitIndex); + return bitIndex; + } + + /** + * 获取组件类型的位掩码 + * @param componentType 组件类型 + * @returns 位掩码 + */ + public static getBitMask(componentType: ComponentType): IBigIntLike { + const bitIndex = this.componentTypes.get(componentType); + if (bitIndex === undefined) { + throw new Error(`Component type ${componentType.name} is not registered`); + } + return BigIntFactory.one().shiftLeft(bitIndex); + } + + /** + * 获取组件类型的位索引 + * @param componentType 组件类型 + * @returns 位索引 + */ + public static getBitIndex(componentType: ComponentType): number { + const bitIndex = this.componentTypes.get(componentType); + if (bitIndex === undefined) { + throw new Error(`Component type ${componentType.name} is not registered`); + } + return bitIndex; + } + + /** + * 检查组件类型是否已注册 + * @param componentType 组件类型 + * @returns 是否已注册 + */ + public static isRegistered(componentType: ComponentType): boolean { + return this.componentTypes.has(componentType); + } + + /** + * 通过名称获取组件类型 + * @param componentName 组件名称 + * @returns 组件类型构造函数 + */ + public static getComponentType(componentName: string): Function | null { + return this.componentNameToType.get(componentName) || null; + } + + /** + * 获取所有已注册的组件类型 + * @returns 组件类型映射 + */ + public static getAllRegisteredTypes(): Map { + return new Map(this.componentTypes); + } + + /** + * 获取所有组件名称到类型的映射 + * @returns 名称到类型的映射 + */ + public static getAllComponentNames(): Map { + return new Map(this.componentNameToType); + } + + /** + * 通过名称获取组件类型ID + * @param componentName 组件名称 + * @returns 组件类型ID + */ + public static getComponentId(componentName: string): number | undefined { + return this.componentNameToId.get(componentName); + } + + /** + * 注册组件类型(通过名称) + * @param componentName 组件名称 + * @returns 分配的组件ID + */ + public static registerComponentByName(componentName: string): number { + if (this.componentNameToId.has(componentName)) { + return this.componentNameToId.get(componentName)!; + } + + if (this.nextBitIndex >= this.maxComponents) { + throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`); + } + + const bitIndex = this.nextBitIndex++; + this.componentNameToId.set(componentName, bitIndex); + return bitIndex; + } + + /** + * 创建单个组件的掩码 + * @param componentName 组件名称 + * @returns 组件掩码 + */ + public static createSingleComponentMask(componentName: string): IBigIntLike { + const cacheKey = `single:${componentName}`; + + if (this.maskCache.has(cacheKey)) { + return this.maskCache.get(cacheKey)!; + } + + const componentId = this.getComponentId(componentName); + if (componentId === undefined) { + throw new Error(`Component type ${componentName} is not registered`); + } + + const mask = BigIntFactory.one().shiftLeft(componentId); + this.maskCache.set(cacheKey, mask); + return mask; + } + + /** + * 创建多个组件的掩码 + * @param componentNames 组件名称数组 + * @returns 组合掩码 + */ + public static createComponentMask(componentNames: string[]): IBigIntLike { + const sortedNames = [...componentNames].sort(); + const cacheKey = `multi:${sortedNames.join(',')}`; + + if (this.maskCache.has(cacheKey)) { + return this.maskCache.get(cacheKey)!; + } + + let mask = BigIntFactory.zero(); + for (const name of componentNames) { + const componentId = this.getComponentId(name); + if (componentId !== undefined) { + mask = mask.or(BigIntFactory.one().shiftLeft(componentId)); + } + } + + this.maskCache.set(cacheKey, mask); + return mask; + } + + /** + * 清除掩码缓存 + */ + public static clearMaskCache(): void { + this.maskCache.clear(); + } + + /** + * 重置注册表(用于测试) + */ + public static reset(): void { + this.componentTypes.clear(); + this.componentNameToType.clear(); + this.componentNameToId.clear(); + this.maskCache.clear(); + this.nextBitIndex = 0; + } +} \ No newline at end of file diff --git a/packages/core/src/ECS/Core/DirtyTrackingSystem.ts b/packages/core/src/ECS/Core/DirtyTrackingSystem.ts index 6b0f6c30..a5df81ea 100644 --- a/packages/core/src/ECS/Core/DirtyTrackingSystem.ts +++ b/packages/core/src/ECS/Core/DirtyTrackingSystem.ts @@ -1,6 +1,7 @@ import { Entity } from '../Entity'; import { Component } from '../Component'; import { ComponentType } from './ComponentStorage'; +import { createLogger } from '../../Utils/Logger'; /** * 脏标记类型 @@ -89,7 +90,7 @@ export interface DirtyStats { * dirtySystem.addListener({ * flags: DirtyFlag.TRANSFORM_CHANGED, * callback: (data) => { - * console.log('Entity position changed:', data.entity.name); + * logger.debug('Entity position changed:', data.entity.name); * } * }); * @@ -98,6 +99,7 @@ export interface DirtyStats { * ``` */ export class DirtyTrackingSystem { + private static readonly _logger = createLogger('DirtyTrackingSystem'); /** 脏实体映射表 */ private _dirtyEntities = new Map(); @@ -329,7 +331,7 @@ export class DirtyTrackingSystem { try { listener.callback(dirtyData); } catch (error) { - console.error('脏数据监听器错误:', error); + DirtyTrackingSystem._logger.error('脏数据监听器错误:', error); } } } @@ -346,7 +348,7 @@ export class DirtyTrackingSystem { try { listener.callback(dirtyData); } catch (error) { - console.error('脏数据监听器通知错误:', error); + DirtyTrackingSystem._logger.error('脏数据监听器通知错误:', error); } } } diff --git a/packages/core/src/ECS/Core/EventBus.ts b/packages/core/src/ECS/Core/EventBus.ts index 4866f90a..220f8f7c 100644 --- a/packages/core/src/ECS/Core/EventBus.ts +++ b/packages/core/src/ECS/Core/EventBus.ts @@ -9,6 +9,7 @@ import { ISceneEventData, IPerformanceEventData } from '../../Types'; +import { createLogger } from '../../Utils/Logger'; import { TypeSafeEventSystem, EventListenerConfig, @@ -26,6 +27,7 @@ import { * 基于TypeSafeEventSystem,提供类型安全的事件发布订阅机制 */ export class EventBus implements IEventBus { + private static readonly _logger = createLogger('EventBus'); private eventSystem: TypeSafeEventSystem; private eventIdCounter = 0; private isDebugMode = false; @@ -47,7 +49,7 @@ export class EventBus implements IEventBus { const enhancedData = this.enhanceEventData(eventType, data); if (this.isDebugMode) { - console.log(`[EventBus] 发射事件: ${eventType}`, enhancedData); + EventBus._logger.info(`发射事件: ${eventType}`, enhancedData); } this.eventSystem.emitSync(eventType, enhancedData); @@ -65,7 +67,7 @@ export class EventBus implements IEventBus { const enhancedData = this.enhanceEventData(eventType, data); if (this.isDebugMode) { - console.log(`[EventBus] 发射异步事件: ${eventType}`, enhancedData); + EventBus._logger.info(`发射异步事件: ${eventType}`, enhancedData); } await this.eventSystem.emit(eventType, enhancedData); @@ -93,7 +95,7 @@ export class EventBus implements IEventBus { }; if (this.isDebugMode) { - console.log(`[EventBus] 添加监听器: ${eventType}`, eventConfig); + EventBus._logger.info(`添加监听器: ${eventType}`, eventConfig); } return this.eventSystem.on(eventType, handler, eventConfig); @@ -136,7 +138,7 @@ export class EventBus implements IEventBus { */ public off(eventType: string, listenerId: string): boolean { if (this.isDebugMode) { - console.log(`[EventBus] 移除监听器: ${listenerId} 事件: ${eventType}`); + EventBus._logger.info(`移除监听器: ${listenerId} 事件: ${eventType}`); } return this.eventSystem.off(eventType, listenerId); @@ -148,7 +150,7 @@ export class EventBus implements IEventBus { */ public offAll(eventType: string): void { if (this.isDebugMode) { - console.log(`[EventBus] 移除所有监听器: ${eventType}`); + EventBus._logger.info(`移除所有监听器: ${eventType}`); } this.eventSystem.offAll(eventType); @@ -186,7 +188,7 @@ export class EventBus implements IEventBus { */ public clear(): void { if (this.isDebugMode) { - console.log('[EventBus] 清空所有监听器'); + EventBus._logger.info('清空所有监听器'); } this.eventSystem.clear(); @@ -379,7 +381,7 @@ export class EventBus implements IEventBus { private validateEventType(eventType: string): void { if (!EventTypeValidator.isValid(eventType)) { if (this.isDebugMode) { - console.warn(`[EventBus] 未知事件类型: ${eventType}`); + EventBus._logger.warn(`未知事件类型: ${eventType}`); } // 在调试模式下添加自定义事件类型 if (this.isDebugMode) { diff --git a/packages/core/src/ECS/Core/EventSystem.ts b/packages/core/src/ECS/Core/EventSystem.ts index 819f35d4..a8e328ed 100644 --- a/packages/core/src/ECS/Core/EventSystem.ts +++ b/packages/core/src/ECS/Core/EventSystem.ts @@ -1,3 +1,5 @@ +import { createLogger } from '../../Utils/Logger'; + /** * 事件处理器函数类型 */ @@ -66,6 +68,7 @@ export interface EventBatchConfig { * 支持同步/异步事件、优先级、批处理等功能 */ export class TypeSafeEventSystem { + private static readonly _logger = createLogger('EventSystem'); private listeners = new Map(); private stats = new Map(); private batchQueue = new Map(); @@ -204,7 +207,7 @@ export class TypeSafeEventSystem { toRemove.push(listener.id); } } catch (error) { - console.error(`事件处理器执行错误 ${eventType}:`, error); + TypeSafeEventSystem._logger.error(`事件处理器执行错误 ${eventType}:`, error); } } @@ -336,7 +339,7 @@ export class TypeSafeEventSystem { // 检查监听器数量限制 if (listeners.length >= this.maxListeners) { - console.warn(`事件类型 ${eventType} 的监听器数量超过最大限制 (${this.maxListeners})`); + TypeSafeEventSystem._logger.warn(`事件类型 ${eventType} 的监听器数量超过最大限制 (${this.maxListeners})`); return ''; } @@ -392,7 +395,7 @@ export class TypeSafeEventSystem { toRemove.push(listener.id); } } catch (error) { - console.error(`同步事件处理器执行错误 ${eventType}:`, error); + TypeSafeEventSystem._logger.error(`同步事件处理器执行错误 ${eventType}:`, error); } } @@ -409,7 +412,7 @@ export class TypeSafeEventSystem { toRemove.push(listener.id); } } catch (error) { - console.error(`异步事件处理器执行错误 ${eventType}:`, error); + TypeSafeEventSystem._logger.error(`异步事件处理器执行错误 ${eventType}:`, error); } }); diff --git a/packages/core/src/ECS/Core/FluentAPI.ts b/packages/core/src/ECS/Core/FluentAPI.ts index 4ef6b735..80d223f8 100644 --- a/packages/core/src/ECS/Core/FluentAPI.ts +++ b/packages/core/src/ECS/Core/FluentAPI.ts @@ -1,638 +1,11 @@ -import { Entity } from '../Entity'; -import { Component } from '../Component'; -import { Scene } from '../Scene'; -import { ComponentType, ComponentStorageManager } from './ComponentStorage'; -import { QuerySystem, QueryBuilder } from './QuerySystem'; -import { TypeSafeEventSystem } from './EventSystem'; -import { EntitySystem } from '../Systems/EntitySystem'; - -/** - * 实体构建器 - 提供流式API创建和配置实体 - */ -export class EntityBuilder { - private entity: Entity; - private scene: Scene; - private storageManager: ComponentStorageManager; - - constructor(scene: Scene, storageManager: ComponentStorageManager) { - this.scene = scene; - this.storageManager = storageManager; - this.entity = new Entity("", scene.identifierPool.checkOut()); - } - - /** - * 设置实体名称 - * @param name 实体名称 - * @returns 实体构建器 - */ - public named(name: string): EntityBuilder { - this.entity.name = name; - return this; - } - - /** - * 设置实体标签 - * @param tag 标签 - * @returns 实体构建器 - */ - public tagged(tag: number): EntityBuilder { - this.entity.tag = tag; - return this; - } - - /** - * 添加组件 - * @param component 组件实例 - * @returns 实体构建器 - */ - public with(component: T): EntityBuilder { - this.entity.addComponent(component); - return this; - } - - /** - * 添加多个组件 - * @param components 组件数组 - * @returns 实体构建器 - */ - public withComponents(...components: Component[]): EntityBuilder { - for (const component of components) { - this.entity.addComponent(component); - } - return this; - } - - /** - * 条件性添加组件 - * @param condition 条件 - * @param component 组件实例 - * @returns 实体构建器 - */ - public withIf(condition: boolean, component: T): EntityBuilder { - if (condition) { - this.entity.addComponent(component); - } - return this; - } - - /** - * 使用工厂函数创建并添加组件 - * @param factory 组件工厂函数 - * @returns 实体构建器 - */ - public withFactory(factory: () => T): EntityBuilder { - const component = factory(); - this.entity.addComponent(component); - return this; - } - - /** - * 配置组件属性 - * @param componentType 组件类型 - * @param configurator 配置函数 - * @returns 实体构建器 - */ - public configure( - componentType: ComponentType, - configurator: (component: T) => void - ): EntityBuilder { - const component = this.entity.getComponent(componentType); - if (component) { - configurator(component); - } - return this; - } - - /** - * 设置实体为启用状态 - * @param enabled 是否启用 - * @returns 实体构建器 - */ - public enabled(enabled: boolean = true): EntityBuilder { - this.entity.enabled = enabled; - return this; - } - - /** - * 设置实体为活跃状态 - * @param active 是否活跃 - * @returns 实体构建器 - */ - public active(active: boolean = true): EntityBuilder { - this.entity.active = active; - return this; - } - - /** - * 添加子实体 - * @param childBuilder 子实体构建器 - * @returns 实体构建器 - */ - public withChild(childBuilder: EntityBuilder): EntityBuilder { - const child = childBuilder.build(); - this.entity.addChild(child); - return this; - } - - /** - * 批量添加子实体 - * @param childBuilders 子实体构建器数组 - * @returns 实体构建器 - */ - public withChildren(...childBuilders: EntityBuilder[]): EntityBuilder { - for (const childBuilder of childBuilders) { - const child = childBuilder.build(); - this.entity.addChild(child); - } - return this; - } - - /** - * 使用工厂函数创建子实体 - * @param childFactory 子实体工厂函数 - * @returns 实体构建器 - */ - public withChildFactory(childFactory: (parent: Entity) => EntityBuilder): EntityBuilder { - const childBuilder = childFactory(this.entity); - const child = childBuilder.build(); - this.entity.addChild(child); - return this; - } - - /** - * 条件性添加子实体 - * @param condition 条件 - * @param childBuilder 子实体构建器 - * @returns 实体构建器 - */ - public withChildIf(condition: boolean, childBuilder: EntityBuilder): EntityBuilder { - if (condition) { - const child = childBuilder.build(); - this.entity.addChild(child); - } - return this; - } - - /** - * 构建并返回实体 - * @returns 构建的实体 - */ - public build(): Entity { - return this.entity; - } - - /** - * 构建实体并添加到场景 - * @returns 构建的实体 - */ - public spawn(): Entity { - this.scene.addEntity(this.entity); - return this.entity; - } - - /** - * 克隆当前构建器 - * @returns 新的实体构建器 - */ - public clone(): EntityBuilder { - const newBuilder = new EntityBuilder(this.scene, this.storageManager); - // 这里需要深度克隆实体,简化实现 - newBuilder.entity = this.entity; // 实际应该是深度克隆 - return newBuilder; - } -} - -/** - * 场景构建器 - 提供流式API创建和配置场景 - */ -export class SceneBuilder { - private scene: Scene; - - constructor() { - this.scene = new Scene(); - } - - /** - * 设置场景名称 - * @param name 场景名称 - * @returns 场景构建器 - */ - public named(name: string): SceneBuilder { - this.scene.name = name; - return this; - } - - /** - * 添加实体 - * @param entity 实体 - * @returns 场景构建器 - */ - public withEntity(entity: Entity): SceneBuilder { - this.scene.addEntity(entity); - return this; - } - - /** - * 使用实体构建器添加实体 - * @param builderFn 实体构建器函数 - * @returns 场景构建器 - */ - public withEntityBuilder(builderFn: (builder: EntityBuilder) => EntityBuilder): SceneBuilder { - const builder = new EntityBuilder(this.scene, this.scene.componentStorageManager); - const configuredBuilder = builderFn(builder); - const entity = configuredBuilder.build(); - this.scene.addEntity(entity); - return this; - } - - /** - * 批量添加实体 - * @param entities 实体数组 - * @returns 场景构建器 - */ - public withEntities(...entities: Entity[]): SceneBuilder { - for (const entity of entities) { - this.scene.addEntity(entity); - } - return this; - } - - /** - * 添加系统 - * @param system 系统实例 - * @returns 场景构建器 - */ - public withSystem(system: EntitySystem): SceneBuilder { - this.scene.addSystem(system); - return this; - } - - /** - * 批量添加系统 - * @param systems 系统数组 - * @returns 场景构建器 - */ - public withSystems(...systems: EntitySystem[]): SceneBuilder { - for (const system of systems) { - this.scene.addSystem(system); - } - return this; - } - - /** - * 构建并返回场景 - * @returns 构建的场景 - */ - public build(): Scene { - return this.scene; - } -} - -/** - * 组件构建器 - 提供流式API创建组件 - */ -export class ComponentBuilder { - private component: T; - - constructor(componentClass: new (...args: unknown[]) => T, ...args: unknown[]) { - this.component = new componentClass(...args); - } - - /** - * 设置组件属性 - * @param property 属性名 - * @param value 属性值 - * @returns 组件构建器 - */ - public set(property: K, value: T[K]): ComponentBuilder { - this.component[property] = value; - return this; - } - - /** - * 使用配置函数设置组件 - * @param configurator 配置函数 - * @returns 组件构建器 - */ - public configure(configurator: (component: T) => void): ComponentBuilder { - configurator(this.component); - return this; - } - - /** - * 条件性设置属性 - * @param condition 条件 - * @param property 属性名 - * @param value 属性值 - * @returns 组件构建器 - */ - public setIf(condition: boolean, property: K, value: T[K]): ComponentBuilder { - if (condition) { - this.component[property] = value; - } - return this; - } - - /** - * 构建并返回组件 - * @returns 构建的组件 - */ - public build(): T { - return this.component; - } -} - -/** - * ECS流式API主入口 - * 提供统一的流式接口 - */ -export class ECSFluentAPI { - private scene: Scene; - private querySystem: QuerySystem; - private eventSystem: TypeSafeEventSystem; - - constructor(scene: Scene, querySystem: QuerySystem, eventSystem: TypeSafeEventSystem) { - this.scene = scene; - this.querySystem = querySystem; - this.eventSystem = eventSystem; - } - - /** - * 创建实体构建器 - * @returns 实体构建器 - */ - public createEntity(): EntityBuilder { - return new EntityBuilder(this.scene, this.scene.componentStorageManager); - } - - /** - * 创建场景构建器 - * @returns 场景构建器 - */ - public createScene(): SceneBuilder { - return new SceneBuilder(); - } - - /** - * 创建组件构建器 - * @param componentClass 组件类 - * @param args 构造参数 - * @returns 组件构建器 - */ - public createComponent( - componentClass: new (...args: unknown[]) => T, - ...args: unknown[] - ): ComponentBuilder { - return new ComponentBuilder(componentClass, ...args); - } - - /** - * 创建查询构建器 - * @returns 查询构建器 - */ - public query(): QueryBuilder { - return new QueryBuilder(this.querySystem); - } - - /** - * 查找实体(简化版) - * @param componentTypes 组件类型 - * @returns 实体数组 - */ - public find(...componentTypes: ComponentType[]): Entity[] { - return this.querySystem.queryAll(...componentTypes).entities; - } - - /** - * 查找第一个匹配的实体 - * @param componentTypes 组件类型 - * @returns 实体或null - */ - public findFirst(...componentTypes: ComponentType[]): Entity | null { - const result = this.querySystem.queryAll(...componentTypes); - return result.entities.length > 0 ? result.entities[0] : null; - } - - /** - * 按名称查找实体 - * @param name 实体名称 - * @returns 实体或null - */ - public findByName(name: string): Entity | null { - return this.scene.getEntityByName(name); - } - - /** - * 按标签查找实体 - * @param tag 标签 - * @returns 实体数组 - */ - public findByTag(tag: number): Entity[] { - return this.scene.getEntitiesByTag(tag); - } - - /** - * 触发事件 - * @param eventType 事件类型 - * @param event 事件数据 - */ - public emit(eventType: string, event: T): void { - this.eventSystem.emitSync(eventType, event); - } - - /** - * 异步触发事件 - * @param eventType 事件类型 - * @param event 事件数据 - */ - public async emitAsync(eventType: string, event: T): Promise { - await this.eventSystem.emit(eventType, event); - } - - /** - * 监听事件 - * @param eventType 事件类型 - * @param handler 事件处理器 - * @returns 监听器ID - */ - public on(eventType: string, handler: (event: T) => void): string { - return this.eventSystem.on(eventType, handler); - } - - /** - * 一次性监听事件 - * @param eventType 事件类型 - * @param handler 事件处理器 - * @returns 监听器ID - */ - public once(eventType: string, handler: (event: T) => void): string { - return this.eventSystem.once(eventType, handler); - } - - /** - * 移除事件监听器 - * @param eventType 事件类型 - * @param listenerId 监听器ID - */ - public off(eventType: string, listenerId: string): void { - this.eventSystem.off(eventType, listenerId); - } - - /** - * 批量操作实体 - * @param entities 实体数组 - * @returns 批量操作器 - */ - public batch(entities: Entity[]): EntityBatchOperator { - return new EntityBatchOperator(entities); - } - - /** - * 获取场景统计信息 - * @returns 统计信息 - */ - public getStats(): { - entityCount: number; - systemCount: number; - componentStats: Map; - queryStats: unknown; - eventStats: Map; - } { - return { - entityCount: this.scene.entities.count, - systemCount: this.scene.systems.length, - componentStats: this.scene.componentStorageManager.getAllStats(), - queryStats: this.querySystem.getStats(), - eventStats: this.eventSystem.getStats() as Map - }; - } -} - -/** - * 实体批量操作器 - * 提供对多个实体的批量操作 - */ -export class EntityBatchOperator { - private entities: Entity[]; - - constructor(entities: Entity[]) { - this.entities = entities; - } - - /** - * 批量添加组件 - * @param component 组件实例 - * @returns 批量操作器 - */ - public addComponent(component: T): EntityBatchOperator { - for (const entity of this.entities) { - entity.addComponent(component); - } - return this; - } - - /** - * 批量移除组件 - * @param componentType 组件类型 - * @returns 批量操作器 - */ - public removeComponent(componentType: ComponentType): EntityBatchOperator { - for (const entity of this.entities) { - entity.removeComponentByType(componentType); - } - return this; - } - - /** - * 批量设置活跃状态 - * @param active 是否活跃 - * @returns 批量操作器 - */ - public setActive(active: boolean): EntityBatchOperator { - for (const entity of this.entities) { - entity.active = active; - } - return this; - } - - /** - * 批量设置标签 - * @param tag 标签 - * @returns 批量操作器 - */ - public setTag(tag: number): EntityBatchOperator { - for (const entity of this.entities) { - entity.tag = tag; - } - return this; - } - - /** - * 批量执行操作 - * @param operation 操作函数 - * @returns 批量操作器 - */ - public forEach(operation: (entity: Entity, index: number) => void): EntityBatchOperator { - this.entities.forEach(operation); - return this; - } - - /** - * 过滤实体 - * @param predicate 过滤条件 - * @returns 新的批量操作器 - */ - public filter(predicate: (entity: Entity) => boolean): EntityBatchOperator { - return new EntityBatchOperator(this.entities.filter(predicate)); - } - - /** - * 获取实体数组 - * @returns 实体数组 - */ - public toArray(): Entity[] { - return this.entities.slice(); - } - - /** - * 获取实体数量 - * @returns 实体数量 - */ - public count(): number { - return this.entities.length; - } -} - -/** - * 创建ECS流式API实例 - * @param scene 场景 - * @param querySystem 查询系统 - * @param eventSystem 事件系统 - * @returns ECS流式API实例 - */ -export function createECSAPI( - scene: Scene, - querySystem: QuerySystem, - eventSystem: TypeSafeEventSystem -): ECSFluentAPI { - return new ECSFluentAPI(scene, querySystem, eventSystem); -} - -/** - * 全局ECS流式API实例(需要在使用前初始化) - */ -export let ECS: ECSFluentAPI; - -/** - * 初始化全局ECS API - * @param scene 场景 - * @param querySystem 查询系统 - * @param eventSystem 事件系统 - */ -export function initializeECS( - scene: Scene, - querySystem: QuerySystem, - eventSystem: TypeSafeEventSystem -): void { - ECS = createECSAPI(scene, querySystem, eventSystem); -} \ No newline at end of file +// 重新导出拆分后的模块以保持向后兼容性 +export { + EntityBuilder, + SceneBuilder, + ComponentBuilder, + EntityBatchOperator, + ECSFluentAPI, + createECSAPI, + initializeECS, + ECS +} from './FluentAPI/index'; \ No newline at end of file diff --git a/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts b/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts new file mode 100644 index 00000000..5040232c --- /dev/null +++ b/packages/core/src/ECS/Core/FluentAPI/ComponentBuilder.ts @@ -0,0 +1,55 @@ +import { Component } from '../../Component'; + +/** + * 组件构建器 - 提供流式API创建组件 + */ +export class ComponentBuilder { + private component: T; + + constructor(componentClass: new (...args: unknown[]) => T, ...args: unknown[]) { + this.component = new componentClass(...args); + } + + /** + * 设置组件属性 + * @param property 属性名 + * @param value 属性值 + * @returns 组件构建器 + */ + public set(property: K, value: T[K]): ComponentBuilder { + this.component[property] = value; + return this; + } + + /** + * 使用配置函数设置组件 + * @param configurator 配置函数 + * @returns 组件构建器 + */ + public configure(configurator: (component: T) => void): ComponentBuilder { + configurator(this.component); + return this; + } + + /** + * 条件性设置属性 + * @param condition 条件 + * @param property 属性名 + * @param value 属性值 + * @returns 组件构建器 + */ + public setIf(condition: boolean, property: K, value: T[K]): ComponentBuilder { + if (condition) { + this.component[property] = value; + } + return this; + } + + /** + * 构建并返回组件 + * @returns 构建的组件 + */ + 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 new file mode 100644 index 00000000..fb6ea5bb --- /dev/null +++ b/packages/core/src/ECS/Core/FluentAPI/ECSFluentAPI.ts @@ -0,0 +1,210 @@ +import { Entity } from '../../Entity'; +import { Component } from '../../Component'; +import { Scene } from '../../Scene'; +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主入口 + * 提供统一的流式接口 + */ +export class ECSFluentAPI { + private scene: Scene; + private querySystem: QuerySystem; + private eventSystem: TypeSafeEventSystem; + + constructor(scene: Scene, querySystem: QuerySystem, eventSystem: TypeSafeEventSystem) { + this.scene = scene; + this.querySystem = querySystem; + this.eventSystem = eventSystem; + } + + /** + * 创建实体构建器 + * @returns 实体构建器 + */ + public createEntity(): EntityBuilder { + return new EntityBuilder(this.scene, this.scene.componentStorageManager); + } + + /** + * 创建场景构建器 + * @returns 场景构建器 + */ + public createScene(): SceneBuilder { + return new SceneBuilder(); + } + + /** + * 创建组件构建器 + * @param componentClass 组件类 + * @param args 构造参数 + * @returns 组件构建器 + */ + public createComponent( + componentClass: new (...args: unknown[]) => T, + ...args: unknown[] + ): ComponentBuilder { + return new ComponentBuilder(componentClass, ...args); + } + + /** + * 创建查询构建器 + * @returns 查询构建器 + */ + public query(): QueryBuilder { + return new QueryBuilder(this.querySystem); + } + + /** + * 查找实体(简化版) + * @param componentTypes 组件类型 + * @returns 实体数组 + */ + public find(...componentTypes: ComponentType[]): Entity[] { + return this.querySystem.queryAll(...componentTypes).entities; + } + + /** + * 查找第一个匹配的实体 + * @param componentTypes 组件类型 + * @returns 实体或null + */ + public findFirst(...componentTypes: ComponentType[]): Entity | null { + const result = this.querySystem.queryAll(...componentTypes); + return result.entities.length > 0 ? result.entities[0] : null; + } + + /** + * 按名称查找实体 + * @param name 实体名称 + * @returns 实体或null + */ + public findByName(name: string): Entity | null { + return this.scene.getEntityByName(name); + } + + /** + * 按标签查找实体 + * @param tag 标签 + * @returns 实体数组 + */ + public findByTag(tag: number): Entity[] { + return this.scene.getEntitiesByTag(tag); + } + + /** + * 触发事件 + * @param eventType 事件类型 + * @param event 事件数据 + */ + public emit(eventType: string, event: T): void { + this.eventSystem.emitSync(eventType, event); + } + + /** + * 异步触发事件 + * @param eventType 事件类型 + * @param event 事件数据 + */ + public async emitAsync(eventType: string, event: T): Promise { + await this.eventSystem.emit(eventType, event); + } + + /** + * 监听事件 + * @param eventType 事件类型 + * @param handler 事件处理器 + * @returns 监听器ID + */ + public on(eventType: string, handler: (event: T) => void): string { + return this.eventSystem.on(eventType, handler); + } + + /** + * 一次性监听事件 + * @param eventType 事件类型 + * @param handler 事件处理器 + * @returns 监听器ID + */ + public once(eventType: string, handler: (event: T) => void): string { + return this.eventSystem.once(eventType, handler); + } + + /** + * 移除事件监听器 + * @param eventType 事件类型 + * @param listenerId 监听器ID + */ + public off(eventType: string, listenerId: string): void { + this.eventSystem.off(eventType, listenerId); + } + + /** + * 批量操作实体 + * @param entities 实体数组 + * @returns 批量操作器 + */ + public batch(entities: Entity[]): EntityBatchOperator { + return new EntityBatchOperator(entities); + } + + /** + * 获取场景统计信息 + * @returns 统计信息 + */ + public getStats(): { + entityCount: number; + systemCount: number; + componentStats: Map; + queryStats: unknown; + eventStats: Map; + } { + return { + entityCount: this.scene.entities.count, + systemCount: this.scene.systems.length, + componentStats: this.scene.componentStorageManager.getAllStats(), + queryStats: this.querySystem.getStats(), + eventStats: this.eventSystem.getStats() as Map + }; + } +} + +/** + * 创建ECS流式API实例 + * @param scene 场景 + * @param querySystem 查询系统 + * @param eventSystem 事件系统 + * @returns ECS流式API实例 + */ +export function createECSAPI( + scene: Scene, + querySystem: QuerySystem, + eventSystem: TypeSafeEventSystem +): ECSFluentAPI { + return new ECSFluentAPI(scene, querySystem, eventSystem); +} + +/** + * 全局ECS流式API实例(需要在使用前初始化) + */ +export let ECS: ECSFluentAPI; + +/** + * 初始化全局ECS API + * @param scene 场景 + * @param querySystem 查询系统 + * @param eventSystem 事件系统 + */ +export function initializeECS( + scene: Scene, + 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 new file mode 100644 index 00000000..4d08217d --- /dev/null +++ b/packages/core/src/ECS/Core/FluentAPI/EntityBatchOperator.ts @@ -0,0 +1,98 @@ +import { Entity } from '../../Entity'; +import { Component } from '../../Component'; +import { ComponentType } from '../ComponentStorage'; + +/** + * 实体批量操作器 + * 提供对多个实体的批量操作 + */ +export class EntityBatchOperator { + private entities: Entity[]; + + constructor(entities: Entity[]) { + this.entities = entities; + } + + /** + * 批量添加组件 + * @param component 组件实例 + * @returns 批量操作器 + */ + public addComponent(component: T): EntityBatchOperator { + for (const entity of this.entities) { + entity.addComponent(component); + } + return this; + } + + /** + * 批量移除组件 + * @param componentType 组件类型 + * @returns 批量操作器 + */ + public removeComponent(componentType: ComponentType): EntityBatchOperator { + for (const entity of this.entities) { + entity.removeComponentByType(componentType); + } + return this; + } + + /** + * 批量设置活跃状态 + * @param active 是否活跃 + * @returns 批量操作器 + */ + public setActive(active: boolean): EntityBatchOperator { + for (const entity of this.entities) { + entity.active = active; + } + return this; + } + + /** + * 批量设置标签 + * @param tag 标签 + * @returns 批量操作器 + */ + public setTag(tag: number): EntityBatchOperator { + for (const entity of this.entities) { + entity.tag = tag; + } + return this; + } + + /** + * 批量执行操作 + * @param operation 操作函数 + * @returns 批量操作器 + */ + public forEach(operation: (entity: Entity, index: number) => void): EntityBatchOperator { + this.entities.forEach(operation); + return this; + } + + /** + * 过滤实体 + * @param predicate 过滤条件 + * @returns 新的批量操作器 + */ + public filter(predicate: (entity: Entity) => boolean): EntityBatchOperator { + return new EntityBatchOperator(this.entities.filter(predicate)); + } + + /** + * 获取实体数组 + * @returns 实体数组 + */ + public toArray(): Entity[] { + return this.entities.slice(); + } + + /** + * 获取实体数量 + * @returns 实体数量 + */ + 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 new file mode 100644 index 00000000..3dc23017 --- /dev/null +++ b/packages/core/src/ECS/Core/FluentAPI/EntityBuilder.ts @@ -0,0 +1,200 @@ +import { Entity } from '../../Entity'; +import { Component } from '../../Component'; +import { Scene } from '../../Scene'; +import { ComponentType, ComponentStorageManager } from '../ComponentStorage'; + +/** + * 实体构建器 - 提供流式API创建和配置实体 + */ +export class EntityBuilder { + private entity: Entity; + private scene: Scene; + private storageManager: ComponentStorageManager; + + constructor(scene: Scene, storageManager: ComponentStorageManager) { + this.scene = scene; + this.storageManager = storageManager; + this.entity = new Entity("", scene.identifierPool.checkOut()); + } + + /** + * 设置实体名称 + * @param name 实体名称 + * @returns 实体构建器 + */ + public named(name: string): EntityBuilder { + this.entity.name = name; + return this; + } + + /** + * 设置实体标签 + * @param tag 标签 + * @returns 实体构建器 + */ + public tagged(tag: number): EntityBuilder { + this.entity.tag = tag; + return this; + } + + /** + * 添加组件 + * @param component 组件实例 + * @returns 实体构建器 + */ + public with(component: T): EntityBuilder { + this.entity.addComponent(component); + return this; + } + + /** + * 添加多个组件 + * @param components 组件数组 + * @returns 实体构建器 + */ + public withComponents(...components: Component[]): EntityBuilder { + for (const component of components) { + this.entity.addComponent(component); + } + return this; + } + + /** + * 条件性添加组件 + * @param condition 条件 + * @param component 组件实例 + * @returns 实体构建器 + */ + public withIf(condition: boolean, component: T): EntityBuilder { + if (condition) { + this.entity.addComponent(component); + } + return this; + } + + /** + * 使用工厂函数创建并添加组件 + * @param factory 组件工厂函数 + * @returns 实体构建器 + */ + public withFactory(factory: () => T): EntityBuilder { + const component = factory(); + this.entity.addComponent(component); + return this; + } + + /** + * 配置组件属性 + * @param componentType 组件类型 + * @param configurator 配置函数 + * @returns 实体构建器 + */ + public configure( + componentType: ComponentType, + configurator: (component: T) => void + ): EntityBuilder { + const component = this.entity.getComponent(componentType); + if (component) { + configurator(component); + } + return this; + } + + /** + * 设置实体为启用状态 + * @param enabled 是否启用 + * @returns 实体构建器 + */ + public enabled(enabled: boolean = true): EntityBuilder { + this.entity.enabled = enabled; + return this; + } + + /** + * 设置实体为活跃状态 + * @param active 是否活跃 + * @returns 实体构建器 + */ + public active(active: boolean = true): EntityBuilder { + this.entity.active = active; + return this; + } + + /** + * 添加子实体 + * @param childBuilder 子实体构建器 + * @returns 实体构建器 + */ + public withChild(childBuilder: EntityBuilder): EntityBuilder { + const child = childBuilder.build(); + this.entity.addChild(child); + return this; + } + + /** + * 批量添加子实体 + * @param childBuilders 子实体构建器数组 + * @returns 实体构建器 + */ + public withChildren(...childBuilders: EntityBuilder[]): EntityBuilder { + for (const childBuilder of childBuilders) { + const child = childBuilder.build(); + this.entity.addChild(child); + } + return this; + } + + /** + * 使用工厂函数创建子实体 + * @param childFactory 子实体工厂函数 + * @returns 实体构建器 + */ + public withChildFactory(childFactory: (parent: Entity) => EntityBuilder): EntityBuilder { + const childBuilder = childFactory(this.entity); + const child = childBuilder.build(); + this.entity.addChild(child); + return this; + } + + /** + * 条件性添加子实体 + * @param condition 条件 + * @param childBuilder 子实体构建器 + * @returns 实体构建器 + */ + public withChildIf(condition: boolean, childBuilder: EntityBuilder): EntityBuilder { + if (condition) { + const child = childBuilder.build(); + this.entity.addChild(child); + } + return this; + } + + /** + * 构建并返回实体 + * @returns 构建的实体 + */ + public build(): Entity { + return this.entity; + } + + /** + * 构建实体并添加到场景 + * @returns 构建的实体 + */ + public spawn(): Entity { + this.scene.addEntity(this.entity); + return this.entity; + } + + /** + * 克隆当前构建器 + * @returns 新的实体构建器 + */ + public clone(): EntityBuilder { + const newBuilder = new EntityBuilder(this.scene, this.storageManager); + // 这里需要深度克隆实体,简化实现 + 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 new file mode 100644 index 00000000..a8bc2489 --- /dev/null +++ b/packages/core/src/ECS/Core/FluentAPI/SceneBuilder.ts @@ -0,0 +1,90 @@ +import { Entity } from '../../Entity'; +import { Scene } from '../../Scene'; +import { EntitySystem } from '../../Systems/EntitySystem'; +import { EntityBuilder } from './EntityBuilder'; + +/** + * 场景构建器 - 提供流式API创建和配置场景 + */ +export class SceneBuilder { + private scene: Scene; + + constructor() { + this.scene = new Scene(); + } + + /** + * 设置场景名称 + * @param name 场景名称 + * @returns 场景构建器 + */ + public named(name: string): SceneBuilder { + this.scene.name = name; + return this; + } + + /** + * 添加实体 + * @param entity 实体 + * @returns 场景构建器 + */ + public withEntity(entity: Entity): SceneBuilder { + this.scene.addEntity(entity); + return this; + } + + /** + * 使用实体构建器添加实体 + * @param builderFn 实体构建器函数 + * @returns 场景构建器 + */ + public withEntityBuilder(builderFn: (builder: EntityBuilder) => EntityBuilder): SceneBuilder { + const builder = new EntityBuilder(this.scene, this.scene.componentStorageManager); + const configuredBuilder = builderFn(builder); + const entity = configuredBuilder.build(); + this.scene.addEntity(entity); + return this; + } + + /** + * 批量添加实体 + * @param entities 实体数组 + * @returns 场景构建器 + */ + public withEntities(...entities: Entity[]): SceneBuilder { + for (const entity of entities) { + this.scene.addEntity(entity); + } + return this; + } + + /** + * 添加系统 + * @param system 系统实例 + * @returns 场景构建器 + */ + public withSystem(system: EntitySystem): SceneBuilder { + this.scene.addSystem(system); + return this; + } + + /** + * 批量添加系统 + * @param systems 系统数组 + * @returns 场景构建器 + */ + public withSystems(...systems: EntitySystem[]): SceneBuilder { + for (const system of systems) { + this.scene.addSystem(system); + } + return this; + } + + /** + * 构建并返回场景 + * @returns 构建的场景 + */ + 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 new file mode 100644 index 00000000..84ffe4dd --- /dev/null +++ b/packages/core/src/ECS/Core/FluentAPI/index.ts @@ -0,0 +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 diff --git a/packages/core/src/ECS/Core/QuerySystem.ts b/packages/core/src/ECS/Core/QuerySystem.ts index acf48b84..05e06980 100644 --- a/packages/core/src/ECS/Core/QuerySystem.ts +++ b/packages/core/src/ECS/Core/QuerySystem.ts @@ -2,6 +2,7 @@ import { Entity } from '../Entity'; import { Component } from '../Component'; import { ComponentRegistry, ComponentType } from './ComponentStorage'; import { IBigIntLike, BigIntFactory } from '../Utils/BigIntCompatibility'; +import { createLogger } from '../../Utils/Logger'; import { ComponentPoolManager } from './ComponentPool'; import { ComponentIndexManager, IndexType } from './ComponentIndex'; @@ -82,6 +83,7 @@ interface QueryCacheEntry { * ``` */ export class QuerySystem { + private _logger = createLogger('QuerySystem'); private entities: Entity[] = []; private entityIndex: EntityIndex; private indexDirty = true; @@ -390,7 +392,7 @@ export class QuerySystem { * ```typescript * // 查询同时具有位置和速度组件的实体 * const result = querySystem.queryAll(PositionComponent, VelocityComponent); - * console.log(`找到 ${result.count} 个移动实体`); + * logger.info(`找到 ${result.count} 个移动实体`); * ``` */ public queryAll(...componentTypes: ComponentType[]): QueryResult { @@ -502,7 +504,7 @@ export class QuerySystem { * ```typescript * // 查询具有武器或护甲组件的实体 * const result = querySystem.queryAny(WeaponComponent, ArmorComponent); - * console.log(`找到 ${result.count} 个装备实体`); + * logger.info(`找到 ${result.count} 个装备实体`); * ``` */ public queryAny(...componentTypes: ComponentType[]): QueryResult { @@ -560,7 +562,7 @@ export class QuerySystem { * ```typescript * // 查询不具有AI和玩家控制组件的实体(如静态物体) * const result = querySystem.queryNone(AIComponent, PlayerControlComponent); - * console.log(`找到 ${result.count} 个静态实体`); + * logger.info(`找到 ${result.count} 个静态实体`); * ``` */ public queryNone(...componentTypes: ComponentType[]): QueryResult { @@ -878,7 +880,7 @@ export class QuerySystem { mask = mask.or(bitMask); hasValidComponents = true; } catch (error) { - console.warn(`组件类型 ${type.name} 未注册,跳过`); + this._logger.warn(`组件类型 ${type.name} 未注册,跳过`); } } @@ -1054,6 +1056,7 @@ export class QuerySystem { * ``` */ export class QueryBuilder { + private _logger = createLogger('QueryBuilder'); private conditions: QueryCondition[] = []; private querySystem: QuerySystem; @@ -1148,7 +1151,7 @@ export class QueryBuilder { const bitMask = ComponentRegistry.getBitMask(type); mask = mask.or(bitMask); } catch (error) { - console.warn(`组件类型 ${type.name} 未注册,跳过`); + this._logger.warn(`组件类型 ${type.name} 未注册,跳过`); } } return mask; diff --git a/packages/core/src/ECS/Core/SoAStorage.ts b/packages/core/src/ECS/Core/SoAStorage.ts index e73b2036..8aa56ee8 100644 --- a/packages/core/src/ECS/Core/SoAStorage.ts +++ b/packages/core/src/ECS/Core/SoAStorage.ts @@ -1,5 +1,6 @@ import { Component } from '../Component'; import { ComponentType } from './ComponentStorage'; +import { createLogger } from '../../Utils/Logger'; /** * 启用SoA优化装饰器 @@ -113,6 +114,7 @@ export function DeepCopy(target: any, propertyKey: string | symbol): void { * 使用Structure of Arrays存储模式,在大规模批量操作时提供优异性能 */ export class SoAStorage { + private static readonly _logger = createLogger('SoAStorage'); private fields = new Map(); private stringFields = new Map(); // 专门存储字符串 private serializedFields = new Map(); // 序列化存储Map/Set/Array @@ -276,7 +278,7 @@ export class SoAStorage { return JSON.stringify(value); } } catch (error) { - console.warn(`SoA序列化字段 ${key} 失败:`, error); + SoAStorage._logger.warn(`SoA序列化字段 ${key} 失败:`, error); return '{}'; } } @@ -301,7 +303,7 @@ export class SoAStorage { return parsed; } } catch (error) { - console.warn(`SoA反序列化字段 ${key} 失败:`, error); + SoAStorage._logger.warn(`SoA反序列化字段 ${key} 失败:`, error); return null; } } diff --git a/packages/core/src/ECS/Entity.ts b/packages/core/src/ECS/Entity.ts index cb89fd05..2ddc0c39 100644 --- a/packages/core/src/ECS/Entity.ts +++ b/packages/core/src/ECS/Entity.ts @@ -2,6 +2,7 @@ import { Component } from './Component'; import { ComponentRegistry, ComponentType } from './Core/ComponentStorage'; import { EventBus } from './Core/EventBus'; import { IBigIntLike, BigIntFactory } from './Utils/BigIntCompatibility'; +import { createLogger } from '../Utils/Logger'; // Forward declaration to avoid circular dependency interface IScene { @@ -65,6 +66,11 @@ export class EntityComparer { * ``` */ export class Entity { + /** + * Entity专用日志器 + */ + private static _logger = createLogger('Entity'); + /** * 实体比较器实例 */ @@ -630,7 +636,7 @@ export class Entity { addedComponents.push(this.addComponent(component)); } catch (error) { // 如果某个组件添加失败,继续添加其他组件 - console.warn(`添加组件失败 ${component.constructor.name}:`, error); + Entity._logger.warn(`添加组件失败 ${component.constructor.name}:`, error); } } diff --git a/packages/core/src/ECS/Utils/EntityProcessorList.ts b/packages/core/src/ECS/Utils/EntityProcessorList.ts index 871d8163..e2f9bc28 100644 --- a/packages/core/src/ECS/Utils/EntityProcessorList.ts +++ b/packages/core/src/ECS/Utils/EntityProcessorList.ts @@ -1,10 +1,12 @@ import { EntitySystem } from '../Systems/EntitySystem'; +import { createLogger } from '../../Utils/Logger'; /** * 实体处理器列表管理器 * 管理场景中的所有实体系统 */ export class EntityProcessorList { + private static readonly _logger = createLogger('EntityProcessorList'); private _processors: EntitySystem[] = []; private _isDirty = false; @@ -73,7 +75,7 @@ export class EntityProcessorList { try { processor.update(); } catch (error) { - console.error(`Error in processor ${processor.constructor.name}:`, error); + EntityProcessorList._logger.error(`Error in processor ${processor.constructor.name}:`, error); } } } diff --git a/packages/network/src/Core/Logger.ts b/packages/core/src/Utils/Logger.ts similarity index 73% rename from packages/network/src/Core/Logger.ts rename to packages/core/src/Utils/Logger.ts index 8c622108..2914e897 100644 --- a/packages/network/src/Core/Logger.ts +++ b/packages/core/src/Utils/Logger.ts @@ -41,53 +41,100 @@ export interface LoggerConfig { * 默认控制台日志实现 */ export class ConsoleLogger implements ILogger { - private config: LoggerConfig; + private _config: LoggerConfig; constructor(config: Partial = {}) { - this.config = { + this._config = { level: LogLevel.Info, enableTimestamp: true, - enableColors: typeof window === 'undefined', // Node.js环境默认启用颜色 + enableColors: typeof window === 'undefined', ...config }; } + /** + * 输出调试级别日志 + * @param message 日志消息 + * @param args 附加参数 + */ public debug(message: string, ...args: unknown[]): void { this.log(LogLevel.Debug, message, ...args); } + /** + * 输出信息级别日志 + * @param message 日志消息 + * @param args 附加参数 + */ public info(message: string, ...args: unknown[]): void { this.log(LogLevel.Info, message, ...args); } + /** + * 输出警告级别日志 + * @param message 日志消息 + * @param args 附加参数 + */ public warn(message: string, ...args: unknown[]): void { this.log(LogLevel.Warn, message, ...args); } + /** + * 输出错误级别日志 + * @param message 日志消息 + * @param args 附加参数 + */ public error(message: string, ...args: unknown[]): void { this.log(LogLevel.Error, message, ...args); } + /** + * 输出致命错误级别日志 + * @param message 日志消息 + * @param args 附加参数 + */ public fatal(message: string, ...args: unknown[]): void { this.log(LogLevel.Fatal, message, ...args); } + /** + * 设置日志级别 + * @param level 日志级别 + */ + public setLevel(level: LogLevel): void { + this._config.level = level; + } + + /** + * 设置日志前缀 + * @param prefix 前缀字符串 + */ + public setPrefix(prefix: string): void { + this._config.prefix = prefix; + } + + /** + * 内部日志输出方法 + * @param level 日志级别 + * @param message 日志消息 + * @param args 附加参数 + */ private log(level: LogLevel, message: string, ...args: unknown[]): void { - if (level < this.config.level) { + if (level < this._config.level) { return; } let formattedMessage = message; // 添加时间戳 - if (this.config.enableTimestamp) { + if (this._config.enableTimestamp) { const timestamp = new Date().toISOString(); formattedMessage = `[${timestamp}] ${formattedMessage}`; } // 添加前缀 - if (this.config.prefix) { - formattedMessage = `[${this.config.prefix}] ${formattedMessage}`; + if (this._config.prefix) { + formattedMessage = `[${this._config.prefix}] ${formattedMessage}`; } // 添加日志级别 @@ -95,15 +142,21 @@ export class ConsoleLogger implements ILogger { formattedMessage = `[${levelName}] ${formattedMessage}`; // 使用自定义输出或默认控制台输出 - if (this.config.output) { - this.config.output(level, formattedMessage); + if (this._config.output) { + this._config.output(level, formattedMessage); } else { this.outputToConsole(level, formattedMessage, ...args); } } + /** + * 输出到控制台 + * @param level 日志级别 + * @param message 格式化后的消息 + * @param args 附加参数 + */ private outputToConsole(level: LogLevel, message: string, ...args: unknown[]): void { - const colors = this.config.enableColors ? this.getColors() : null; + const colors = this._config.enableColors ? this.getColors() : null; switch (level) { case LogLevel.Debug: @@ -138,6 +191,10 @@ export class ConsoleLogger implements ILogger { } } + /** + * 获取控制台颜色配置 + * @returns 颜色配置对象 + */ private getColors() { return { reset: '\x1b[0m', @@ -147,14 +204,6 @@ export class ConsoleLogger implements ILogger { gray: '\x1b[90m' }; } - - public setLevel(level: LogLevel): void { - this.config.level = level; - } - - public setPrefix(prefix: string): void { - this.config.prefix = prefix; - } } /** @@ -169,6 +218,10 @@ export class LoggerManager { this._defaultLogger = new ConsoleLogger(); } + /** + * 获取日志管理器实例 + * @returns 日志管理器实例 + */ public static getInstance(): LoggerManager { if (!LoggerManager._instance) { LoggerManager._instance = new LoggerManager(); @@ -178,6 +231,8 @@ export class LoggerManager { /** * 获取或创建日志器 + * @param name 日志器名称 + * @returns 日志器实例 */ public getLogger(name?: string): ILogger { if (!name) { @@ -197,6 +252,8 @@ export class LoggerManager { /** * 设置日志器 + * @param name 日志器名称 + * @param logger 日志器实例 */ public setLogger(name: string, logger: ILogger): void { this._loggers.set(name, logger); @@ -204,6 +261,7 @@ export class LoggerManager { /** * 设置全局日志级别 + * @param level 日志级别 */ public setGlobalLevel(level: LogLevel): void { if (this._defaultLogger instanceof ConsoleLogger) { @@ -219,6 +277,9 @@ export class LoggerManager { /** * 创建子日志器 + * @param parentName 父日志器名称 + * @param childName 子日志器名称 + * @returns 子日志器实例 */ public createChildLogger(parentName: string, childName: string): ILogger { const fullName = `${parentName}.${childName}`; @@ -233,6 +294,8 @@ export const Logger = LoggerManager.getInstance().getLogger(); /** * 创建命名日志器 + * @param name 日志器名称 + * @returns 日志器实例 */ export function createLogger(name: string): ILogger { return LoggerManager.getInstance().getLogger(name); @@ -240,6 +303,7 @@ export function createLogger(name: string): ILogger { /** * 设置全局日志级别 + * @param level 日志级别 */ export function setGlobalLogLevel(level: LogLevel): void { LoggerManager.getInstance().setGlobalLevel(level); diff --git a/packages/core/src/Utils/Pool.ts b/packages/core/src/Utils/Pool.ts deleted file mode 100644 index 00830f86..00000000 --- a/packages/core/src/Utils/Pool.ts +++ /dev/null @@ -1,565 +0,0 @@ -/** - * 可池化对象接口 - */ -export interface IPoolable { - /** - * 重置对象状态,准备重用 - */ - reset(): void; -} - -/** - * 对象池统计信息 - */ -export interface PoolStats { - /** 池中对象数量 */ - size: number; - /** 池的最大大小 */ - maxSize: number; - /** 总共创建的对象数量 */ - totalCreated: number; - /** 总共获取的次数 */ - totalObtained: number; - /** 总共释放的次数 */ - totalReleased: number; - /** 命中率(从池中获取的比例) */ - hitRate: number; - /** 内存使用估算(字节) */ - estimatedMemoryUsage: number; -} - -/** - * 高性能通用对象池 - * 支持任意类型的对象池化,包含详细的统计信息 - */ -export class Pool { - private static _pools = new Map>(); - - private _objects: T[] = []; - private _createFn: () => T; - private _maxSize: number; - private _stats: PoolStats; - private _objectSize: number; // 估算的单个对象大小 - - /** - * 构造函数 - * @param createFn 创建对象的函数 - * @param maxSize 池的最大大小,默认100 - * @param estimatedObjectSize 估算的单个对象大小(字节),默认1024 - */ - constructor(createFn: () => T, maxSize: number = 100, estimatedObjectSize: number = 1024) { - this._createFn = createFn; - this._maxSize = maxSize; - this._objectSize = estimatedObjectSize; - this._stats = { - size: 0, - maxSize, - totalCreated: 0, - totalObtained: 0, - totalReleased: 0, - hitRate: 0, - estimatedMemoryUsage: 0 - }; - } - - /** - * 获取指定类型的对象池 - * @param type 对象类型 - * @param maxSize 池的最大大小 - * @param estimatedObjectSize 估算的单个对象大小 - * @returns 对象池实例 - */ - public static getPool( - 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; - } - - /** - * 从池中获取对象 - * @returns 对象实例 - */ - public obtain(): T { - this._stats.totalObtained++; - - if (this._objects.length > 0) { - const obj = this._objects.pop()!; - this._stats.size--; - this._updateHitRate(); - this._updateMemoryUsage(); - return obj; - } - - // 池中没有对象,创建新的 - const obj = this._createFn(); - this._stats.totalCreated++; - this._updateHitRate(); - return obj; - } - - /** - * 将对象归还到池中 - * @param obj 要归还的对象 - */ - public free(obj: T): void { - if (this._objects.length < this._maxSize) { - obj.reset(); - this._objects.push(obj); - this._stats.size++; - this._stats.totalReleased++; - this._updateMemoryUsage(); - } - // 如果池已满,对象会被丢弃(由GC回收) - } - - /** - * 预热池,创建指定数量的对象 - * @param count 要创建的对象数量 - */ - public warmUp(count: number): void { - const targetSize = Math.min(count, this._maxSize); - - while (this._objects.length < targetSize) { - const obj = this._createFn(); - this._stats.totalCreated++; - this._objects.push(obj); - this._stats.size++; - } - - this._updateMemoryUsage(); - } - - /** - * 清空池 - */ - public clear(): void { - this._objects.length = 0; - this._stats.size = 0; - this._updateMemoryUsage(); - } - - /** - * 获取池中对象数量 - */ - public get size(): number { - return this._objects.length; - } - - /** - * 获取池的最大大小 - */ - public get maxSize(): number { - return this._maxSize; - } - - /** - * 设置池的最大大小 - */ - public set maxSize(value: number) { - this._maxSize = value; - this._stats.maxSize = value; - - // 如果当前池大小超过新的最大值,则移除多余的对象 - while (this._objects.length > this._maxSize) { - this._objects.pop(); - this._stats.size--; - } - - this._updateMemoryUsage(); - } - - /** - * 获取池的统计信息 - */ - public getStats(): PoolStats { - return { ...this._stats }; - } - - /** - * 重置统计信息 - */ - public resetStats(): void { - this._stats.totalCreated = 0; - this._stats.totalObtained = 0; - this._stats.totalReleased = 0; - this._stats.hitRate = 0; - } - - /** - * 更新命中率 - */ - private _updateHitRate(): void { - if (this._stats.totalObtained > 0) { - const hits = this._stats.totalObtained - this._stats.totalCreated; - this._stats.hitRate = hits / this._stats.totalObtained; - } - } - - /** - * 更新内存使用估算 - */ - private _updateMemoryUsage(): void { - this._stats.estimatedMemoryUsage = this._stats.size * this._objectSize; - } - - /** - * 静态方法:从指定类型的池中获取对象 - * @param type 对象类型 - * @returns 对象实例 - */ - public static obtain(type: new (...args: unknown[]) => T): T { - return this.getPool(type).obtain(); - } - - /** - * 静态方法:将对象归还到对应类型的池中 - * @param type 对象类型 - * @param obj 要归还的对象 - */ - public static free(type: new (...args: unknown[]) => T, obj: T): void { - this.getPool(type).free(obj); - } - - /** - * 静态方法:预热指定类型的池 - * @param type 对象类型 - * @param count 要创建的对象数量 - */ - public static warmUp(type: new (...args: unknown[]) => T, count: number): void { - this.getPool(type).warmUp(count); - } - - /** - * 静态方法:清空指定类型的池 - * @param type 对象类型 - */ - public static clearPool(type: new (...args: unknown[]) => T): void { - const pool = this._pools.get(type); - if (pool) { - pool.clear(); - } - } - - /** - * 静态方法:清空所有池 - */ - public static clearAllPools(): void { - for (const pool of this._pools.values()) { - pool.clear(); - } - this._pools.clear(); - } - - /** - * 静态方法:获取池的统计信息 - * @returns 池的统计信息 - */ - public static getStats(): { [typeName: string]: PoolStats } { - const stats: { [typeName: string]: PoolStats } = {}; - - for (const [type, pool] of this._pools.entries()) { - const typeName = (type as any).name || 'Unknown'; - stats[typeName] = pool.getStats(); - } - - return stats; - } - - /** - * 静态方法:获取所有池的总内存使用量 - * @returns 总内存使用量(字节) - */ - public static getTotalMemoryUsage(): number { - let total = 0; - for (const pool of this._pools.values()) { - total += pool.getStats().estimatedMemoryUsage; - } - return total; - } - - /** - * 静态方法:获取性能报告 - * @returns 格式化的性能报告 - */ - public static getPerformanceReport(): string { - const stats = this.getStats(); - const lines: string[] = []; - - lines.push('=== Object Pool Performance Report ==='); - lines.push(`Total Memory Usage: ${(this.getTotalMemoryUsage() / 1024 / 1024).toFixed(2)} MB`); - lines.push(''); - - for (const [typeName, stat] of Object.entries(stats)) { - lines.push(`${typeName}:`); - lines.push(` Size: ${stat.size}/${stat.maxSize}`); - lines.push(` Hit Rate: ${(stat.hitRate * 100).toFixed(1)}%`); - lines.push(` Total Created: ${stat.totalCreated}`); - lines.push(` Total Obtained: ${stat.totalObtained}`); - lines.push(` Memory: ${(stat.estimatedMemoryUsage / 1024).toFixed(1)} KB`); - lines.push(''); - } - - return lines.join('\n'); - } -} - -/** - * 分层对象池 - * 使用多个不同大小的池来优化内存使用 - */ -export class TieredObjectPool { - private pools: Pool[] = []; - private createFn: () => T; - private resetFn: (obj: T) => void; - private tierSizes: number[]; - private totalObtained = 0; - private totalReleased = 0; - - /** - * 构造函数 - * @param createFn 创建对象的函数 - * @param resetFn 重置对象的函数 - * @param tierSizes 各层级的大小,默认[10, 50, 200] - * @param estimatedObjectSize 估算的单个对象大小 - */ - constructor( - createFn: () => T, - resetFn: (obj: T) => void, - tierSizes: number[] = [10, 50, 200], - estimatedObjectSize: number = 1024 - ) { - this.createFn = createFn; - this.resetFn = resetFn; - this.tierSizes = tierSizes; - - // 初始化不同层级的池 - for (const size of tierSizes) { - this.pools.push(new Pool(createFn, size, estimatedObjectSize)); - } - } - - /** - * 获取对象 - * @returns 对象实例 - */ - public obtain(): T { - this.totalObtained++; - - // 从最小的池开始尝试获取 - for (const pool of this.pools) { - if (pool.size > 0) { - return pool.obtain(); - } - } - - // 所有池都空了,创建新对象 - return this.createFn(); - } - - /** - * 释放对象 - * @param obj 要释放的对象 - */ - public release(obj: T): void { - this.totalReleased++; - this.resetFn(obj); - - // 放入第一个有空间的池 - for (const pool of this.pools) { - if (pool.size < pool.maxSize) { - pool.free(obj); - return; - } - } - - // 所有池都满了,直接丢弃 - } - - /** - * 预热所有池 - * @param totalCount 总预热数量 - */ - public warmUp(totalCount: number): void { - let remaining = totalCount; - - for (const pool of this.pools) { - const warmUpCount = Math.min(remaining, pool.maxSize); - pool.warmUp(warmUpCount); - remaining -= warmUpCount; - - if (remaining <= 0) break; - } - } - - /** - * 清空所有池 - */ - public clear(): void { - for (const pool of this.pools) { - pool.clear(); - } - } - - /** - * 获取统计信息 - */ - public getStats(): { - totalSize: number; - totalMaxSize: number; - totalMemoryUsage: number; - tierStats: PoolStats[]; - hitRate: number; - } { - let totalSize = 0; - let totalMaxSize = 0; - let totalMemoryUsage = 0; - const tierStats: PoolStats[] = []; - - for (const pool of this.pools) { - const stats = pool.getStats(); - tierStats.push(stats); - totalSize += stats.size; - totalMaxSize += stats.maxSize; - totalMemoryUsage += stats.estimatedMemoryUsage; - } - - const hitRate = this.totalObtained > 0 ? - (this.totalObtained - this.getTotalCreated()) / this.totalObtained : 0; - - return { - totalSize, - totalMaxSize, - totalMemoryUsage, - tierStats, - hitRate - }; - } - - /** - * 获取总创建数量 - */ - private getTotalCreated(): number { - return this.pools.reduce((total, pool) => total + pool.getStats().totalCreated, 0); - } -} - -/** - * 池管理器 - * 统一管理所有对象池 - */ -export class PoolManager { - private static instance: PoolManager; - private pools = new Map | TieredObjectPool>(); - private autoCompactInterval = 60000; // 60秒 - private lastCompactTime = 0; - - public static getInstance(): PoolManager { - if (!PoolManager.instance) { - PoolManager.instance = new PoolManager(); - } - return PoolManager.instance; - } - - /** - * 注册池 - * @param name 池名称 - * @param pool 池实例 - */ - public registerPool(name: string, pool: Pool | TieredObjectPool): void { - this.pools.set(name, pool); - } - - /** - * 获取池 - * @param name 池名称 - * @returns 池实例 - */ - public getPool(name: string): Pool | TieredObjectPool | null { - return this.pools.get(name) || null; - } - - /** - * 更新池管理器(应在游戏循环中调用) - */ - public update(): void { - const now = Date.now(); - - if (now - this.lastCompactTime > this.autoCompactInterval) { - this.compactAllPools(); - this.lastCompactTime = now; - } - } - - /** - * 压缩所有池(清理碎片) - */ - public compactAllPools(): void { - // 对于标准池,可以考虑清理一些长时间未使用的对象 - // 这里简单实现为重置统计信息 - for (const pool of this.pools.values()) { - if (pool instanceof Pool) { - pool.resetStats(); - } - } - } - - /** - * 获取所有池的统计信息 - */ - public getAllStats(): Map { - const stats = new Map(); - - for (const [name, pool] of this.pools.entries()) { - if (pool instanceof Pool) { - stats.set(name, pool.getStats()); - } else if (pool instanceof TieredObjectPool) { - stats.set(name, pool.getStats()); - } - } - - return stats; - } - - /** - * 生成性能报告 - */ - public generateReport(): string { - const lines: string[] = []; - lines.push('=== Pool Manager Report ==='); - - let totalMemory = 0; - - for (const [name, pool] of this.pools.entries()) { - lines.push(`\n${name}:`); - - if (pool instanceof Pool) { - const stats = pool.getStats(); - lines.push(` Type: Standard Pool`); - 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`); - totalMemory += stats.estimatedMemoryUsage; - } else if (pool instanceof TieredObjectPool) { - const stats = pool.getStats(); - lines.push(` Type: Tiered Pool`); - lines.push(` Total Size: ${stats.totalSize}/${stats.totalMaxSize}`); - lines.push(` Hit Rate: ${(stats.hitRate * 100).toFixed(1)}%`); - lines.push(` Memory: ${(stats.totalMemoryUsage / 1024).toFixed(1)} KB`); - totalMemory += stats.totalMemoryUsage; - } - } - - lines.push(`\nTotal Memory Usage: ${(totalMemory / 1024 / 1024).toFixed(2)} MB`); - - return lines.join('\n'); - } -} \ No newline at end of file diff --git a/packages/core/src/Utils/Pool/IPoolable.ts b/packages/core/src/Utils/Pool/IPoolable.ts new file mode 100644 index 00000000..e0fa7300 --- /dev/null +++ b/packages/core/src/Utils/Pool/IPoolable.ts @@ -0,0 +1,29 @@ +/** + * 可池化对象接口 + */ +export interface IPoolable { + /** + * 重置对象状态,准备重用 + */ + reset(): void; +} + +/** + * 对象池统计信息 + */ +export interface PoolStats { + /** 池中对象数量 */ + size: number; + /** 池的最大大小 */ + maxSize: number; + /** 总共创建的对象数量 */ + totalCreated: number; + /** 总共获取的次数 */ + totalObtained: number; + /** 总共释放的次数 */ + totalReleased: number; + /** 命中率(从池中获取的比例) */ + 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 new file mode 100644 index 00000000..bb69146e --- /dev/null +++ b/packages/core/src/Utils/Pool/Pool.ts @@ -0,0 +1,282 @@ +import { IPoolable, PoolStats } from './IPoolable'; + +/** + * 高性能通用对象池 + * 支持任意类型的对象池化,包含详细的统计信息 + */ +export class Pool { + private static _pools = new Map>(); + + private _objects: T[] = []; + private _createFn: () => T; + private _maxSize: number; + private _stats: PoolStats; + private _objectSize: number; // 估算的单个对象大小 + + /** + * 构造函数 + * @param createFn 创建对象的函数 + * @param maxSize 池的最大大小,默认100 + * @param estimatedObjectSize 估算的单个对象大小(字节),默认1024 + */ + constructor(createFn: () => T, maxSize: number = 100, estimatedObjectSize: number = 1024) { + this._createFn = createFn; + this._maxSize = maxSize; + this._objectSize = estimatedObjectSize; + this._stats = { + size: 0, + maxSize, + totalCreated: 0, + totalObtained: 0, + totalReleased: 0, + hitRate: 0, + estimatedMemoryUsage: 0 + }; + } + + /** + * 获取指定类型的对象池 + * @param type 对象类型 + * @param maxSize 池的最大大小 + * @param estimatedObjectSize 估算的单个对象大小 + * @returns 对象池实例 + */ + public static getPool( + 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; + } + + /** + * 从池中获取对象 + * @returns 对象实例 + */ + public obtain(): T { + this._stats.totalObtained++; + + if (this._objects.length > 0) { + const obj = this._objects.pop()!; + this._stats.size--; + this._updateHitRate(); + this._updateMemoryUsage(); + return obj; + } + + // 池中没有可用对象,创建新对象 + this._stats.totalCreated++; + this._updateHitRate(); + return this._createFn(); + } + + /** + * 释放对象回池中 + * @param obj 要释放的对象 + */ + public release(obj: T): void { + if (!obj) return; + + this._stats.totalReleased++; + + // 如果池未满,将对象放回池中 + if (this._stats.size < this._maxSize) { + // 重置对象状态 + obj.reset(); + this._objects.push(obj); + this._stats.size++; + this._updateMemoryUsage(); + } + // 如果池已满,让对象被垃圾回收 + } + + /** + * 获取池统计信息 + * @returns 统计信息对象 + */ + public getStats(): Readonly { + return { ...this._stats }; + } + + /** + * 清空池 + */ + public clear(): void { + // 重置所有对象 + for (const obj of this._objects) { + obj.reset(); + } + + this._objects.length = 0; + this._stats.size = 0; + this._updateMemoryUsage(); + } + + /** + * 压缩池(移除多余的对象) + * @param targetSize 目标大小,默认为当前大小的一半 + */ + 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) { + obj.reset(); + this._stats.size--; + } + } + + this._updateMemoryUsage(); + } + + /** + * 预填充池 + * @param count 预填充的对象数量 + */ + 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(); + this._objects.push(obj); + this._stats.totalCreated++; + this._stats.size++; + } + + this._updateMemoryUsage(); + } + + /** + * 设置最大池大小 + * @param maxSize 新的最大大小 + */ + public setMaxSize(maxSize: number): void { + this._maxSize = maxSize; + this._stats.maxSize = maxSize; + + // 如果当前池大小超过新的最大值,进行压缩 + if (this._objects.length > maxSize) { + this.compact(maxSize); + } + } + + /** + * 获取池中可用对象数量 + * @returns 可用对象数量 + */ + public getAvailableCount(): number { + return this._objects.length; + } + + /** + * 检查池是否为空 + * @returns 如果池为空返回true + */ + public isEmpty(): boolean { + return this._objects.length === 0; + } + + /** + * 检查池是否已满 + * @returns 如果池已满返回true + */ + public isFull(): boolean { + return this._objects.length >= this._maxSize; + } + + /** + * 获取所有已注册的池类型 + * @returns 所有池类型的数组 + */ + public static getAllPoolTypes(): Function[] { + return Array.from(this._pools.keys()); + } + + /** + * 获取所有池的统计信息 + * @returns 包含所有池统计信息的对象 + */ + 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; + } + + /** + * 压缩所有池 + */ + public static compactAllPools(): void { + for (const pool of this._pools.values()) { + pool.compact(); + } + } + + /** + * 清空所有池 + */ + public static clearAllPools(): void { + for (const pool of this._pools.values()) { + pool.clear(); + } + this._pools.clear(); + } + + /** + * 获取全局池统计信息的格式化字符串 + * @returns 格式化的统计信息字符串 + */ + public static getGlobalStatsString(): string { + const stats = this.getAllPoolStats(); + const lines: string[] = ['=== Object Pool Global Statistics ===', '']; + + if (Object.keys(stats).length === 0) { + lines.push('No pools registered'); + return lines.join('\n'); + } + + for (const [typeName, stat] of Object.entries(stats)) { + lines.push(`${typeName}:`); + lines.push(` Size: ${stat.size}/${stat.maxSize}`); + lines.push(` Hit Rate: ${(stat.hitRate * 100).toFixed(1)}%`); + lines.push(` Total Created: ${stat.totalCreated}`); + lines.push(` Total Obtained: ${stat.totalObtained}`); + lines.push(` Memory: ${(stat.estimatedMemoryUsage / 1024).toFixed(1)} KB`); + lines.push(''); + } + + return lines.join('\n'); + } + + /** + * 更新命中率 + */ + private _updateHitRate(): void { + if (this._stats.totalObtained === 0) { + this._stats.hitRate = 0; + } else { + const hits = this._stats.totalObtained - this._stats.totalCreated; + this._stats.hitRate = hits / this._stats.totalObtained; + } + } + + /** + * 更新内存使用估算 + */ + 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 new file mode 100644 index 00000000..9fcb1933 --- /dev/null +++ b/packages/core/src/Utils/Pool/PoolManager.ts @@ -0,0 +1,231 @@ +import { IPoolable, PoolStats } from './IPoolable'; +import { Pool } from './Pool'; + +/** + * 池管理器 + * 统一管理所有对象池 + */ +export class PoolManager { + private static instance: PoolManager; + private pools = new Map>(); + private autoCompactInterval = 60000; // 60秒 + private lastCompactTime = 0; + + public static getInstance(): PoolManager { + if (!PoolManager.instance) { + PoolManager.instance = new PoolManager(); + } + return PoolManager.instance; + } + + /** + * 注册池 + * @param name 池名称 + * @param pool 池实例 + */ + public registerPool(name: string, pool: Pool): void { + this.pools.set(name, pool); + } + + /** + * 获取池 + * @param name 池名称 + * @returns 池实例 + */ + public getPool(name: string): Pool | null { + return this.pools.get(name) || null; + } + + /** + * 更新池管理器(应在游戏循环中调用) + */ + public update(): void { + const now = Date.now(); + + if (now - this.lastCompactTime > this.autoCompactInterval) { + this.compactAllPools(); + this.lastCompactTime = now; + } + } + + /** + * 创建或获取标准池 + * @param name 池名称 + * @param createFn 创建函数 + * @param maxSize 最大大小 + * @param estimatedObjectSize 估算对象大小 + * @returns 池实例 + */ + public createPool( + name: string, + createFn: () => T, + maxSize: number = 100, + 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; + } + + + /** + * 移除池 + * @param name 池名称 + * @returns 是否成功移除 + */ + public removePool(name: string): boolean { + const pool = this.pools.get(name); + if (pool) { + pool.clear(); + this.pools.delete(name); + return true; + } + return false; + } + + /** + * 获取所有池名称 + * @returns 池名称数组 + */ + public getPoolNames(): string[] { + return Array.from(this.pools.keys()); + } + + /** + * 获取池数量 + * @returns 池数量 + */ + public getPoolCount(): number { + return this.pools.size; + } + + /** + * 压缩所有池 + */ + public compactAllPools(): void { + for (const pool of this.pools.values()) { + pool.compact(); + } + } + + /** + * 清空所有池 + */ + public clearAllPools(): void { + for (const pool of this.pools.values()) { + pool.clear(); + } + } + + /** + * 获取所有池的统计信息 + * @returns 统计信息映射 + */ + public getAllStats(): Map { + const stats = new Map(); + + for (const [name, pool] of this.pools) { + stats.set(name, pool.getStats()); + } + + return stats; + } + + /** + * 获取总体统计信息 + * @returns 总体统计信息 + */ + public getGlobalStats(): PoolStats { + let totalSize = 0; + let totalMaxSize = 0; + let totalCreated = 0; + let totalObtained = 0; + let totalReleased = 0; + let totalMemoryUsage = 0; + + for (const pool of this.pools.values()) { + const stats = pool.getStats(); + totalSize += stats.size; + totalMaxSize += stats.maxSize; + totalCreated += stats.totalCreated; + totalObtained += stats.totalObtained; + totalReleased += stats.totalReleased; + totalMemoryUsage += stats.estimatedMemoryUsage; + } + + const hitRate = totalObtained === 0 ? 0 : (totalObtained - totalCreated) / totalObtained; + + return { + size: totalSize, + maxSize: totalMaxSize, + totalCreated, + totalObtained, + totalReleased, + hitRate, + estimatedMemoryUsage: totalMemoryUsage + }; + } + + /** + * 获取格式化的统计信息字符串 + * @returns 格式化字符串 + */ + public getStatsString(): string { + const lines: string[] = ['=== Pool Manager Statistics ===', '']; + + if (this.pools.size === 0) { + lines.push('No pools registered'); + return lines.join('\n'); + } + + const globalStats = this.getGlobalStats(); + lines.push(`Total Pools: ${this.pools.size}`); + lines.push(`Global Hit Rate: ${(globalStats.hitRate * 100).toFixed(1)}%`); + lines.push(`Global Memory Usage: ${(globalStats.estimatedMemoryUsage / 1024).toFixed(1)} KB`); + lines.push(''); + + for (const [name, pool] of this.pools) { + const stats = pool.getStats(); + lines.push(`${name}:`); + 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(''); + } + + return lines.join('\n'); + } + + /** + * 设置自动压缩间隔 + * @param intervalMs 间隔毫秒数 + */ + public setAutoCompactInterval(intervalMs: number): void { + this.autoCompactInterval = intervalMs; + } + + /** + * 预填充所有池 + */ + public prewarmAllPools(): void { + for (const pool of this.pools.values()) { + const stats = pool.getStats(); + const prewarmCount = Math.floor(stats.maxSize * 0.2); // 预填充20% + pool.prewarm(prewarmCount); + } + } + + /** + * 重置池管理器 + */ + public reset(): void { + this.clearAllPools(); + this.pools.clear(); + this.lastCompactTime = 0; + } +} \ No newline at end of file diff --git a/packages/core/src/Utils/Pool/index.ts b/packages/core/src/Utils/Pool/index.ts new file mode 100644 index 00000000..2f238812 --- /dev/null +++ b/packages/core/src/Utils/Pool/index.ts @@ -0,0 +1,3 @@ +export * from './IPoolable'; +export * from './Pool'; +export * from './PoolManager'; \ No newline at end of file diff --git a/packages/core/src/Utils/index.ts b/packages/core/src/Utils/index.ts index a3eab8b2..1302e7a3 100644 --- a/packages/core/src/Utils/index.ts +++ b/packages/core/src/Utils/index.ts @@ -4,4 +4,5 @@ export * from './Emitter'; export * from './GlobalManager'; export * from './PerformanceMonitor'; export { Time } from './Time'; -export * from './Debug'; \ No newline at end of file +export * from './Debug'; +export * from './Logger'; \ No newline at end of file diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 9a2a357d..825b398e 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -13,6 +13,17 @@ export { TimerManager } from './Utils/Timers/TimerManager'; export { ITimer } from './Utils/Timers/ITimer'; export { Timer } from './Utils/Timers/Timer'; +// 日志系统 +export { + LoggerManager, + ConsoleLogger, + Logger, + createLogger, + setGlobalLogLevel, + LogLevel +} from './Utils/Logger'; +export type { ILogger, LoggerConfig } from './Utils/Logger'; + // ECS核心组件 export * from './ECS'; diff --git a/packages/network/package.json b/packages/network/package.json index 473cbaea..79641457 100644 --- a/packages/network/package.json +++ b/packages/network/package.json @@ -47,7 +47,7 @@ "@esengine/ecs-framework": ">=2.1.29" }, "devDependencies": { - "@esengine/ecs-framework": "file:../core", + "@esengine/ecs-framework": "*", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-terser": "^0.4.4", diff --git a/packages/network/src/Core/NetworkClient.ts b/packages/network/src/Core/NetworkClient.ts index 7b79f3d3..b34a1cdc 100644 --- a/packages/network/src/Core/NetworkClient.ts +++ b/packages/network/src/Core/NetworkClient.ts @@ -4,6 +4,7 @@ import { SyncVarUpdateMessage } from '../Messaging/MessageTypes'; import { SyncVarMessageHandler } from '../SyncVar/SyncVarMessageHandler'; import { MessageHandler } from '../Messaging/MessageHandler'; import { NetworkPerformanceMonitor } from './NetworkPerformanceMonitor'; +import { createLogger } from '@esengine/ecs-framework'; /** * 客户端事件接口 @@ -24,6 +25,7 @@ export interface NetworkClientEvents { * 提供消息发送和接收功能 */ export class NetworkClient { + private static readonly logger = createLogger('NetworkClient'); private _connection: NetworkConnection | null = null; private _url: string = ''; private _isConnected: boolean = false; @@ -129,7 +131,7 @@ export class NetworkClient { // 设置连接事件监听 this._connection.on('connected', () => { - console.log(`[NetworkClient] 连接成功: ${this._url}`); + NetworkClient.logger.info(`连接成功: ${this._url}`); this.emit('connected'); // 如果这是重连,触发重连成功事件 @@ -139,7 +141,7 @@ export class NetworkClient { }); this._connection.on('disconnected', (reason) => { - console.log(`[NetworkClient] 连接断开: ${reason}`); + NetworkClient.logger.info(`连接断开: ${reason}`); this.handleDisconnection(reason); }); @@ -153,7 +155,7 @@ export class NetworkClient { }); this._connection.on('error', (error) => { - console.error('[NetworkClient] 连接错误:', error); + NetworkClient.logger.error('连接错误:', error); this.emit('error', error); }); @@ -214,7 +216,7 @@ export class NetworkClient { this._maxReconnectDelay ); - console.log(`[NetworkClient] ${delay}ms后尝试重连 (${this._reconnectAttempts}/${this._maxReconnectAttempts})`); + NetworkClient.logger.info(`${delay}ms后尝试重连 (${this._reconnectAttempts}/${this._maxReconnectAttempts})`); this.emit('reconnecting', this._reconnectAttempts); this._reconnectTimer = setTimeout(async () => { @@ -266,7 +268,7 @@ export class NetworkClient { */ public send(data: Uint8Array): boolean { if (!this._connection || !this._isConnected) { - console.warn('[NetworkClient] 未连接,无法发送数据'); + NetworkClient.logger.warn('未连接,无法发送数据'); return false; } @@ -364,7 +366,7 @@ export class NetworkClient { try { handler(...args); } catch (error) { - console.error(`[NetworkClient] 事件处理器错误 (${event}):`, error); + NetworkClient.logger.error(`事件处理器错误 (${event}):`, error); } }); } @@ -449,14 +451,14 @@ export class NetworkClient { const success = this.send(serializedMessage); if (success) { - console.log(`[NetworkClient] 发送SyncVar消息: ${message.networkId}.${message.componentType}`); + NetworkClient.logger.debug(`发送SyncVar消息: ${message.networkId}.${message.componentType}`); } else { - console.warn(`[NetworkClient] SyncVar消息发送失败: ${message.networkId}.${message.componentType}`); + NetworkClient.logger.warn(`SyncVar消息发送失败: ${message.networkId}.${message.componentType}`); } return success; } catch (error) { - console.error('[NetworkClient] 发送SyncVar消息失败:', error); + NetworkClient.logger.error('发送SyncVar消息失赅:', error); return false; } } @@ -476,7 +478,7 @@ export class NetworkClient { } } - console.log(`[NetworkClient] 批量发送SyncVar消息: ${successCount}/${messages.length} 成功`); + NetworkClient.logger.debug(`批量发送SyncVar消息: ${successCount}/${messages.length} 成功`); return successCount; } diff --git a/packages/network/src/Core/NetworkConnection.ts b/packages/network/src/Core/NetworkConnection.ts index 5285e2b6..b644d3a9 100644 --- a/packages/network/src/Core/NetworkConnection.ts +++ b/packages/network/src/Core/NetworkConnection.ts @@ -1,4 +1,5 @@ import WebSocket from 'isomorphic-ws'; +import { createLogger } from '@esengine/ecs-framework'; /** * 网络连接状态 @@ -27,6 +28,7 @@ export interface NetworkConnectionEvents { * 支持二进制消息传输,集成心跳检测 */ export class NetworkConnection { + private static readonly logger = createLogger('NetworkConnection'); private _ws: WebSocket | null = null; private _state: ConnectionState = ConnectionState.Disconnected; private _connectionId: string = ''; @@ -96,13 +98,13 @@ export class NetworkConnection { // 将字符串转换为Uint8Array data = new TextEncoder().encode(event.data); } else { - console.warn('[NetworkConnection] 收到未知类型的消息:', typeof event.data); + NetworkConnection.logger.warn(' 收到未知类型的消息:', typeof event.data); return; } this.emit('message', data); } catch (error) { - console.error('[NetworkConnection] 消息处理错误:', error); + NetworkConnection.logger.error(' 消息处理错误:', error); } }; } @@ -136,7 +138,7 @@ export class NetworkConnection { try { this._ws.send('ping'); } catch (error) { - console.error('[NetworkConnection] 心跳发送失败:', error); + NetworkConnection.logger.error(' 心跳发送失败:', error); } } } @@ -149,7 +151,7 @@ export class NetworkConnection { */ public send(data: Uint8Array): boolean { if (!this._ws || this._state !== ConnectionState.Connected) { - console.warn('[NetworkConnection] 连接未就绪,无法发送数据'); + NetworkConnection.logger.warn(' 连接未就绪,无法发送数据'); return false; } @@ -157,7 +159,7 @@ export class NetworkConnection { this._ws.send(data); return true; } catch (error) { - console.error('[NetworkConnection] 数据发送失败:', error); + NetworkConnection.logger.error(' 数据发送失败:', error); return false; } } @@ -179,7 +181,7 @@ export class NetworkConnection { try { this._ws.close(1000, reason); } catch (error) { - console.error('[NetworkConnection] 连接关闭失败:', error); + NetworkConnection.logger.error(' 连接关闭失败:', error); } this._ws = null; } @@ -236,7 +238,7 @@ export class NetworkConnection { try { handler(...args); } catch (error) { - console.error(`[NetworkConnection] 事件处理器错误 (${event}):`, error); + NetworkConnection.logger.error(`事件处理器错误 (${event}):`, error); } }); } diff --git a/packages/network/src/Core/NetworkEnvironment.ts b/packages/network/src/Core/NetworkEnvironment.ts index 43f1b06b..001ddd7c 100644 --- a/packages/network/src/Core/NetworkEnvironment.ts +++ b/packages/network/src/Core/NetworkEnvironment.ts @@ -1,4 +1,5 @@ import { NetworkRole } from '../NetworkRole'; +import { createLogger } from '@esengine/ecs-framework'; /** * 网络环境状态 @@ -21,6 +22,7 @@ export enum NetworkEnvironmentState { * 避免在构造函数中传递角色参数,保持与核心ECS框架的兼容性 */ export class NetworkEnvironment { + private static readonly logger = createLogger('NetworkEnvironment'); private static _instance: NetworkEnvironment | null = null; private _state: NetworkEnvironmentState = NetworkEnvironmentState.None; private _serverStartTime: number = 0; @@ -52,7 +54,7 @@ export class NetworkEnvironment { } instance._serverStartTime = Date.now(); - console.log(`[NetworkEnvironment] 环境设置为: ${instance._state}`); + NetworkEnvironment.logger.info(`环境设置为: ${instance._state}`); } /** @@ -69,7 +71,7 @@ export class NetworkEnvironment { } instance._clientConnectTime = Date.now(); - console.log(`[NetworkEnvironment] 环境设置为: ${instance._state}`); + NetworkEnvironment.logger.info(`环境设置为: ${instance._state}`); } /** @@ -85,7 +87,7 @@ export class NetworkEnvironment { } instance._serverStartTime = 0; - console.log(`[NetworkEnvironment] 服务端模式已清除,当前状态: ${instance._state}`); + NetworkEnvironment.logger.info(`服务端模式已清除,当前状态: ${instance._state}`); } /** @@ -101,7 +103,7 @@ export class NetworkEnvironment { } instance._clientConnectTime = 0; - console.log(`[NetworkEnvironment] 客户端模式已清除,当前状态: ${instance._state}`); + NetworkEnvironment.logger.info(`客户端模式已清除,当前状态: ${instance._state}`); } /** @@ -112,7 +114,7 @@ export class NetworkEnvironment { instance._state = NetworkEnvironmentState.None; instance._serverStartTime = 0; instance._clientConnectTime = 0; - console.log('[NetworkEnvironment] 环境状态已重置'); + NetworkEnvironment.logger.info('环境状态已重置'); } /** @@ -241,6 +243,6 @@ export class NetworkEnvironment { instance._clientConnectTime = clientConnectTime; } - console.log(`[NetworkEnvironment] 强制设置环境状态为: ${state}`); + NetworkEnvironment.logger.debug(`强制设置环境状态为: ${state}`); } } \ No newline at end of file diff --git a/packages/network/src/Core/NetworkIdentity.ts b/packages/network/src/Core/NetworkIdentity.ts index eb7d9f00..14b766f3 100644 --- a/packages/network/src/Core/NetworkIdentity.ts +++ b/packages/network/src/Core/NetworkIdentity.ts @@ -1,4 +1,4 @@ -import { Component } from '@esengine/ecs-framework'; +import { Component, createLogger } from '@esengine/ecs-framework'; import { v4 as uuidv4 } from 'uuid'; /** @@ -8,6 +8,8 @@ import { v4 as uuidv4 } from 'uuid'; * 每个需要网络同步的实体都必须拥有此组件 */ export class NetworkIdentity extends Component { + private static readonly logger = createLogger('NetworkIdentity'); + /** * 网络对象唯一ID */ @@ -74,7 +76,7 @@ export class NetworkIdentity extends Component { // 自动注册到NetworkIdentityRegistry NetworkIdentityRegistry.Instance.register(this); - console.log(`[NetworkIdentity] 创建网络对象: ${this.networkId}, 权威: ${hasAuthority}`); + NetworkIdentity.logger.debug(` 创建网络对象: ${this.networkId}, 权威: ${hasAuthority}`); } /** @@ -86,7 +88,7 @@ export class NetworkIdentity extends Component { const oldOwnerId = this.ownerId; this.ownerId = ownerId; - console.log(`[NetworkIdentity] 对象 ${this.networkId} 拥有者变更: ${oldOwnerId} -> ${ownerId}`); + NetworkIdentity.logger.debug(` 对象 ${this.networkId} 拥有者变更: ${oldOwnerId} -> ${ownerId}`); } /** @@ -97,7 +99,7 @@ export class NetworkIdentity extends Component { public setAuthority(hasAuthority: boolean): void { if (this.hasAuthority !== hasAuthority) { this.hasAuthority = hasAuthority; - console.log(`[NetworkIdentity] 对象 ${this.networkId} 权威状态变更: ${hasAuthority}`); + NetworkIdentity.logger.debug(` 对象 ${this.networkId} 权威状态变更: ${hasAuthority}`); } } @@ -107,7 +109,7 @@ export class NetworkIdentity extends Component { public activate(): void { if (!this.isNetworkActive) { this.isNetworkActive = true; - console.log(`[NetworkIdentity] 激活网络对象: ${this.networkId}`); + NetworkIdentity.logger.debug(` 激活网络对象: ${this.networkId}`); } } @@ -117,7 +119,7 @@ export class NetworkIdentity extends Component { public deactivate(): void { if (this.isNetworkActive) { this.isNetworkActive = false; - console.log(`[NetworkIdentity] 停用网络对象: ${this.networkId}`); + NetworkIdentity.logger.debug(` 停用网络对象: ${this.networkId}`); } } @@ -178,7 +180,7 @@ export class NetworkIdentity extends Component { public cleanup(): void { NetworkIdentityRegistry.Instance.unregister(this.networkId); this.deactivate(); - console.log(`[NetworkIdentity] 清理网络对象: ${this.networkId}`); + NetworkIdentity.logger.debug(` 清理网络对象: ${this.networkId}`); } } @@ -188,6 +190,7 @@ export class NetworkIdentity extends Component { * 管理所有网络对象的注册和查找 */ export class NetworkIdentityRegistry { + private static readonly logger = createLogger('NetworkIdentityRegistry'); private static _instance: NetworkIdentityRegistry | null = null; /** @@ -226,7 +229,7 @@ export class NetworkIdentityRegistry { */ public register(identity: NetworkIdentity): void { if (this._identities.has(identity.networkId)) { - console.warn(`[NetworkIdentityRegistry] 网络对象ID重复: ${identity.networkId}`); + NetworkIdentityRegistry.logger.warn(` 网络对象ID重复: ${identity.networkId}`); return; } @@ -242,7 +245,7 @@ export class NetworkIdentityRegistry { this._authorityObjects.add(identity); } - console.log(`[NetworkIdentityRegistry] 注册网络对象: ${identity.networkId}`); + NetworkIdentityRegistry.logger.debug(` 注册网络对象: ${identity.networkId}`); } /** @@ -266,7 +269,7 @@ export class NetworkIdentityRegistry { // 从权威对象集合中移除 this._authorityObjects.delete(identity); - console.log(`[NetworkIdentityRegistry] 注销网络对象: ${networkId}`); + NetworkIdentityRegistry.logger.debug(` 注销网络对象: ${networkId}`); return true; } @@ -386,7 +389,7 @@ export class NetworkIdentityRegistry { identity.setAuthority(false); } - console.log(`[NetworkIdentityRegistry] 清理断开连接客户端 ${disconnectedOwnerId} 的 ${ownerObjects.length} 个对象`); + NetworkIdentityRegistry.logger.debug(` 清理断开连接客户端 ${disconnectedOwnerId} 的 ${ownerObjects.length} 个对象`); return ownerObjects; } @@ -473,6 +476,6 @@ export class NetworkIdentityRegistry { this._identities.clear(); this._ownerObjects.clear(); this._authorityObjects.clear(); - console.log('[NetworkIdentityRegistry] 已清空注册表'); + NetworkIdentityRegistry.logger.info(' 已清空注册表'); } } \ No newline at end of file diff --git a/packages/network/src/Core/NetworkManager.ts b/packages/network/src/Core/NetworkManager.ts index 8c2b8d61..e7929d9a 100644 --- a/packages/network/src/Core/NetworkManager.ts +++ b/packages/network/src/Core/NetworkManager.ts @@ -1,6 +1,7 @@ import { NetworkServer } from './NetworkServer'; import { NetworkClient } from './NetworkClient'; import { NetworkEnvironment } from './NetworkEnvironment'; +import { createLogger } from '@esengine/ecs-framework'; /** * 网络管理器 - 网络框架的核心入口 @@ -9,6 +10,7 @@ import { NetworkEnvironment } from './NetworkEnvironment'; * 支持启动服务端、客户端,管理连接状态 */ export class NetworkManager { + private static readonly _logger = createLogger('NetworkManager'); private static _instance: NetworkManager | null = null; private _server: NetworkServer | null = null; private _client: NetworkClient | null = null; @@ -38,7 +40,7 @@ export class NetworkManager { const instance = NetworkManager.Instance; if (instance._isServer) { - console.warn('[NetworkManager] 服务端已经在运行'); + NetworkManager._logger.warn('服务端已经在运行'); return false; } @@ -50,10 +52,10 @@ export class NetworkManager { // 自动设置网络环境为服务端模式 NetworkEnvironment.SetServerMode(); - console.log(`[NetworkManager] 服务端启动成功,监听 ${host}:${port}`); + NetworkManager._logger.info(`服务端启动成功,监听 ${host}:${port}`); return true; } catch (error) { - console.error('[NetworkManager] 服务端启动失败:', error); + NetworkManager._logger.error('服务端启动失败:', error); instance._server = null; return false; } @@ -69,7 +71,7 @@ export class NetworkManager { const instance = NetworkManager.Instance; if (instance._isClient) { - console.warn('[NetworkManager] 客户端已经在运行'); + NetworkManager._logger.warn('客户端已经在运行'); return false; } @@ -81,10 +83,10 @@ export class NetworkManager { // 自动设置网络环境为客户端模式 NetworkEnvironment.SetClientMode(); - console.log(`[NetworkManager] 客户端连接成功: ${url}`); + NetworkManager._logger.info(`客户端连接成功: ${url}`); return true; } catch (error) { - console.error('[NetworkManager] 客户端连接失败:', error); + NetworkManager._logger.error('客户端连接失败:', error); instance._client = null; return false; } @@ -104,7 +106,7 @@ export class NetworkManager { // 清除服务端环境模式 NetworkEnvironment.ClearServerMode(); - console.log('[NetworkManager] 服务端已停止'); + NetworkManager._logger.info('服务端已停止'); } } @@ -122,7 +124,7 @@ export class NetworkManager { // 清除客户端环境模式 NetworkEnvironment.ClearClientMode(); - console.log('[NetworkManager] 客户端已断开连接'); + NetworkManager._logger.info('客户端已断开连接'); } } diff --git a/packages/network/src/Core/NetworkPerformanceMonitor.ts b/packages/network/src/Core/NetworkPerformanceMonitor.ts index 891c4ca2..0c349a85 100644 --- a/packages/network/src/Core/NetworkPerformanceMonitor.ts +++ b/packages/network/src/Core/NetworkPerformanceMonitor.ts @@ -3,6 +3,7 @@ * * 监控网络连接的性能指标,包括延迟、吞吐量、包丢失率等 */ +import { createLogger } from '@esengine/ecs-framework'; export interface NetworkMetrics { /** 往返时延 (ms) */ @@ -56,6 +57,7 @@ export interface PerformanceSnapshot { * 网络性能监控器 */ export class NetworkPerformanceMonitor { + private static readonly logger = createLogger('NetworkPerformanceMonitor'); private static _instance: NetworkPerformanceMonitor | null = null; /** 性能快照历史 */ @@ -117,7 +119,7 @@ export class NetworkPerformanceMonitor { */ public startMonitoring(interval: number = 1000): void { if (this._isMonitoring) { - console.warn('[NetworkPerformanceMonitor] 监控已在运行'); + NetworkPerformanceMonitor.logger.warn('监控已在运行'); return; } @@ -128,7 +130,7 @@ export class NetworkPerformanceMonitor { this.collectMetrics(); }, this._monitoringInterval); - console.log(`[NetworkPerformanceMonitor] 开始性能监控,间隔: ${interval}ms`); + NetworkPerformanceMonitor.logger.info(`开始性能监控,间隔: ${interval}ms`); } /** @@ -145,7 +147,7 @@ export class NetworkPerformanceMonitor { } this._isMonitoring = false; - console.log('[NetworkPerformanceMonitor] 停止性能监控'); + NetworkPerformanceMonitor.logger.info('停止性能监控'); } /** @@ -308,7 +310,7 @@ export class NetworkPerformanceMonitor { syncDataSize: stats.totalDataSize || 0 }; } catch (error) { - console.warn('[NetworkPerformanceMonitor] 获取SyncVar统计失败:', error); + NetworkPerformanceMonitor.logger.warn('获取SyncVar统计失败:', error); return undefined; } } @@ -337,7 +339,7 @@ export class NetworkPerformanceMonitor { if (warnings.length > 0) { this.emit('performanceWarning', warnings); - console.warn('[NetworkPerformanceMonitor] 性能警告:', warnings.join(', ')); + NetworkPerformanceMonitor.logger.warn('性能警告:', warnings.join(', ')); } } @@ -418,7 +420,7 @@ export class NetworkPerformanceMonitor { this._snapshots = []; this._rttHistory = []; this._bandwidthWindow = []; - console.log('[NetworkPerformanceMonitor] 清除历史数据'); + NetworkPerformanceMonitor.logger.debug('清除历史数据'); } /** @@ -504,7 +506,7 @@ export class NetworkPerformanceMonitor { try { listener(...args); } catch (error) { - console.error(`[NetworkPerformanceMonitor] 事件处理器错误 (${event}):`, error); + NetworkPerformanceMonitor.logger.error(`事件处理器错误 (${event}):`, error); } }); } @@ -530,7 +532,7 @@ export class NetworkPerformanceMonitor { this._bandwidthWindowSize = options.bandwidthWindowSize; } - console.log('[NetworkPerformanceMonitor] 配置已更新:', options); + NetworkPerformanceMonitor.logger.info('配置已更新:', options); } /** diff --git a/packages/network/src/Core/NetworkServer.ts b/packages/network/src/Core/NetworkServer.ts index d3373063..5621aa29 100644 --- a/packages/network/src/Core/NetworkServer.ts +++ b/packages/network/src/Core/NetworkServer.ts @@ -6,6 +6,7 @@ import { SyncVarMessageHandler } from '../SyncVar/SyncVarMessageHandler'; import { SyncVarSyncScheduler } from '../SyncVar/SyncVarSyncScheduler'; import { MessageHandler } from '../Messaging/MessageHandler'; import { NetworkPerformanceMonitor } from './NetworkPerformanceMonitor'; +import { createLogger } from '@esengine/ecs-framework'; /** * 服务端事件接口 @@ -26,6 +27,7 @@ export interface NetworkServerEvents { * 支持多客户端连接,提供广播和单播功能 */ export class NetworkServer { + private static readonly _logger = createLogger('NetworkServer'); private _wss: WebSocketServer | null = null; private _connections: Map = new Map(); private _isRunning: boolean = false; @@ -104,13 +106,13 @@ export class NetworkServer { // 启动性能监控 this.startPerformanceMonitoring(); - console.log(`[NetworkServer] 服务器启动成功: ${host}:${port}`); + NetworkServer._logger.info(`服务器启动成功: ${host}:${port}`); this.emit('serverStarted', port, host); resolve(); }); this._wss.on('error', (error) => { - console.error('[NetworkServer] 服务器错误:', error); + NetworkServer._logger.error('服务器错误:', error); this.emit('error', error); if (!this._isRunning) { @@ -154,7 +156,7 @@ export class NetworkServer { this._host = ''; this._startTime = 0; - console.log('[NetworkServer] 服务器已停止'); + NetworkServer._logger.info('服务器已停止'); this.emit('serverStopped'); resolve(); }); @@ -170,7 +172,7 @@ export class NetworkServer { private handleNewConnection(ws: WebSocket, request: any): void { // 检查连接数限制 if (this._connections.size >= NetworkServer.MAX_CONNECTIONS) { - console.warn('[NetworkServer] 达到最大连接数限制,拒绝新连接'); + NetworkServer._logger.warn('达到最大连接数限制,拒绝新连接'); ws.close(1013, 'Server full'); return; } @@ -185,13 +187,13 @@ export class NetworkServer { // 设置连接事件监听 connection.on('connected', () => { this._connections.set(connectionId, connection); - console.log(`[NetworkServer] 客户端连接: ${connectionId} (${clientAddress})`); + NetworkServer._logger.info(`客户端连接: ${connectionId} (${clientAddress})`); this.emit('clientConnected', connection); }); connection.on('disconnected', (reason) => { this._connections.delete(connectionId); - console.log(`[NetworkServer] 客户端断开: ${connectionId} (${reason})`); + NetworkServer._logger.info(`客户端断开: ${connectionId} (${reason})`); this.emit('clientDisconnected', connection, reason); }); @@ -205,7 +207,7 @@ export class NetworkServer { }); connection.on('error', (error) => { - console.error(`[NetworkServer] 连接错误 ${connectionId}:`, error); + NetworkServer._logger.error(`连接错误 ${connectionId}:`, error); this.emit('error', error); }); } @@ -220,7 +222,7 @@ export class NetworkServer { public sendToClient(connectionId: string, data: Uint8Array): boolean { const connection = this._connections.get(connectionId); if (!connection) { - console.warn(`[NetworkServer] 连接不存在: ${connectionId}`); + NetworkServer._logger.warn(`连接不存在: ${connectionId}`); return false; } @@ -370,7 +372,7 @@ export class NetworkServer { try { handler(...args); } catch (error) { - console.error(`[NetworkServer] 事件处理器错误 (${event}):`, error); + NetworkServer._logger.error(`事件处理器错误 (${event}):`, error); } }); } @@ -417,9 +419,9 @@ export class NetworkServer { private startSyncVarScheduler(): void { try { this._syncScheduler.start(); - console.log('[NetworkServer] SyncVar同步调度器已启动'); + NetworkServer._logger.info('SyncVar同步调度器已启动'); } catch (error) { - console.error('[NetworkServer] 启动SyncVar调度器失败:', error); + NetworkServer._logger.error('启动SyncVar调度器失败:', error); } } @@ -429,9 +431,9 @@ export class NetworkServer { private stopSyncVarScheduler(): void { try { this._syncScheduler.stop(); - console.log('[NetworkServer] SyncVar同步调度器已停止'); + NetworkServer._logger.info('SyncVar同步调度器已停止'); } catch (error) { - console.error('[NetworkServer] 停止SyncVar调度器失败:', error); + NetworkServer._logger.error('停止SyncVar调度器失败:', error); } } @@ -445,9 +447,9 @@ export class NetworkServer { const serializedMessage = message.serialize(); const successCount = this.broadcast(serializedMessage); - console.log(`[NetworkServer] 广播SyncVar消息: ${message.networkId}.${message.componentType}, 成功发送到 ${successCount} 个客户端`); + NetworkServer._logger.info(`广播SyncVar消息: ${message.networkId}.${message.componentType}, 成功发送到 ${successCount} 个客户端`); } catch (error) { - console.error('[NetworkServer] 广播SyncVar消息失败:', error); + NetworkServer._logger.error('广播SyncVar消息失败:', error); } } @@ -462,7 +464,7 @@ export class NetworkServer { const serializedMessage = message.serialize(); return this.sendToClient(connectionId, serializedMessage); } catch (error) { - console.error(`[NetworkServer] 发送SyncVar消息到客户端 ${connectionId} 失败:`, error); + NetworkServer._logger.error(`发送SyncVar消息到客户端 ${connectionId} 失败:`, error); return false; } } @@ -481,7 +483,7 @@ export class NetworkServer { return this.sendToMultipleClients(targetConnections, serializedMessage); } catch (error) { - console.error('[NetworkServer] 广播SyncVar消息(排除指定客户端)失败:', error); + NetworkServer._logger.error('广播SyncVar消息(排除指定客户端)失败:', error); return 0; } } @@ -506,9 +508,9 @@ export class NetworkServer { private startPerformanceMonitoring(): void { try { this._performanceMonitor.startMonitoring(); - console.log('[NetworkServer] 性能监控已启动'); + NetworkServer._logger.info('性能监控已启动'); } catch (error) { - console.error('[NetworkServer] 启动性能监控失败:', error); + NetworkServer._logger.error('启动性能监控失败:', error); } } @@ -518,9 +520,9 @@ export class NetworkServer { private stopPerformanceMonitoring(): void { try { this._performanceMonitor.stopMonitoring(); - console.log('[NetworkServer] 性能监控已停止'); + NetworkServer._logger.info('性能监控已停止'); } catch (error) { - console.error('[NetworkServer] 停止性能监控失败:', error); + NetworkServer._logger.error('停止性能监控失败:', error); } } diff --git a/packages/network/src/Core/index.ts b/packages/network/src/Core/index.ts index bc060f3a..6576af6c 100644 --- a/packages/network/src/Core/index.ts +++ b/packages/network/src/Core/index.ts @@ -11,22 +11,10 @@ export { NetworkConnection, ConnectionState } from './NetworkConnection'; export { NetworkEnvironment, NetworkEnvironmentState } from './NetworkEnvironment'; export { NetworkIdentity, NetworkIdentityRegistry } from './NetworkIdentity'; export { NetworkPerformanceMonitor } from './NetworkPerformanceMonitor'; -export { - LoggerManager, - ConsoleLogger, - Logger, - createLogger, - setGlobalLogLevel, - LogLevel -} from './Logger'; - // 事件接口导出 export type { NetworkServerEvents } from './NetworkServer'; export type { NetworkClientEvents } from './NetworkClient'; export type { NetworkConnectionEvents } from './NetworkConnection'; // 性能监控类型导出 -export type { NetworkMetrics, PerformanceSnapshot } from './NetworkPerformanceMonitor'; - -// 日志类型导出 -export type { ILogger, LoggerConfig } from './Logger'; \ No newline at end of file +export type { NetworkMetrics, PerformanceSnapshot } from './NetworkPerformanceMonitor'; \ No newline at end of file diff --git a/packages/network/src/Messaging/MessageHandler.ts b/packages/network/src/Messaging/MessageHandler.ts index 16f75f30..c41e81df 100644 --- a/packages/network/src/Messaging/MessageHandler.ts +++ b/packages/network/src/Messaging/MessageHandler.ts @@ -1,6 +1,7 @@ import { NetworkMessage } from './NetworkMessage'; import { NetworkConnection } from '../Core/NetworkConnection'; import { INetworkMessage, MessageData } from '../types/NetworkTypes'; +import { createLogger } from '@esengine/ecs-framework'; /** * 消息处理器接口 @@ -31,6 +32,7 @@ interface MessageHandlerInfo { * 支持消息优先级和类型匹配 */ export class MessageHandler { + private static readonly logger = createLogger('MessageHandler'); private static _instance: MessageHandler | null = null; private _handlers: Map = new Map(); private _messageClasses: Map INetworkMessage> = new Map(); @@ -74,7 +76,7 @@ export class MessageHandler { // 检查是否已经注册了相同的处理器 const existingIndex = handlers.findIndex(h => h.handler === handler); if (existingIndex !== -1) { - console.warn(`[MessageHandler] 消息类型 ${messageType} 的处理器已存在,将替换优先级`); + MessageHandler.logger.warn(`消息类型 ${messageType} 的处理器已存在,将替换优先级`); handlers[existingIndex].priority = priority; } else { // 添加新处理器 @@ -88,7 +90,7 @@ export class MessageHandler { // 按优先级排序(数字越小优先级越高) handlers.sort((a, b) => a.priority - b.priority); - console.log(`[MessageHandler] 注册消息处理器: 类型=${messageType}, 优先级=${priority}`); + MessageHandler.logger.debug(`注册消息处理器: 类型=${messageType}, 优先级=${priority}`); } /** @@ -106,7 +108,7 @@ export class MessageHandler { const index = handlers.findIndex(h => h.handler === handler); if (index !== -1) { handlers.splice(index, 1); - console.log(`[MessageHandler] 注销消息处理器: 类型=${messageType}`); + MessageHandler.logger.debug(`注销消息处理器: 类型=${messageType}`); } // 如果没有处理器了,清理映射 @@ -125,7 +127,7 @@ export class MessageHandler { */ public async handleRawMessage(data: Uint8Array, connection?: NetworkConnection): Promise { if (data.length < 4) { - console.error('[MessageHandler] 消息数据长度不足,至少需要4字节消息类型'); + MessageHandler.logger.error('消息数据长度不足,至少需要4字节消息类型'); return false; } @@ -136,7 +138,7 @@ export class MessageHandler { // 查找消息类 const MessageClass = this._messageClasses.get(messageType); if (!MessageClass) { - console.warn(`[MessageHandler] 未知的消息类型: ${messageType}`); + MessageHandler.logger.warn(`未知的消息类型: ${messageType}`); return false; } @@ -147,7 +149,7 @@ export class MessageHandler { return await this.handleMessage(message, connection); } catch (error) { - console.error(`[MessageHandler] 消息反序列化失败 (类型=${messageType}):`, error); + MessageHandler.logger.error(`消息反序列化失败 (类型=${messageType}):`, error); return false; } } @@ -164,7 +166,7 @@ export class MessageHandler { const handlers = this._handlers.get(messageType); if (!handlers || handlers.length === 0) { - console.warn(`[MessageHandler] 没有找到消息类型 ${messageType} 的处理器`); + MessageHandler.logger.warn(`没有找到消息类型 ${messageType} 的处理器`); return false; } @@ -182,7 +184,7 @@ export class MessageHandler { handledCount++; } catch (error) { - console.error(`[MessageHandler] 处理器执行错误 (类型=${messageType}, 优先级=${handlerInfo.priority}):`, error); + MessageHandler.logger.error(`处理器执行错误 (类型=${messageType}, 优先级=${handlerInfo.priority}):`, error); // 继续执行其他处理器 } } @@ -226,7 +228,7 @@ export class MessageHandler { public clear(): void { this._handlers.clear(); this._messageClasses.clear(); - console.log('[MessageHandler] 已清除所有消息处理器'); + MessageHandler.logger.info('已清除所有消息处理器'); } /** diff --git a/packages/network/src/NetworkComponent.ts b/packages/network/src/NetworkComponent.ts index b83ec92a..bfd0a2f3 100644 --- a/packages/network/src/NetworkComponent.ts +++ b/packages/network/src/NetworkComponent.ts @@ -5,6 +5,7 @@ import { NetworkEnvironment } from './Core/NetworkEnvironment'; import { createSyncVarProxy, isSyncVarProxied, destroySyncVarProxy } from './SyncVar/SyncVarProxy'; import { SyncVarManager } from './SyncVar/SyncVarManager'; import { getSyncVarMetadata } from './SyncVar/SyncVarDecorator'; +import { createLogger } from '@esengine/ecs-framework'; /** * 网络组件基类 @@ -92,10 +93,12 @@ export abstract class NetworkComponent extends Component implements INetworkSync if (!ComponentRegistry.isRegistered(this.constructor)) { // 如果未注册,自动注册 ComponentRegistry.register(this.constructor); - console.log(`[NetworkComponent] 自动注册组件类型: ${this.constructor.name}`); + const logger = createLogger('NetworkComponent'); + logger.debug(`自动注册组件类型: ${this.constructor.name}`); } } catch (error) { - console.warn(`[NetworkComponent] 无法注册组件类型 ${this.constructor.name}:`, error); + const logger = createLogger('NetworkComponent'); + logger.warn(`无法注册组件类型 ${this.constructor.name}:`, error); } } @@ -107,7 +110,8 @@ export abstract class NetworkComponent extends Component implements INetworkSync private initializeSyncVar(): void { const metadata = getSyncVarMetadata(this.constructor); if (metadata.length > 0) { - console.log(`[NetworkComponent] ${this.constructor.name} 发现 ${metadata.length} 个SyncVar字段,将启用代理监听`); + const logger = createLogger('NetworkComponent'); + logger.debug(`${this.constructor.name} 发现 ${metadata.length} 个SyncVar字段,将启用代理监听`); } } diff --git a/packages/network/src/Serialization/ProtobufSerializer.ts b/packages/network/src/Serialization/ProtobufSerializer.ts index 5006bb3f..0a84f8fc 100644 --- a/packages/network/src/Serialization/ProtobufSerializer.ts +++ b/packages/network/src/Serialization/ProtobufSerializer.ts @@ -12,6 +12,7 @@ import { getProtoName } from './ProtobufDecorators'; import { SerializedData } from './SerializationTypes'; +import { createLogger } from '@esengine/ecs-framework'; /** * 可序列化组件接口 @@ -28,6 +29,7 @@ interface SerializableComponent extends Component { export class ProtobufSerializer { private registry: ProtobufRegistry; private static instance: ProtobufSerializer; + private static readonly logger = createLogger('ProtobufSerializer'); /** protobuf.js根对象 */ private root: protobuf.Root | null = null; @@ -104,7 +106,7 @@ export class ProtobufSerializer { private async initializeProtobuf(): Promise { try { this.buildProtoDefinitions(); - console.log('[ProtobufSerializer] Protobuf支持已启用'); + ProtobufSerializer.logger.info('Protobuf支持已启用'); } catch (error) { throw new Error('[ProtobufSerializer] 初始化protobuf失败: ' + error); } @@ -127,7 +129,7 @@ export class ProtobufSerializer { } else { this.buildProtoDefinitions(); } - console.log('[ProtobufSerializer] Protobuf支持已手动启用'); + ProtobufSerializer.logger.info('Protobuf支持已手动启用'); } /** @@ -247,7 +249,7 @@ export class ProtobufSerializer { // 记录错误统计 if (errors.length > 0) { - console.warn(`[ProtobufSerializer] 批量序列化完成,${results.length} 成功,${errors.length} 失败`); + ProtobufSerializer.logger.warn(`批量序列化完成,${results.length} 成功,${errors.length} 失败`); } return results; @@ -382,7 +384,7 @@ export class ProtobufSerializer { this.componentDataCache.delete(key); } - console.log(`[ProtobufSerializer] 清理了 ${entries.length} 个缓存项`); + ProtobufSerializer.logger.debug(`清理了 ${entries.length} 个缓存项`); } /** @@ -434,7 +436,7 @@ export class ProtobufSerializer { this.messageTypeCache.clear(); this.cacheAccessCount.clear(); } catch (error) { - console.error('[ProtobufSerializer] 构建protobuf定义失败:', error); + ProtobufSerializer.logger.error('构建protobuf定义失败:', error); } } @@ -463,7 +465,7 @@ export class ProtobufSerializer { } return null; } catch (error) { - console.warn(`[ProtobufSerializer] 未找到消息类型: ${fullTypeName}`); + ProtobufSerializer.logger.warn(`未找到消息类型: ${fullTypeName}`); return null; } } diff --git a/packages/network/src/Snapshot/SnapshotManager.ts b/packages/network/src/Snapshot/SnapshotManager.ts index 2ec8fef5..8d87493b 100644 --- a/packages/network/src/Snapshot/SnapshotManager.ts +++ b/packages/network/src/Snapshot/SnapshotManager.ts @@ -1,4 +1,4 @@ -import { Entity, Component, ComponentType } from '@esengine/ecs-framework'; +import { Entity, Component, ComponentType, createLogger } from '@esengine/ecs-framework'; import { ISnapshotable, SceneSnapshot, EntitySnapshot, ComponentSnapshot, SnapshotConfig } from './ISnapshotable'; import { ProtobufSerializer } from '../Serialization/ProtobufSerializer'; import { SerializedData } from '../Serialization/SerializationTypes'; @@ -103,6 +103,8 @@ class ComponentTypeRegistry implements IComponentFactory { * 使用protobuf序列化 */ export class SnapshotManager { + private static readonly logger = createLogger('SnapshotManager'); + /** 默认快照配置 */ private static readonly DEFAULT_CONFIG: SnapshotConfig = { includeInSnapshot: true, @@ -240,7 +242,7 @@ export class SnapshotManager { return entity; } catch (error) { - console.error(`[SnapshotManager] 创建实体失败: ${entitySnapshot.name}`, error); + SnapshotManager.logger.error(`创建实体失败: ${entitySnapshot.name}`, error); return null; } } @@ -253,7 +255,7 @@ export class SnapshotManager { // 尝试获取组件构造函数 const componentType = this.getComponentType(componentSnapshot.type); if (!componentType) { - console.warn(`[SnapshotManager] 未知组件类型: ${componentSnapshot.type}`); + SnapshotManager.logger.warn(`未知组件类型: ${componentSnapshot.type}`); return; } @@ -272,7 +274,7 @@ export class SnapshotManager { this.protobufSerializer.deserialize(component, serializedData); } catch (error) { - console.error(`[SnapshotManager] 创建组件失败: ${componentSnapshot.type}`, error); + SnapshotManager.logger.error(`创建组件失败: ${componentSnapshot.type}`, error); } } @@ -282,7 +284,7 @@ export class SnapshotManager { private getComponentType(typeName: string): NetworkComponentType | null { const componentType = this.componentRegistry.get(typeName); if (!componentType) { - console.warn(`[SnapshotManager] 组件类型 ${typeName} 未注册,请先调用 registerComponentType() 注册`); + SnapshotManager.logger.warn(`组件类型 ${typeName} 未注册,请先调用 registerComponentType() 注册`); return null; } return componentType; @@ -414,7 +416,7 @@ export class SnapshotManager { public initializeProtobuf(protobufJs: any): void { if (this.protobufSerializer) { this.protobufSerializer.initialize(protobufJs); - console.log('[SnapshotManager] Protobuf支持已手动启用'); + SnapshotManager.logger.info('Protobuf支持已手动启用'); } } @@ -425,7 +427,7 @@ export class SnapshotManager { */ public registerComponentType(constructor: NetworkComponentType): void { this.componentRegistry.autoRegister(constructor); - console.log(`[SnapshotManager] 已注册组件类型: ${constructor.name}`); + SnapshotManager.logger.debug(`已注册组件类型: ${constructor.name}`); } /** @@ -597,7 +599,7 @@ export class SnapshotManager { // 查找现有组件 const componentType = this.getComponentType(componentSnapshot.type); if (!componentType) { - console.warn(`[SnapshotManager] 组件类型 ${componentSnapshot.type} 未注册,无法恢复`); + SnapshotManager.logger.warn(`组件类型 ${componentSnapshot.type} 未注册,无法恢复`); return; } @@ -605,7 +607,7 @@ export class SnapshotManager { if (!component) { // 组件不存在,需要创建 - console.warn(`[SnapshotManager] 组件 ${componentSnapshot.type} 不存在于实体 ${entity.name},无法恢复`); + SnapshotManager.logger.warn(`组件 ${componentSnapshot.type} 不存在于实体 ${entity.name},无法恢复`); return; } diff --git a/packages/network/src/SyncVar/SyncVarDecorator.ts b/packages/network/src/SyncVar/SyncVarDecorator.ts index 7eed74e4..73131fc5 100644 --- a/packages/network/src/SyncVar/SyncVarDecorator.ts +++ b/packages/network/src/SyncVar/SyncVarDecorator.ts @@ -1,4 +1,7 @@ import 'reflect-metadata'; +import { createLogger } from '@esengine/ecs-framework'; + +const logger = createLogger('SyncVarDecorator'); /** * SyncVar配置选项 @@ -151,7 +154,8 @@ export function getSyncVarMetadataForProperty(target: any, propertyKey: string): * public isReady: boolean = false; * * onNameChanged(oldName: string, newName: string) { - * console.log(`Name changed: ${oldName} -> ${newName}`); + * const logger = createLogger('PlayerComponent'); + * logger.info(`Name changed: ${oldName} -> ${newName}`); * } * } * ``` @@ -165,7 +169,7 @@ export function SyncVar(options: SyncVarOptions = {}): PropertyDecorator { // 获取属性类型 const type = Reflect.getMetadata('design:type', target, propertyKey); if (!type) { - console.warn(`[SyncVar] 无法获取属性 ${propertyKey} 的类型信息`); + logger.warn(`无法获取属性 ${propertyKey} 的类型信息`); } // 获取现有元数据 @@ -174,7 +178,7 @@ export function SyncVar(options: SyncVarOptions = {}): PropertyDecorator { // 检查是否已经存在 const existingIndex = existingMetadata.findIndex(m => m.propertyKey === propertyKey); if (existingIndex !== -1) { - console.warn(`[SyncVar] 属性 ${propertyKey} 已经被标记为SyncVar,将覆盖配置`); + logger.warn(`属性 ${propertyKey} 已经被标记为SyncVar,将覆盖配置`); existingMetadata[existingIndex].options = options; existingMetadata[existingIndex].type = type; } else { @@ -194,7 +198,7 @@ export function SyncVar(options: SyncVarOptions = {}): PropertyDecorator { // 保存元数据 setSyncVarMetadata(target.constructor, existingMetadata); - console.log(`[SyncVar] 注册同步变量: ${target.constructor.name}.${propertyKey}, 字段编号: ${existingMetadata.find(m => m.propertyKey === propertyKey)?.fieldNumber}`); + logger.debug(`注册同步变量: ${target.constructor.name}.${propertyKey}, 字段编号: ${existingMetadata.find(m => m.propertyKey === propertyKey)?.fieldNumber}`); }; } diff --git a/packages/network/src/SyncVar/SyncVarFactory.ts b/packages/network/src/SyncVar/SyncVarFactory.ts index 581bbd7f..ede4f1de 100644 --- a/packages/network/src/SyncVar/SyncVarFactory.ts +++ b/packages/network/src/SyncVar/SyncVarFactory.ts @@ -1,6 +1,7 @@ import { createSyncVarProxy } from './SyncVarProxy'; import { getSyncVarMetadata } from './SyncVarDecorator'; import { INetworkSyncable } from '../types/NetworkTypes'; +import { createLogger } from '@esengine/ecs-framework'; /** * SyncVar工厂函数 @@ -16,6 +17,8 @@ import { INetworkSyncable } from '../types/NetworkTypes'; * @param args - 构造函数参数 * @returns 带代理的组件实例 */ +const logger = createLogger('SyncVarFactory'); + export function createNetworkComponent( ComponentClass: new (...args: any[]) => T, ...args: any[] @@ -36,7 +39,7 @@ export function createNetworkComponent( debugLog: false // 可以根据需要启用调试 }); - console.log(`[SyncVarFactory] 为 ${ComponentClass.name} 创建了SyncVar代理,包含 ${metadata.length} 个同步字段`); + logger.debug(`为 ${ComponentClass.name} 创建了SyncVar代理,包含 ${metadata.length} 个同步字段`); return proxy; } diff --git a/packages/network/src/SyncVar/SyncVarManager.ts b/packages/network/src/SyncVar/SyncVarManager.ts index 71c97bdc..76113a87 100644 --- a/packages/network/src/SyncVar/SyncVarManager.ts +++ b/packages/network/src/SyncVar/SyncVarManager.ts @@ -12,6 +12,7 @@ import { NetworkComponentType, TypeGuards } from '../types/NetworkTypes'; +import { createLogger } from '@esengine/ecs-framework'; /** * SyncVar变化记录 @@ -83,6 +84,7 @@ export interface SyncVarSyncData { */ export class SyncVarManager { private static _instance: SyncVarManager | null = null; + private static readonly logger = createLogger('SyncVarManager'); /** * 组件实例的SyncVar变化监听器 @@ -133,7 +135,7 @@ export class SyncVarManager { } if (validationErrors.length > 0) { - console.error(`[SyncVarManager] 组件 ${component.constructor.name} 的SyncVar配置错误:`, validationErrors); + SyncVarManager.logger.error(`组件 ${component.constructor.name} 的SyncVar配置错误:`, validationErrors); return false; } @@ -141,7 +143,7 @@ export class SyncVarManager { this._componentChanges.set(componentId, []); this._lastSyncTimes.set(componentId, new Map()); - console.log(`[SyncVarManager] 初始化组件 ${component.constructor.name} 的SyncVar系统,共 ${metadata.length} 个同步变量`); + SyncVarManager.logger.info(`初始化组件 ${component.constructor.name} 的SyncVar系统,共 ${metadata.length} 个同步变量`); return true; } @@ -174,13 +176,13 @@ export class SyncVarManager { const metadata = getSyncVarMetadataForProperty(component, propertyKey); if (!metadata) { - console.warn(`[SyncVarManager] 属性 ${propertyKey} 不是SyncVar`); + SyncVarManager.logger.warn(`属性 ${propertyKey} 不是SyncVar`); return; } // 检查值是否真的发生了变化 if (!TypeGuards.isSyncVarValue(oldValue) || !TypeGuards.isSyncVarValue(newValue)) { - console.warn(`[SyncVarManager] 无效的SyncVar值类型: ${typeof oldValue}, ${typeof newValue}`); + SyncVarManager.logger.warn(`无效的SyncVar值类型: ${typeof oldValue}, ${typeof newValue}`); return; } @@ -195,14 +197,14 @@ export class SyncVarManager { if (metadata.options.throttleMs && metadata.options.throttleMs > 0) { if (now - lastSyncTime < metadata.options.throttleMs) { - console.log(`[SyncVarManager] 属性 ${propertyKey} 变化过于频繁,跳过同步`); + SyncVarManager.logger.debug(`属性 ${propertyKey} 变化过于频繁,跳过同步`); return; } } // 检查权限 if (metadata.options.authorityOnly && !this.hasAuthority(component)) { - console.warn(`[SyncVarManager] 属性 ${propertyKey} 需要权限才能修改,但当前没有权限`); + SyncVarManager.logger.warn(`属性 ${propertyKey} 需要权限才能修改,但当前没有权限`); return; } @@ -229,7 +231,7 @@ export class SyncVarManager { lastSyncTimes.set(propertyKey, now); } - console.log(`[SyncVarManager] 记录变化: ${component.constructor.name}.${propertyKey} = ${newValue} (was ${oldValue})`); + SyncVarManager.logger.debug(`记录变化: ${component.constructor.name}.${propertyKey} = ${newValue} (was ${oldValue})`); // 触发hook回调 this.triggerHook(component, metadata, oldValue, newValue); @@ -294,7 +296,7 @@ export class SyncVarManager { data: serializedData }); } catch (error) { - console.error(`[SyncVarManager] 序列化失败 ${change.propertyKey}:`, error); + SyncVarManager.logger.error(`序列化失败 ${change.propertyKey}:`, error); } } @@ -322,7 +324,7 @@ export class SyncVarManager { for (const update of syncData.fieldUpdates) { const meta = metadataMap.get(update.fieldNumber); if (!meta) { - console.warn(`[SyncVarManager] 未找到字段编号 ${update.fieldNumber} 的元数据`); + SyncVarManager.logger.warn(`未找到字段编号 ${update.fieldNumber} 的元数据`); continue; } @@ -336,9 +338,9 @@ export class SyncVarManager { // 触发hook回调 this.triggerHook(component, meta, oldValue, newValue); - console.log(`[SyncVarManager] 应用同步: ${component.constructor.name}.${meta.propertyKey} = ${newValue}`); + SyncVarManager.logger.debug(`应用同步: ${component.constructor.name}.${meta.propertyKey} = ${newValue}`); } catch (error) { - console.error(`[SyncVarManager] 反序列化失败 ${meta.propertyKey}:`, error); + SyncVarManager.logger.error(`反序列化失败 ${meta.propertyKey}:`, error); } } } @@ -421,7 +423,7 @@ export class SyncVarManager { private shouldSync(component: any, metadata: SyncVarMetadata): boolean { // 权限检查:权威字段只有在有权限时才同步 if (metadata.options.authorityOnly && !this.hasAuthority(component)) { - console.log(`[SyncVarManager] 字段 ${metadata.propertyKey} 是权威字段,但当前没有权限,跳过同步`); + SyncVarManager.logger.debug(`字段 ${metadata.propertyKey} 是权威字段,但当前没有权限,跳过同步`); return false; } @@ -457,7 +459,7 @@ export class SyncVarManager { try { hookFunction.call(component, oldValue, newValue); } catch (error) { - console.error(`[SyncVarManager] Hook函数执行失败 ${metadata.options.hook}:`, error); + SyncVarManager.logger.error(`Hook函数执行失败 ${metadata.options.hook}:`, error); } } } @@ -641,7 +643,7 @@ export class SyncVarManager { syncSequence ); - console.log(`[SyncVarManager] 创建SyncVar更新消息: ${component.constructor.name}, ${fieldUpdates.length} 个字段`); + SyncVarManager.logger.debug(`创建SyncVar更新消息: ${component.constructor.name}, ${fieldUpdates.length} 个字段`); return message; } @@ -653,7 +655,7 @@ export class SyncVarManager { */ public applySyncVarUpdateMessage(component: any, message: SyncVarUpdateMessage): void { if (message.componentType !== component.constructor.name) { - console.warn(`[SyncVarManager] 组件类型不匹配: 期望 ${component.constructor.name}, 收到 ${message.componentType}`); + SyncVarManager.logger.warn(`组件类型不匹配: 期望 ${component.constructor.name}, 收到 ${message.componentType}`); return; } @@ -663,7 +665,7 @@ export class SyncVarManager { for (const fieldUpdate of message.fieldUpdates) { const meta = metadataMap.get(fieldUpdate.fieldNumber); if (!meta) { - console.warn(`[SyncVarManager] 未找到字段编号 ${fieldUpdate.fieldNumber} 的元数据`); + SyncVarManager.logger.warn(`未找到字段编号 ${fieldUpdate.fieldNumber} 的元数据`); continue; } @@ -672,7 +674,7 @@ export class SyncVarManager { if (fieldUpdate.authorityOnly && NetworkEnvironment.isClient && !this.hasAuthority(component)) { // 如果这是来自服务端的更新,则允许应用 // 这里简单实现:客户端接受所有权威字段的更新 - console.log(`[SyncVarManager] 客户端接受权威字段更新: ${fieldUpdate.propertyKey}`); + SyncVarManager.logger.debug(`客户端接受权威字段更新: ${fieldUpdate.propertyKey}`); } try { @@ -684,9 +686,9 @@ export class SyncVarManager { // 触发hook回调 this.triggerHook(component, meta, oldValue, fieldUpdate.newValue); - console.log(`[SyncVarManager] 应用SyncVar消息更新: ${component.constructor.name}.${meta.propertyKey} = ${fieldUpdate.newValue}`); + SyncVarManager.logger.debug(`应用SyncVar消息更新: ${component.constructor.name}.${meta.propertyKey} = ${fieldUpdate.newValue}`); } catch (error) { - console.error(`[SyncVarManager] 应用SyncVar更新失败 ${meta.propertyKey}:`, error); + SyncVarManager.logger.error(`应用SyncVar更新失败 ${meta.propertyKey}:`, error); } } diff --git a/packages/network/src/SyncVar/SyncVarMessageHandler.ts b/packages/network/src/SyncVar/SyncVarMessageHandler.ts index 8f04eebc..8791aef5 100644 --- a/packages/network/src/SyncVar/SyncVarMessageHandler.ts +++ b/packages/network/src/SyncVar/SyncVarMessageHandler.ts @@ -4,7 +4,7 @@ import { NetworkConnection } from '../Core/NetworkConnection'; import { NetworkIdentityRegistry } from '../Core/NetworkIdentity'; import { SyncVarManager } from './SyncVarManager'; import { NetworkEnvironment } from '../Core/NetworkEnvironment'; -import { ComponentRegistry } from '@esengine/ecs-framework'; +import { ComponentRegistry, createLogger } from '@esengine/ecs-framework'; import { NetworkManager } from '../Core/NetworkManager'; /** @@ -13,6 +13,7 @@ import { NetworkManager } from '../Core/NetworkManager'; * 处理接收到的SyncVar更新消息,自动查找目标网络对象并应用更新 */ export class SyncVarMessageHandler implements IMessageHandler { + private static readonly logger = createLogger('SyncVarMessageHandler'); private _processedMessages: Set = new Set(); private _maxProcessedCache: number = 1000; @@ -27,7 +28,7 @@ export class SyncVarMessageHandler implements IMessageHandler now + 5000 || message.timestamp < now - maxAge) { - console.warn(`[SyncVarMessageHandler] 消息时间戳异常: ${message.timestamp}, 当前: ${now}`); + SyncVarMessageHandler.logger.warn(` 消息时间戳异常: ${message.timestamp}, 当前: ${now}`); return false; } @@ -143,7 +144,7 @@ export class SyncVarMessageHandler implements IMessageHandler update.authorityOnly); if (hasAuthorityOnlyUpdates) { - console.warn(`[SyncVarMessageHandler] 非拥有者 ${connection.connectionId} 尝试修改权威字段`); + SyncVarMessageHandler.logger.warn(` 非拥有者 ${connection.connectionId} 尝试修改权威字段`); return false; } } @@ -165,7 +166,7 @@ export class SyncVarMessageHandler implements IMessageHandler 0) { - console.log(`[SyncVarMessageHandler] 成功转发消息给 ${successCount} 个其他客户端 (发送者: ${senderConnection.connectionId})`); + SyncVarMessageHandler.logger.debug(` 成功转发消息给 ${successCount} 个其他客户端 (发送者: ${senderConnection.connectionId})`); } else { - console.log(`[SyncVarMessageHandler] 没有其他客户端需要转发消息 (发送者: ${senderConnection.connectionId})`); + SyncVarMessageHandler.logger.debug(` 没有其他客户端需要转发消息 (发送者: ${senderConnection.connectionId})`); } } catch (error) { - console.error(`[SyncVarMessageHandler] 转发消息失败 (发送者: ${senderConnection.connectionId}):`, error); + SyncVarMessageHandler.logger.error(`转发消息失败 (发送者: ${senderConnection.connectionId}):`, error); } } @@ -267,7 +268,7 @@ export class SyncVarMessageHandler implements IMessageHandler 0) { this._stats.messagesBlocked++; - console.log(`[SyncVarOptimizer] 消息被距离剔除阻止: ${message.networkId}`); + SyncVarOptimizer.logger.debug(` 消息被距离剔除阻止: ${message.networkId}`); return; } @@ -393,7 +395,7 @@ export class SyncVarOptimizer { this._messageMerger.addMessage(message, (mergedMessage) => { if (mergedMessage !== message) { this._stats.messagesMerged++; - console.log(`[SyncVarOptimizer] 消息已合并: ${message.networkId}`); + SyncVarOptimizer.logger.debug(` 消息已合并: ${message.networkId}`); } onOptimized([mergedMessage], validObservers); @@ -412,7 +414,7 @@ export class SyncVarOptimizer { */ public configure(config: Partial): void { this._config = { ...this._config, ...config }; - console.log('[SyncVarOptimizer] 配置已更新:', this._config); + SyncVarOptimizer.logger.info(' 配置已更新:', this._config); } /** diff --git a/packages/network/src/SyncVar/SyncVarProxy.ts b/packages/network/src/SyncVar/SyncVarProxy.ts index 372c430c..6476485e 100644 --- a/packages/network/src/SyncVar/SyncVarProxy.ts +++ b/packages/network/src/SyncVar/SyncVarProxy.ts @@ -1,6 +1,7 @@ import { getSyncVarMetadata, isSyncVar } from './SyncVarDecorator'; import { SyncVarManager } from './SyncVarManager'; import { INetworkSyncable, SyncVarValue, TypeGuards } from '../types/NetworkTypes'; +import { createLogger } from '@esengine/ecs-framework'; /** * SyncVar代理配置 @@ -36,9 +37,11 @@ export function createSyncVarProxy( // 检查目标是否有SyncVar const metadata = getSyncVarMetadata(target.constructor); + const logger = createLogger('SyncVarProxy'); + if (metadata.length === 0) { if (debugLog) { - console.log(`[SyncVarProxy] 对象 ${target.constructor.name} 没有SyncVar,返回原对象`); + logger.debug(`对象 ${target.constructor.name} 没有SyncVar,返回原对象`); } return target; } @@ -47,7 +50,7 @@ export function createSyncVarProxy( syncVarManager.initializeComponent(target); if (debugLog) { - console.log(`[SyncVarProxy] 为 ${target.constructor.name} 创建代理,SyncVar字段:`, + logger.debug(`为 ${target.constructor.name} 创建代理,SyncVar字段:`, metadata.map(m => m.propertyKey)); } @@ -81,7 +84,7 @@ export function createSyncVarProxy( const value = Reflect.get(obj, prop); if (debugLog && isSyncVar(obj, propertyKey)) { - console.log(`[SyncVarProxy] GET ${obj.constructor.name}.${propertyKey} = ${value}`); + logger.debug(`GET ${obj.constructor.name}.${propertyKey} = ${value}`); } return value; @@ -117,7 +120,7 @@ export function createSyncVarProxy( const oldValue = originalValues.get(propertyKey); if (debugLog) { - console.log(`[SyncVarProxy] SET ${obj.constructor.name}.${propertyKey} = ${newValue} (was ${oldValue})`); + logger.debug(`SET ${obj.constructor.name}.${propertyKey} = ${newValue} (was ${oldValue})`); } // 设置新值 @@ -133,7 +136,7 @@ export function createSyncVarProxy( syncVarManager.recordChange(obj, propertyKey, oldValue, newValue); } } catch (error) { - console.error(`[SyncVarProxy] 记录SyncVar变化失败:`, error); + logger.error(`记录SyncVar变化失败:`, error); } } @@ -147,7 +150,7 @@ export function createSyncVarProxy( const propertyKey = prop as string; if (typeof prop === 'string' && isSyncVar(obj, propertyKey)) { - console.warn(`[SyncVarProxy] 尝试删除SyncVar属性 ${propertyKey},这可能会导致同步问题`); + logger.warn(`尝试删除SyncVar属性 ${propertyKey},这可能会导致同步问题`); } return Reflect.deleteProperty(obj, prop); @@ -180,7 +183,7 @@ export function createSyncVarProxy( (proxy as T & { _syncVarProxied: boolean; _syncVarOptions: SyncVarProxyOptions })._syncVarOptions = options; if (debugLog) { - console.log(`[SyncVarProxy] ${target.constructor.name} 代理创建完成`); + logger.debug(`${target.constructor.name} 代理创建完成`); } return proxy; @@ -229,7 +232,8 @@ export function destroySyncVarProxy(proxy: INetworkSyncable & { _syncVarProxied? proxy._syncVarProxied = false; proxy._syncVarDestroyed = true; - console.log(`[SyncVarProxy] ${proxy.constructor?.name || 'Unknown'} 代理已销毁`); + const logger = createLogger('SyncVarProxy'); + logger.debug(`${proxy.constructor?.name || 'Unknown'} 代理已销毁`); } /** diff --git a/packages/network/src/SyncVar/SyncVarSyncScheduler.ts b/packages/network/src/SyncVar/SyncVarSyncScheduler.ts index 32362a71..a38e7ca8 100644 --- a/packages/network/src/SyncVar/SyncVarSyncScheduler.ts +++ b/packages/network/src/SyncVar/SyncVarSyncScheduler.ts @@ -2,7 +2,7 @@ import { SyncVarManager } from './SyncVarManager'; import { NetworkIdentityRegistry, NetworkIdentity } from '../Core/NetworkIdentity'; import { SyncVarUpdateMessage } from '../Messaging/MessageTypes'; import { NetworkEnvironment } from '../Core/NetworkEnvironment'; -import { ComponentRegistry } from '@esengine/ecs-framework'; +import { ComponentRegistry, createLogger } from '@esengine/ecs-framework'; import { NetworkComponent } from '../NetworkComponent'; /** @@ -69,6 +69,7 @@ export class DefaultSyncPriorityCalculator implements ISyncPriorityCalculator { * 支持批处理、优先级排序和性能优化 */ export class SyncVarSyncScheduler { + private static readonly logger = createLogger('SyncVarSyncScheduler'); private static _instance: SyncVarSyncScheduler | null = null; private _config: SyncVarSyncConfig; @@ -130,7 +131,7 @@ export class SyncVarSyncScheduler { this.start(); } - console.log('[SyncVarSyncScheduler] 调度器配置已更新:', this._config); + SyncVarSyncScheduler.logger.debug('调度器配置已更新:', this._config); } /** @@ -140,7 +141,7 @@ export class SyncVarSyncScheduler { */ public setPriorityCalculator(calculator: ISyncPriorityCalculator): void { this._priorityCalculator = calculator; - console.log('[SyncVarSyncScheduler] 优先级计算器已更新'); + SyncVarSyncScheduler.logger.debug('优先级计算器已更新'); } /** @@ -150,7 +151,7 @@ export class SyncVarSyncScheduler { */ public setMessageSendCallback(callback: (message: SyncVarUpdateMessage) => Promise): void { this._messageSendCallback = callback; - console.log('[SyncVarSyncScheduler] 消息发送回调已设置'); + SyncVarSyncScheduler.logger.debug('消息发送回调已设置'); } /** @@ -158,7 +159,7 @@ export class SyncVarSyncScheduler { */ public start(): void { if (this._isRunning) { - console.warn('[SyncVarSyncScheduler] 调度器已经在运行'); + SyncVarSyncScheduler.logger.warn('调度器已经在运行'); return; } @@ -170,7 +171,7 @@ export class SyncVarSyncScheduler { this.performSyncCycle(); }, this._config.syncInterval); - console.log(`[SyncVarSyncScheduler] 调度器已启动,同步间隔: ${this._config.syncInterval}ms`); + SyncVarSyncScheduler.logger.info(`调度器已启动,同步间隔: ${this._config.syncInterval}ms`); } /** @@ -188,7 +189,7 @@ export class SyncVarSyncScheduler { this._syncTimer = null; } - console.log('[SyncVarSyncScheduler] 调度器已停止'); + SyncVarSyncScheduler.logger.info('调度器已停止'); } /** @@ -235,7 +236,7 @@ export class SyncVarSyncScheduler { } catch (error) { this._stats.errors++; - console.error('[SyncVarSyncScheduler] 同步周期执行失败:', error); + SyncVarSyncScheduler.logger.error('同步周期执行失败:', error); } } @@ -285,7 +286,7 @@ export class SyncVarSyncScheduler { }); } } catch (error) { - console.error(`[SyncVarSyncScheduler] 处理网络对象失败: ${identity.networkId}`, error); + SyncVarSyncScheduler.logger.error(`处理网络对象失败: ${identity.networkId}`, error); } } @@ -298,7 +299,7 @@ export class SyncVarSyncScheduler { private getNetworkComponents(identity: NetworkIdentity): NetworkComponent[] { const entity = identity.entity; if (!entity) { - console.warn(`[SyncVarSyncScheduler] NetworkIdentity ${identity.networkId} 缺少Entity引用`); + SyncVarSyncScheduler.logger.warn(`NetworkIdentity ${identity.networkId} 缺少Entity引用`); return []; } @@ -318,7 +319,7 @@ export class SyncVarSyncScheduler { } } } catch (error) { - console.error(`[SyncVarSyncScheduler] 获取网络组件失败 (${identity.networkId}):`, error); + SyncVarSyncScheduler.logger.error(`获取网络组件失败 (${identity.networkId}):`, error); } return networkComponents; @@ -383,7 +384,7 @@ export class SyncVarSyncScheduler { } } catch (error) { - console.error(`[SyncVarSyncScheduler] 处理同步候选对象失败: ${candidate.identity.networkId}`, error); + SyncVarSyncScheduler.logger.error(`处理同步候选对象失败: ${candidate.identity.networkId}`, error); } } @@ -398,7 +399,7 @@ export class SyncVarSyncScheduler { */ private async sendMessageBatch(messages: SyncVarUpdateMessage[]): Promise { if (!this._messageSendCallback) { - console.warn('[SyncVarSyncScheduler] 没有设置消息发送回调,消息被丢弃'); + SyncVarSyncScheduler.logger.warn('没有设置消息发送回调,消息被丢弃'); return; } @@ -407,7 +408,7 @@ export class SyncVarSyncScheduler { await this._messageSendCallback(message); this._stats.totalMessagesSent++; } catch (error) { - console.error('[SyncVarSyncScheduler] 发送SyncVar消息失败:', error); + SyncVarSyncScheduler.logger.error('发送SyncVar消息失败:', error); this._stats.errors++; } } @@ -458,7 +459,7 @@ export class SyncVarSyncScheduler { lastCycleTime: 0, errors: 0 }; - console.log('[SyncVarSyncScheduler] 统计信息已重置'); + SyncVarSyncScheduler.logger.debug('统计信息已重置'); } /** diff --git a/packages/network/src/types/global.d.ts b/packages/network/src/types/global.d.ts index 0153203f..c6dd0165 100644 --- a/packages/network/src/types/global.d.ts +++ b/packages/network/src/types/global.d.ts @@ -1,49 +1,11 @@ /** - * 全局宏定义类型声明 - * - * 这些宏变量由构建工具在编译时定义,用于条件编译 - * 支持在客户端构建时移除服务端代码,在服务端构建时移除客户端代码 + * 网络库编译时宏定义 + * 这些宏在构建时会被具体的布尔值替换,用于实现客户端/服务端代码的编译时过滤 */ -/** - * 客户端构建标志 - * - * 当构建客户端版本时为true,服务端版本时为false - * 使用示例: - * ```typescript - * if (__CLIENT__) { - * // 只在客户端构建中包含的代码 - * this.renderUI(); - * } - * ``` - */ -declare const __CLIENT__: boolean; +declare global { + const __CLIENT__: boolean; + const __SERVER__: boolean; +} -/** - * 服务端构建标志 - * - * 当构建服务端版本时为true,客户端版本时为false - * 使用示例: - * ```typescript - * if (__SERVER__) { - * // 只在服务端构建中包含的代码 - * this.validateInput(); - * this.saveToDatabase(); - * } - * ``` - */ -declare const __SERVER__: boolean; - -/** - * 开发环境标志(可选) - * - * 当在开发环境时为true,生产环境时为false - */ -declare const __DEV__: boolean; - -/** - * 生产环境标志(可选) - * - * 当在生产环境时为true,开发环境时为false - */ -declare const __PROD__: boolean; \ No newline at end of file +export {}; \ No newline at end of file diff --git a/packages/network/tsconfig.json b/packages/network/tsconfig.json index 51658b56..86d8ea1a 100644 --- a/packages/network/tsconfig.json +++ b/packages/network/tsconfig.json @@ -30,11 +30,20 @@ "downlevelIteration": true, "isolatedModules": false, "allowJs": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "baseUrl": ".", + "paths": { + "@esengine/ecs-framework": ["../core/src"], + "@esengine/ecs-framework/*": ["../core/src/*"] + } }, "include": [ "src/**/*" ], + "typeRoots": [ + "./node_modules/@types", + "./src/types" + ], "exclude": [ "node_modules", "bin",