# WorldManager

WorldManager 是 ECS Framework 提供的高级世界管理器，用于管理多个完全隔离的游戏世界（World）。每个 World 都是独立的 ECS 环境，可以包含多个场景。

## 适用场景

WorldManager 适合以下高级场景：
- MMO 游戏服务器的多房间管理
- 游戏大厅系统（每个游戏房间完全隔离）
- 服务器端的多游戏实例
- 需要完全隔离的多个游戏环境
- 需要同时运行多个独立世界的应用

## 特点

- 多 World 管理，每个 World 完全独立
- 每个 World 可以包含多个 Scene
- 支持 World 的激活/停用
- 自动清理空 World
- World 级别的全局系统
- 批量操作和查询

## 基本使用

### 初始化

WorldManager 是 Core 的内置服务，通过服务容器获取：

```typescript
import { Core, WorldManager } from '@esengine/ecs-framework';

// 初始化 Core
Core.create({ debug: true });

// 从服务容器获取 WorldManager（Core 已自动创建并注册）
const worldManager = Core.services.resolve(WorldManager);
```

### 创建 World

```typescript
// 创建游戏房间 World
const room1 = worldManager.createWorld('room_001', {
  name: 'GameRoom_001',
  maxScenes: 5,
  debug: true
});

// 激活 World
worldManager.setWorldActive('room_001', true);

// 创建更多房间
const room2 = worldManager.createWorld('room_002', {
  name: 'GameRoom_002',
  maxScenes: 5
});

worldManager.setWorldActive('room_002', true);
```

### 游戏循环

在游戏循环中更新所有活跃的 World：

```typescript
function gameLoop(deltaTime: number) {
  Core.update(deltaTime);        // 更新全局服务
  worldManager.updateAll();      // 更新所有活跃的 World
}

// 启动游戏循环
let lastTime = 0;
setInterval(() => {
  const currentTime = Date.now();
  const deltaTime = (currentTime - lastTime) / 1000;
  lastTime = currentTime;

  gameLoop(deltaTime);
}, 16); // 60 FPS
```

## World 管理

### 创建 World

```typescript
// 基本创建
const world = worldManager.createWorld('worldId');

// 带配置创建
const world = worldManager.createWorld('worldId', {
  name: 'MyWorld',
  maxScenes: 10,
  autoCleanup: true,
  debug: true
});
```

**配置选项（IWorldConfig）**：
- `name?: string` - World 名称
- `maxScenes?: number` - 最大场景数量限制（默认 10）
- `autoCleanup?: boolean` - 是否自动清理空场景（默认 true）
- `debug?: boolean` - 是否启用调试模式（默认 false）

### 获取 World

```typescript
// 通过 ID 获取
const world = worldManager.getWorld('room_001');
if (world) {
  console.log(`World: ${world.name}`);
}

// 获取所有 World
const allWorlds = worldManager.getAllWorlds();
console.log(`共有 ${allWorlds.length} 个 World`);

// 获取所有 World ID
const worldIds = worldManager.getWorldIds();
console.log('World 列表:', worldIds);

// 通过名称查找
const world = worldManager.findWorldByName('GameRoom_001');
```

### 激活和停用 World

```typescript
// 激活 World（开始运行和更新）
worldManager.setWorldActive('room_001', true);

// 停用 World（停止更新但保留数据）
worldManager.setWorldActive('room_001', false);

// 检查 World 是否激活
if (worldManager.isWorldActive('room_001')) {
  console.log('房间正在运行');
}

// 获取所有活跃的 World
const activeWorlds = worldManager.getActiveWorlds();
console.log(`当前有 ${activeWorlds.length} 个活跃 World`);
```

### 移除 World

```typescript
// 移除 World（会自动停用并销毁）
const removed = worldManager.removeWorld('room_001');
if (removed) {
  console.log('World 已移除');
}
```

## World 中的场景管理

每个 World 可以包含多个 Scene 并独立管理它们的生命周期。

### 创建场景

