# 轻量级的神岛实体组件系统（ECS）框架

轻量级的实体组件系统（ECS）框架，专为 神岛引擎（Box3）设计，提供了一套完整的组件系统解决方案，帮助开发者构建可维护、可扩展的游戏项目。

更多详细信息请查看 [https://docs.box3lab.com/arenapro/package/componentGuide/component/](https://docs.box3lab.com/arenapro/package/componentGuide/component/)。

## 特性

- 🚀 高性能的组件更新系统
- 📊 内置性能监控和分析
- 🎯 基于装饰器的组件注册机制
- 🔄 事件驱动的观察者模式
- 🌐 支持服务端和客户端

## 核心概念

### EntityNode

节点是最基础的场景元素容器，具有事件功能，相当于游戏世界的原子单位。

```typescript
const node = new EntityNode(world.querySelector('#实体名称')!);
node.addComponent(new MovementComponent());
```

### Component

所有组件类的基类，提供组件的基本功能和接口。

```typescript
@apclass('MovementComponent')
class MovementComponent extends Component {
  update(deltaTime: number) {
    // 实现更新逻辑
  }
}
```

### 事件系统

提供强大的事件处理机制：

```typescript
// 使用全局事件总线
Emitter.on('gameStart', (event) => {
  console.log('游戏开始');
});

// 游戏世界事件
GameWorldEvent.on(world.onPlayerJoin, ({ entity }) => {
  console.log(`玩家 ${entity.player.name} 加入游戏`);
});
```

### 性能监控

内置性能监控系统，帮助识别和解决性能问题：

```typescript
// 启用全局性能监控
EntityNode.isMonitoringEnabled = true;

// 监听全局性能警告
EntityNode.onPerformanceWarning(({ component, executionTime, currentFPS }) => {
  console.warn(
    `组件 ${component.constructor.name} 执行时间过长: ${executionTime}ms`
  );
});
```

## 性能优化建议

1. 合理使用组件的 `enable` 属性
2. 避免在 `update` 方法中进行重复计算
3. 利用性能监控数据优化组件逻辑
4. 及时清理不需要的事件监听器
5. 生产环境下可禁用性能监控

### 如何正确管理组件的事件监听？

```typescript
class EventManagerComponent extends Component {
  start(): void {
    // 添加事件监听
    GameWorldEvent.on(world.onPlayerJoin, this.handlePlayerJoin, this);
    this.node.on('customEvent', this.handleCustomEvent, this);
  }

  onDestroy(): void {
    // 清理事件监听
    GameWorldEvent.off(world.onPlayerJoin, this.handlePlayerJoin, this);
    this.node.off('customEvent', this.handleCustomEvent, this);
  }

  private handlePlayerJoin(): void {
    // 处理玩家加入事件
  }

  private handleCustomEvent(): void {
    // 处理自定义事件
  }
}
```

### 组件之间如何共享数据？

1. **通过事件系统**：适用于松耦合场景

```typescript
// 发送方
this.node.emit('scoreChange', 100);

// 接收方
this.node.on('scoreChange', (score: number) => {
  // 处理数据
});
```

2. **通过全局单例**：适用于全局状态管理

```typescript
class GameDataManager extends Component {
  private static instance: GameDataManager;
  public gameData = {
    score: 0,
    level: 1,
  };

  onLoad(): void {
    GameDataManager.instance = this;
  }

  static getInstance(): GameDataManager {
    return GameDataManager.instance;
  }
}
```

### 如何处理组件的异常情况？

```typescript
class SafeComponent extends Component {
  start(): void {
    try {
      this.initializeComponent();
    } catch (error) {
      console.error('组件初始化失败:', error);
      // 优雅降级处理
      this.handleError(error);
    }
  }

  private handleError(error: Error): void {
    // 1. 记录错误
    console.error('组件错误:', error);

    // 2. 尝试恢复
    this.tryRecover();

    // 3. 如果无法恢复，禁用组件
    if (!this.canRecover()) {
      this.enabled = false;
    }
  }
}
```

### 组件配置如何管理？

1. **使用配置接口**

```typescript
interface PlayerConfig {
  speed: number;
  jumpForce: number;
  maxHealth: number;
}

class PlayerComponent extends Component {
  private config: PlayerConfig = {
    speed: 1,
    jumpForce: 10,
    maxHealth: 100,
  };

  // 通过 addComponent 时可以传入配置
  // node.addComponent(PlayerComponent, { config: customConfig });
}
```

### 如何处理组件的依赖关系？

```typescript
class DependentComponent extends Component {
  start(): void {
    // 检查必要组件
    const requiredComp = this.node.getComponent(RequiredComponent);
    if (!requiredComp) {
      console.error('缺少依赖组件 RequiredComponent');
      this.enabled = false;
      return;
    }

    // 自动添加依赖组件
    if (!this.node.getComponent(AutoAddComponent)) {
      this.node.addComponent(AutoAddComponent);
    }
  }
}
```

### 如何实现组件的热重载？

```typescript
class HotReloadableComponent extends Component<GameEntity> {
  private state = {};

  onDisable(): void {
    // 保存状态
    this.saveState();
  }

  onEnable(): void {
    // 恢复状态
    this.restoreState();
  }

  private saveState(): void {
    // 保存需要在重载时保持的状态
    this.state = {
      position: this.node.entity.position.clone(),
      data: this.getCurrentData(),
    };
  }

  private restoreState(): void {
    // 恢复之前保存的状态
    if (this.state) {
      this.node.entity.position = this.state.position;
      this.setCurrentData(this.state.data);
    }
  }
}
```
