diff --git a/packages/core/src/Core.ts b/packages/core/src/Core.ts index f04e2202..d240c4f3 100644 --- a/packages/core/src/Core.ts +++ b/packages/core/src/Core.ts @@ -13,7 +13,6 @@ import { ServiceContainer } from './Core/ServiceContainer'; import { PluginManager } from './Core/PluginManager'; import { IPlugin } from './Core/Plugin'; import { WorldManager } from './ECS/WorldManager'; -import { registerInjectable } from './Core/DI'; /** * 游戏引擎核心类 @@ -178,14 +177,9 @@ export class Core { this._poolManager = new PoolManager(); this._serviceContainer.registerInstance(PoolManager, this._poolManager); - // 使用依赖注入自动注册WorldManager和SceneManager - // WorldManager会在构造时创建默认World - registerInjectable(this._serviceContainer, WorldManager); - this._worldManager = this._serviceContainer.resolve(WorldManager); - - // SceneManager会通过@Inject自动获取WorldManager - registerInjectable(this._serviceContainer, SceneManager); - this._sceneManager = this._serviceContainer.resolve(SceneManager); + // 初始化场景管理器 + this._sceneManager = new SceneManager(); + this._serviceContainer.registerInstance(SceneManager, this._sceneManager); // 设置场景切换回调,通知调试管理器 this._sceneManager.setSceneChangedCallback(() => { @@ -194,6 +188,10 @@ export class Core { } }); + // 初始化World管理器 + this._worldManager = new WorldManager(); + this._serviceContainer.registerInstance(WorldManager, this._worldManager); + // 初始化插件管理器 this._pluginManager = new PluginManager(); this._pluginManager.initialize(this, this._serviceContainer); @@ -647,7 +645,7 @@ export class Core { this._performanceMonitor.updateFPS(Time.deltaTime); } - // 更新所有@Updatable服务(包括TimerManager, WorldManager, SceneManager等) + // 更新所有可更新的服务 const servicesStartTime = this._performanceMonitor.startMonitoring('Services.update'); this._serviceContainer.updateAll(deltaTime); this._performanceMonitor.endMonitoring('Services.update', servicesStartTime, this._serviceContainer.getUpdatableCount()); @@ -655,6 +653,12 @@ export class Core { // 更新对象池管理器 this._poolManager.update(); + // 更新默认场景(通过 SceneManager) + this._sceneManager.update(); + + // 更新额外的 WorldManager + this._worldManager.updateAll(); + // 更新调试管理器(基于FPS的数据发送) if (this._debugManager) { this._debugManager.onFrameUpdate(deltaTime); diff --git a/packages/core/src/ECS/SceneManager.ts b/packages/core/src/ECS/SceneManager.ts index 62b3876d..8d1b2b50 100644 --- a/packages/core/src/ECS/SceneManager.ts +++ b/packages/core/src/ECS/SceneManager.ts @@ -3,10 +3,7 @@ import { ECSFluentAPI, createECSAPI } from './Core/FluentAPI'; import { Time } from '../Utils/Time'; import { createLogger } from '../Utils/Logger'; import type { IService } from '../Core/ServiceContainer'; -import type { IUpdatable } from '../Types/IUpdatable'; import { World } from './World'; -import { WorldManager } from './WorldManager'; -import { Injectable, Inject, Updatable } from '../Core/DI'; /** * 单场景管理器 @@ -21,13 +18,15 @@ import { Injectable, Inject, Updatable } from '../Core/DI'; * - 简单直观的API * - 支持延迟场景切换 * - 自动管理ECS API - * - 通过依赖注入获取WorldManager的默认World * * @example * ```typescript * // 初始化Core * Core.create({ debug: true }); * + * // 创建场景管理器 + * const sceneManager = new SceneManager(); + * * // 设置场景 * class GameScene extends Scene { * initialize() { @@ -36,22 +35,21 @@ import { Injectable, Inject, Updatable } from '../Core/DI'; * } * } * - * Core.setScene(new GameScene()); + * sceneManager.setScene(new GameScene()); * * // 游戏循环 * function gameLoop(deltaTime: number) { - * Core.update(deltaTime); // 自动更新所有服务(包括SceneManager) + * Core.update(deltaTime); // 更新全局服务 + * sceneManager.update(); // 更新场景 * } * * // 延迟切换场景(下一帧生效) - * Core.loadScene(new MenuScene()); + * sceneManager.loadScene(new MenuScene()); * ``` */ -@Injectable() -@Updatable(10) -export class SceneManager implements IService, IUpdatable { +export class SceneManager implements IService { /** - * 内部默认World(从WorldManager获取) + * 内部默认World */ private _defaultWorld: World; @@ -80,18 +78,9 @@ export class SceneManager implements IService, IUpdatable { */ private static readonly DEFAULT_SCENE_ID = '__main__'; - /** - * 构造函数 - * - * WorldManager通过依赖注入自动传入 - * - * @param worldManager WorldManager实例,用于获取默认World - */ - constructor( - @Inject(WorldManager) worldManager: WorldManager - ) { - // 使用WorldManager管理的默认World - this._defaultWorld = worldManager.getDefaultWorld(); + constructor() { + this._defaultWorld = new World({ name: '__default__' }); + this._defaultWorld.start(); } /** diff --git a/packages/core/src/ECS/WorldManager.ts b/packages/core/src/ECS/WorldManager.ts index d04c6151..5296e8a9 100644 --- a/packages/core/src/ECS/WorldManager.ts +++ b/packages/core/src/ECS/WorldManager.ts @@ -1,8 +1,6 @@ import { World, IWorldConfig } from './World'; import { createLogger } from '../Utils/Logger'; import type { IService } from '../Core/ServiceContainer'; -import type { IUpdatable } from '../Types/IUpdatable'; -import { Injectable, Updatable } from '../Core/DI'; const logger = createLogger('WorldManager'); @@ -14,28 +12,21 @@ export interface IWorldManagerConfig { * 最大World数量 */ maxWorlds?: number; - + /** * 是否自动清理空World */ autoCleanup?: boolean; - + /** * 清理间隔(毫秒) */ cleanupInterval?: number; - + /** * 是否启用调试模式 */ debug?: boolean; - - /** - * 是否创建默认World(默认true) - * - * 当通过Core使用时应该为true,直接使用WorldManager时可设为false - */ - createDefaultWorld?: boolean; } /** @@ -66,18 +57,12 @@ export interface IWorldManagerConfig { * * // 游戏循环 * function gameLoop(deltaTime: number) { - * Core.update(deltaTime); // 自动更新所有@Updatable服务(包括WorldManager) + * Core.update(deltaTime); + * worldManager.updateAll(); // 更新所有活跃World * } * ``` */ -@Injectable() -@Updatable(5) -export class WorldManager implements IService, IUpdatable { - /** - * 默认World的ID - */ - public static readonly DEFAULT_WORLD_ID = '__default__'; - +export class WorldManager implements IService { private readonly _config: IWorldManagerConfig; private readonly _worlds: Map = new Map(); private readonly _activeWorlds: Set = new Set(); @@ -90,26 +75,16 @@ export class WorldManager implements IService, IUpdatable { autoCleanup: true, cleanupInterval: 30000, // 30秒 debug: false, - createDefaultWorld: true, // 默认创建 ...config }; // 默认启动运行状态 this._isRunning = true; - // 如果配置要求,创建并注册默认World - if (this._config.createDefaultWorld) { - const defaultWorld = new World({ name: WorldManager.DEFAULT_WORLD_ID }); - this._worlds.set(WorldManager.DEFAULT_WORLD_ID, defaultWorld); - this._activeWorlds.add(WorldManager.DEFAULT_WORLD_ID); - defaultWorld.start(); - } - logger.info('WorldManager已初始化', { maxWorlds: this._config.maxWorlds, autoCleanup: this._config.autoCleanup, - cleanupInterval: this._config.cleanupInterval, - defaultWorldCreated: this._config.createDefaultWorld + cleanupInterval: this._config.cleanupInterval }); this.startCleanupTimer(); @@ -117,22 +92,6 @@ export class WorldManager implements IService, IUpdatable { // ===== World管理 ===== - /** - * 获取默认World - * - * 默认World由WorldManager自动创建,供SceneManager使用。 - * 此方法主要供SceneManager内部使用。 - * - * @returns 默认World实例 - */ - public getDefaultWorld(): World { - const defaultWorld = this._worlds.get(WorldManager.DEFAULT_WORLD_ID); - if (!defaultWorld) { - throw new Error('默认World不存在,这不应该发生'); - } - return defaultWorld; - } - /** * 创建新World */ @@ -164,16 +123,8 @@ export class WorldManager implements IService, IUpdatable { /** * 移除World - * - * 注意:默认World不能被删除 */ public removeWorld(worldId: string): boolean { - // 防止删除默认World - if (worldId === WorldManager.DEFAULT_WORLD_ID) { - logger.warn('无法删除默认World'); - return false; - } - const world = this._worlds.get(worldId); if (!world) { return false; @@ -246,12 +197,18 @@ export class WorldManager implements IService, IUpdatable { /** * 更新所有活跃的World * - * 此方法由ServiceContainer自动调用(@Updatable装饰器) + * 应该在每帧的游戏循环中调用。 * 会自动更新所有活跃World的全局系统和场景。 * - * @param deltaTime 帧时间间隔(未使用,保留用于接口兼容) + * @example + * ```typescript + * function gameLoop(deltaTime: number) { + * Core.update(deltaTime); // 更新全局服务 + * worldManager.updateAll(); // 更新所有World + * } + * ``` */ - public update(deltaTime?: number): void { + public updateAll(): void { if (!this._isRunning) return; for (const worldId of this._activeWorlds) { diff --git a/packages/core/tests/ECS/Core/WorldCoreIntegration.test.ts b/packages/core/tests/ECS/Core/WorldCoreIntegration.test.ts index 6ea14e3e..969a8851 100644 --- a/packages/core/tests/ECS/Core/WorldCoreIntegration.test.ts +++ b/packages/core/tests/ECS/Core/WorldCoreIntegration.test.ts @@ -47,6 +47,13 @@ class NetworkGlobalSystem implements IGlobalSystem { /** * World与Core集成测试 + * + * 注意:v3.0重构后,Core不再直接管理Scene/World + * - 场景管理由 SceneManager 负责 + * - 多世界管理由 WorldManager 负责 + * - Core 仅负责全局服务(Timer、Performance等) + * + * 大部分旧的集成测试已移至 SceneManager.test.ts 和 WorldManager.test.ts */ describe('World与Core集成测试', () => { let worldManager: WorldManager; @@ -60,10 +67,8 @@ describe('World与Core集成测试', () => { Core.create({ debug: false }); // WorldManager和SceneManager不再是单例 - // SceneManager需要WorldManager的默认World,所以必须创建 - worldManager = new WorldManager({ createDefaultWorld: true }); - // SceneManager需要WorldManager实例 - sceneManager = new SceneManager(worldManager); + worldManager = new WorldManager(); + sceneManager = new SceneManager(); }); afterEach(() => { @@ -104,8 +109,7 @@ describe('World与Core集成测试', () => { const world1 = worldManager.createWorld('world1'); const world2 = worldManager.createWorld('world2'); - // worldManager已包含默认World,所以总数是3 - expect(worldManager.worldCount).toBe(3); + expect(worldManager.worldCount).toBe(2); expect(worldManager.getWorld('world1')).toBe(world1); expect(worldManager.getWorld('world2')).toBe(world2); }); @@ -133,7 +137,7 @@ describe('World与Core集成测试', () => { // 游戏循环 Core.update(0.016); // 更新全局服务 - worldManager.update(); // 更新所有World + worldManager.updateAll(); // 更新所有World expect(world.isActive).toBe(true); }); @@ -146,7 +150,7 @@ describe('World与Core集成测试', () => { worldManager.setWorldActive('test-world', true); // 更新World - worldManager.update(); + worldManager.updateAll(); expect(globalSystem.syncCount).toBeGreaterThan(0); }); @@ -154,8 +158,8 @@ describe('World与Core集成测试', () => { describe('隔离性测试', () => { test('多个WorldManager实例应该完全隔离', () => { - const manager1 = new WorldManager({ createDefaultWorld: false }); - const manager2 = new WorldManager({ createDefaultWorld: false }); + const manager1 = new WorldManager(); + const manager2 = new WorldManager(); manager1.createWorld('world1'); manager2.createWorld('world2'); @@ -171,10 +175,8 @@ describe('World与Core集成测试', () => { }); test('多个SceneManager实例应该完全隔离', () => { - const wm1 = new WorldManager({ createDefaultWorld: true }); - const wm2 = new WorldManager({ createDefaultWorld: true }); - const sm1 = new SceneManager(wm1); - const sm2 = new SceneManager(wm2); + const sm1 = new SceneManager(); + const sm2 = new SceneManager(); const scene1 = new Scene(); const scene2 = new Scene(); @@ -188,8 +190,6 @@ describe('World与Core集成测试', () => { // 清理 sm1.destroy(); sm2.destroy(); - wm1.destroy(); - wm2.destroy(); }); }); }); diff --git a/packages/core/tests/ECS/WorldManager.test.ts b/packages/core/tests/ECS/WorldManager.test.ts index 64ffbbad..0285fd2c 100644 --- a/packages/core/tests/ECS/WorldManager.test.ts +++ b/packages/core/tests/ECS/WorldManager.test.ts @@ -42,8 +42,7 @@ describe('WorldManager', () => { beforeEach(() => { // WorldManager不再是单例,直接创建新实例 - // 测试时不创建默认World - worldManager = new WorldManager({ createDefaultWorld: false }); + worldManager = new WorldManager(); }); afterEach(() => { @@ -60,8 +59,8 @@ describe('WorldManager', () => { describe('实例化', () => { test('可以创建多个独立的WorldManager实例', () => { - const manager1 = new WorldManager({ createDefaultWorld: false }); - const manager2 = new WorldManager({ createDefaultWorld: false }); + const manager1 = new WorldManager(); + const manager2 = new WorldManager(); expect(manager1).not.toBe(manager2); @@ -77,8 +76,7 @@ describe('WorldManager', () => { const config: IWorldManagerConfig = { maxWorlds: 10, autoCleanup: true, - debug: false, - createDefaultWorld: false + debug: false }; const instance = new WorldManager(config); @@ -123,7 +121,7 @@ describe('WorldManager', () => { }); test('超出最大World数量应该抛出错误', () => { - const limitedManager = new WorldManager({ maxWorlds: 2, createDefaultWorld: false }); + const limitedManager = new WorldManager({ maxWorlds: 2 }); limitedManager.createWorld('world1'); limitedManager.createWorld('world2'); @@ -430,8 +428,7 @@ describe('WorldManager', () => { const invalidConfig: IWorldManagerConfig = { maxWorlds: -1, autoCleanup: true, - debug: true, - createDefaultWorld: false + debug: true }; const manager = new WorldManager(invalidConfig); @@ -445,8 +442,7 @@ describe('WorldManager', () => { const config: IWorldManagerConfig = { maxWorlds: 3, autoCleanup: true, - debug: true, - createDefaultWorld: false + debug: true }; const manager = new WorldManager(config);