```typescript
const world = worldManager.getWorld('room_001');
if (!world) return;

// 创建场景
const mainScene = world.createScene('main', new MainScene());
const uiScene = world.createScene('ui', new UIScene());
const hudScene = world.createScene('hud', new HUDScene());

// 激活场景
world.setSceneActive('main', true);
world.setSceneActive('ui', true);
world.setSceneActive('hud', false);
```

### 查询场景

```typescript
// 获取特定场景
const mainScene = world.getScene<MainScene>('main');
if (mainScene) {
  console.log(`场景名称: ${mainScene.name}`);
}

// 获取所有场景
const allScenes = world.getAllScenes();
console.log(`World 中共有 ${allScenes.length} 个场景`);

// 获取所有场景 ID
const sceneIds = world.getSceneIds();
console.log('场景列表:', sceneIds);

// 获取活跃场景数量
const activeCount = world.getActiveSceneCount();
console.log(`当前有 ${activeCount} 个活跃场景`);

// 检查场景是否激活
if (world.isSceneActive('main')) {
  console.log('主场景正在运行');
}
```

### 场景切换

World 支持多场景同时运行，也支持场景切换：

```typescript
class GameWorld {
  private world: World;

  constructor(worldManager: WorldManager) {
    this.world = worldManager.createWorld('game', {
      name: 'GameWorld',
      maxScenes: 5
    });

    // 创建所有场景
    this.world.createScene('menu', new MenuScene());
    this.world.createScene('game', new GameScene());
    this.world.createScene('pause', new PauseScene());
    this.world.createScene('gameover', new GameOverScene());

    // 激活 World
    worldManager.setWorldActive('game', true);
  }

  public showMenu(): void {
    this.deactivateAllScenes();
    this.world.setSceneActive('menu', true);
  }

  public startGame(): void {
    this.deactivateAllScenes();
    this.world.setSceneActive('game', true);
  }

  public pauseGame(): void {
    // 游戏场景继续存在但停止更新
    this.world.setSceneActive('game', false);
    // 显示暂停界面
    this.world.setSceneActive('pause', true);
  }

  public resumeGame(): void {
    this.world.setSceneActive('pause', false);
    this.world.setSceneActive('game', true);
  }

  public showGameOver(): void {
    this.deactivateAllScenes();
    this.world.setSceneActive('gameover', true);
  }

  private deactivateAllScenes(): void {
    const sceneIds = this.world.getSceneIds();
    sceneIds.forEach(id => this.world.setSceneActive(id, false));
  }
}
```

### 移除场景

```typescript
// 移除不再需要的场景
const removed = world.removeScene('oldScene');
if (removed) {
  console.log('场景已移除');
}

// 场景会自动调用 end() 方法进行清理
```

## 全局系统

World 支持全局系统，这些系统在 World 级别运行，不依赖特定 Scene。

### 定义全局系统

```typescript
import { IGlobalSystem } from '@esengine/ecs-framework';

// 网络系统（World 级别）
class NetworkSystem implements IGlobalSystem {
  readonly name = 'NetworkSystem';

  private connectionId: string;

  constructor(connectionId: string) {
    this.connectionId = connectionId;
  }

  initialize(): void {
    console.log(`网络系统初始化: ${this.connectionId}`);
    // 建立网络连接
  }

  update(deltaTime?: number): void {
    // 处理网络消息，不依赖任何 Scene
    // 接收和发送网络包
  }

  destroy(): void {
    console.log(`网络系统销毁: ${this.connectionId}`);
    // 关闭网络连接
  }
}

// 物理系统（World 级别）
class PhysicsSystem implements IGlobalSystem {
  readonly name = 'PhysicsSystem';

  initialize(): void {
    console.log('物理系统初始化');
  }

  update(deltaTime?: number): void {
    // 物理模拟，作用于 World 中所有场景
  }

  destroy(): void {
    console.log('物理系统销毁');
  }
}
```

### 使用全局系统

```typescript
const world = worldManager.getWorld('room_001');
if (!world) return;

// 添加全局系统
const networkSystem = world.addGlobalSystem(new NetworkSystem('conn_001'));
const physicsSystem = world.addGlobalSystem(new PhysicsSystem());

// 获取全局系统
const network = world.getGlobalSystem(NetworkSystem);
if (network) {
  console.log('找到网络系统');
}

// 移除全局系统
world.removeGlobalSystem(networkSystem);
```

## 批量操作

### 更新所有 World

```typescript
// 更新所有活跃的 World（应该在游戏循环中调用）
worldManager.updateAll();

// 这会自动更新每个 World 的：
// 1. 全局系统
// 2. 所有活跃场景
```

### 启动和停止

```typescript
// 启动所有 World
worldManager.startAll();

// 停止所有 World
worldManager.stopAll();

// 检查是否正在运行
if (worldManager.isRunning) {
  console.log('WorldManager 正在运行');
}
```

### 查找 World

```typescript
// 使用条件查找
const emptyWorlds = worldManager.findWorlds(world => {
  return world.sceneCount === 0;
});

// 查找活跃的 World
const activeWorlds = worldManager.findWorlds(world => {
  return world.isActive;
});

// 查找特定名称的 World
const world = worldManager.findWorldByName('GameRoom_001');
```

## 统计和监控

### 获取统计信息

```typescript
const stats = worldManager.getStats();

console.log(`总 World 数: ${stats.totalWorlds}`);
console.log(`活跃 World 数: ${stats.activeWorlds}`);
console.log(`总场景数: ${stats.totalScenes}`);
console.log(`总实体数: ${stats.totalEntities}`);
console.log(`总系统数: ${stats.totalSystems}`);

// 查看每个 World 的详细信息
stats.worlds.forEach(worldInfo => {
  console.log(`World: ${worldInfo.name}`);
  console.log(`  场景数: ${worldInfo.sceneCount}`);
  console.log(`  是否活跃: ${worldInfo.isActive}`);
});
```

### 获取详细状态

```typescript
const status = worldManager.getDetailedStatus();

// 包含所有 World 的详细状态
status.worlds.forEach(worldStatus => {
  console.log(`World ID: ${worldStatus.id}`);
  console.log(`状态:`, worldStatus.status);
});
```

## 自动清理

WorldManager 支持自动清理空的 World。

### 配置清理

```typescript
// 创建带清理配置的 WorldManager
const worldManager = Core.services.resolve(WorldManager);

// WorldManager 的配置在 Core 中设置：
// {
//   maxWorlds: 50,
//   autoCleanup: true,
//   cleanupFrameInterval: 1800  // 间隔多少帧清理闲置 World
// }
```

### 手动清理

```typescript
// 手动触发清理
const cleanedCount = worldManager.cleanup();
console.log(`清理了 ${cleanedCount} 个 World`);
```

**清理条件**：
- World 未激活
- 没有 Scene 或所有 Scene 都是空的
- 创建时间超过 10 分钟

## API 参考

### WorldManager API

| 方法 | 说明 |
|------|------|
| `createWorld(worldId, config?)` | 创建新 World |
| `removeWorld(worldId)` | 移除 World |
| `getWorld(worldId)` | 获取 World |
| `getAllWorlds()` | 获取所有 World |
| `getWorldIds()` | 获取所有 World ID |
| `setWorldActive(worldId, active)` | 设置 World 激活状态 |
| `isWorldActive(worldId)` | 检查 World 是否激活 |
| `getActiveWorlds()` | 获取所有活跃的 World |
| `updateAll()` | 更新所有活跃 World |
| `startAll()` | 启动所有 World |
| `stopAll()` | 停止所有 World |
| `findWorlds(predicate)` | 查找满足条件的 World |
| `findWorldByName(name)` | 根据名称查找 World |
| `getStats()` | 获取统计信息 |
| `getDetailedStatus()` | 获取详细状态信息 |
| `cleanup()` | 清理空 World |
| `destroy()` | 销毁 WorldManager |

### World API

| 方法 | 说明 |
|------|------|
| `createScene(sceneId, sceneInstance?)` | 创建并添加 Scene |
| `removeScene(sceneId)` | 移除 Scene |
| `getScene(sceneId)` | 获取 Scene |
| `getAllScenes()` | 获取所有 Scene |
| `getSceneIds()` | 获取所有 Scene ID |
| `setSceneActive(sceneId, active)` | 设置 Scene 激活状态 |
| `isSceneActive(sceneId)` | 检查 Scene 是否激活 |
| `getActiveSceneCount()` | 获取活跃 Scene 数量 |
| `addGlobalSystem(system)` | 添加全局系统 |
| `removeGlobalSystem(system)` | 移除全局系统 |
| `getGlobalSystem(type)` | 获取全局系统 |
| `start()` | 启动 World |
| `stop()` | 停止 World |
| `updateGlobalSystems()` | 更新全局系统 |
| `updateScenes()` | 更新所有激活 Scene |
| `destroy()` | 销毁 World |
| `getStatus()` | 获取 World 状态 |
| `getStats()` | 获取统计信息 |

### 属性

| 属性 | 说明 |
|------|------|
| `worldCount` | World 总数 |
| `activeWorldCount` | 活跃 World 数量 |
| `isRunning` | 是否正在运行 |
| `config` | 配置信息 |

## 完整示例

### MMO 游戏房间系统

```typescript
import { Core, WorldManager, Scene, World } from '@esengine/ecs-framework';

// 初始化
Core.create({ debug: true });
const worldManager = Core.services.resolve(WorldManager);

// 房间管理器
class RoomManager {
  private worldManager: WorldManager;
  private rooms: Map<string, World> = new Map();

  constructor(worldManager: WorldManager) {
    this.worldManager = worldManager;
  }

  // 创建游戏房间
  public createRoom(roomId: string, maxPlayers: number): World {
    const world = this.worldManager.createWorld(roomId, {
      name: `Room_${roomId}`,
      maxScenes: 3,
      debug: true
    });

    // 创建房间场景
    world.createScene('lobby', new LobbyScene());
    world.createScene('game', new GameScene());
    world.createScene('result', new ResultScene());

    // 添加房间级别的系统
    world.addGlobalSystem(new NetworkSystem(roomId));
    world.addGlobalSystem(new RoomLogicSystem(maxPlayers));

    // 激活 World 和初始场景
    this.worldManager.setWorldActive(roomId, true);
    world.setSceneActive('lobby', true);

    this.rooms.set(roomId, world);
    console.log(`房间 ${roomId} 已创建`);

    return world;
  }

  // 玩家加入房间
  public joinRoom(roomId: string, playerId: string): boolean {
    const world = this.rooms.get(roomId);
    if (!world) {
      console.log(`房间 ${roomId} 不存在`);
      return false;
    }

    // 在大厅场景中创建玩家实体
    const lobbyScene = world.getScene('lobby');
    if (lobbyScene) {
      const player = lobbyScene.createEntity(`Player_${playerId}`);
      // 添加玩家组件...
      console.log(`玩家 ${playerId} 加入房间 ${roomId}`);
      return true;
    }

    return false;
  }

  // 开始游戏
  public startGame(roomId: string): void {
    const world = this.rooms.get(roomId);
    if (!world) return;

    // 切换到游戏场景
    world.setSceneActive('lobby', false);
    world.setSceneActive('game', true);

    console.log(`房间 ${roomId} 游戏开始`);
  }

  // 结束游戏
  public endGame(roomId: string): void {
    const world = this.rooms.get(roomId);
    if (!world) return;

    // 切换到结果场景
    world.setSceneActive('game', false);
    world.setSceneActive('result', true);

    console.log(`房间 ${roomId} 游戏结束`);
  }

  // 关闭房间
  public closeRoom(roomId: string): void {
    this.worldManager.removeWorld(roomId);
    this.rooms.delete(roomId);
    console.log(`房间 ${roomId} 已关闭`);
  }

  // 获取房间列表
  public getRoomList(): string[] {
    return Array.from(this.rooms.keys());
  }

  // 获取房间统计
  public getRoomStats(roomId: string) {
    const world = this.rooms.get(roomId);
    return world?.getStats();
  }
}

// 使用房间管理器
const roomManager = new RoomManager(worldManager);

// 创建多个游戏房间
roomManager.createRoom('room_001', 4);
roomManager.createRoom('room_002', 4);
roomManager.createRoom('room_003', 2);

// 玩家加入
roomManager.joinRoom('room_001', 'player_1');
roomManager.joinRoom('room_001', 'player_2');

// 开始游戏
roomManager.startGame('room_001');

// 游戏循环
function gameLoop(deltaTime: number) {
  Core.update(deltaTime);
  worldManager.updateAll();  // 更新所有房间
}

// 定期清理空房间
setInterval(() => {
  const stats = worldManager.getStats();
  console.log(`当前房间数: ${stats.totalWorlds}`);
  console.log(`活跃房间数: ${stats.activeWorlds}`);

  worldManager.cleanup();
}, 60000); // 每分钟清理一次
```

## 最佳实践

### 1. 合理的 World 粒度

```typescript
// 推荐：每个独立环境一个 World
const room1 = worldManager.createWorld('room_1');  // 游戏房间1
const room2 = worldManager.createWorld('room_2');  // 游戏房间2

// 不推荐：过度使用 World
const world1 = worldManager.createWorld('ui');     // UI 不需要独立 World
const world2 = worldManager.createWorld('menu');   // 菜单不需要独立 World
```

### 2. 使用全局系统处理跨场景逻辑

```typescript
// 推荐：World 级别的系统
class NetworkSystem implements IGlobalSystem {
  update() {
    // 网络处理不依赖场景
  }
}

// 不推荐：在每个场景中重复创建
class GameScene extends Scene {
  initialize() {
    this.addSystem(new NetworkSystem());  // 不应该在场景级别
  }
}
```

### 3. 及时清理不用的 World

```typescript
// 推荐：玩家离开时清理房间
function onPlayerLeave(roomId: string) {
  const world = worldManager.getWorld(roomId);
  if (world && world.sceneCount === 0) {
    worldManager.removeWorld(roomId);
  }
}

// 或使用自动清理
worldManager.cleanup();
```

### 4. 监控资源使用

```typescript
// 定期检查资源使用情况
setInterval(() => {
  const stats = worldManager.getStats();

  if (stats.totalWorlds > 100) {
    console.warn('World 数量过多，考虑清理');
    worldManager.cleanup();
  }

  if (stats.totalEntities > 10000) {
    console.warn('实体数量过多，检查是否有泄漏');
  }
}, 30000);
```

## 与 SceneManager 的对比

| 特性 | SceneManager | WorldManager |
|------|--------------|--------------|
| 适用场景 | 95% 的游戏应用 | 高级多世界隔离场景 |
| 复杂度 | 简单 | 复杂 |
| 场景数量 | 单场景（可切换） | 多 World，每个 World 多场景 |
| 场景隔离 | 无（场景切换） | 完全隔离（每个 World 独立） |
| 性能开销 | 最小 | 较高 |
| 全局系统 | 无 | 支持（World 级别） |
| 使用示例 | 单人游戏、移动游戏 | MMO 服务器、游戏房间系统 |

**何时使用 WorldManager**：
- MMO 游戏服务器（每个房间一个 World）
- 游戏大厅系统（每个游戏房间完全隔离）
- 需要运行多个完全独立的游戏实例
- 服务器端模拟多个游戏世界

**何时使用 SceneManager**：
- 单人游戏
- 简单的多人游戏
- 移动游戏
- 场景之间需要切换但不需要同时运行

## 架构层次

WorldManager 在 ECS Framework 中的位置：

```
Core (全局服务)
  └── WorldManager (世界管理)
      ├── World 1 (游戏房间1)
      │   ├── GlobalSystem (全局系统)
      │   ├── Scene 1 (场景1)
      │   │   ├── EntitySystem
      │   │   ├── Entity
      │   │   └── Component
      │   └── Scene 2 (场景2)
      ├── World 2 (游戏房间2)
      │   ├── GlobalSystem
      │   └── Scene 1
      └── World 3 (游戏房间3)
```

WorldManager 为需要多世界隔离的高级应用提供了强大的管理能力。如果你的应用不需要多世界隔离，建议使用更简单的 [SceneManager](./scene-manager.md)。
