@esengine/ecs-framework 2.1.4 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +385 -0
- package/{bin/index.d.ts → index.d.ts} +9 -6
- package/index.js +7 -0
- package/index.js.map +7 -0
- package/package.json +20 -46
- package/bin/Core.d.ts +0 -198
- package/bin/Core.d.ts.map +0 -1
- package/bin/Core.js +0 -247
- package/bin/Core.js.map +0 -1
- package/bin/ECS/Component.d.ts +0 -119
- package/bin/ECS/Component.d.ts.map +0 -1
- package/bin/ECS/Component.js +0 -129
- package/bin/ECS/Component.js.map +0 -1
- package/bin/ECS/Components/IUpdatable.d.ts +0 -22
- package/bin/ECS/Components/IUpdatable.d.ts.map +0 -1
- package/bin/ECS/Components/IUpdatable.js +0 -22
- package/bin/ECS/Components/IUpdatable.js.map +0 -1
- package/bin/ECS/Components/SceneComponent.d.ts +0 -40
- package/bin/ECS/Components/SceneComponent.d.ts.map +0 -1
- package/bin/ECS/Components/SceneComponent.js +0 -61
- package/bin/ECS/Components/SceneComponent.js.map +0 -1
- package/bin/ECS/Core/BitMaskOptimizer.d.ts +0 -75
- package/bin/ECS/Core/BitMaskOptimizer.d.ts.map +0 -1
- package/bin/ECS/Core/BitMaskOptimizer.js +0 -161
- package/bin/ECS/Core/BitMaskOptimizer.js.map +0 -1
- package/bin/ECS/Core/ComponentPool.d.ts +0 -72
- package/bin/ECS/Core/ComponentPool.d.ts.map +0 -1
- package/bin/ECS/Core/ComponentPool.js +0 -123
- package/bin/ECS/Core/ComponentPool.js.map +0 -1
- package/bin/ECS/Core/ComponentStorage.d.ts +0 -182
- package/bin/ECS/Core/ComponentStorage.d.ts.map +0 -1
- package/bin/ECS/Core/ComponentStorage.js +0 -346
- package/bin/ECS/Core/ComponentStorage.js.map +0 -1
- package/bin/ECS/Core/EventSystem.d.ts +0 -236
- package/bin/ECS/Core/EventSystem.d.ts.map +0 -1
- package/bin/ECS/Core/EventSystem.js +0 -476
- package/bin/ECS/Core/EventSystem.js.map +0 -1
- package/bin/ECS/Core/FluentAPI.d.ts +0 -371
- package/bin/ECS/Core/FluentAPI.d.ts.map +0 -1
- package/bin/ECS/Core/FluentAPI.js +0 -543
- package/bin/ECS/Core/FluentAPI.js.map +0 -1
- package/bin/ECS/Core/IndexUpdateBatcher.d.ts +0 -100
- package/bin/ECS/Core/IndexUpdateBatcher.d.ts.map +0 -1
- package/bin/ECS/Core/IndexUpdateBatcher.js +0 -219
- package/bin/ECS/Core/IndexUpdateBatcher.js.map +0 -1
- package/bin/ECS/Core/QuerySystem.d.ts +0 -422
- package/bin/ECS/Core/QuerySystem.d.ts.map +0 -1
- package/bin/ECS/Core/QuerySystem.js +0 -937
- package/bin/ECS/Core/QuerySystem.js.map +0 -1
- package/bin/ECS/CoreEvents.d.ts +0 -19
- package/bin/ECS/CoreEvents.d.ts.map +0 -1
- package/bin/ECS/CoreEvents.js +0 -20
- package/bin/ECS/CoreEvents.js.map +0 -1
- package/bin/ECS/Entity.d.ts +0 -538
- package/bin/ECS/Entity.d.ts.map +0 -1
- package/bin/ECS/Entity.js +0 -1030
- package/bin/ECS/Entity.js.map +0 -1
- package/bin/ECS/Scene.d.ts +0 -226
- package/bin/ECS/Scene.d.ts.map +0 -1
- package/bin/ECS/Scene.js +0 -308
- package/bin/ECS/Scene.js.map +0 -1
- package/bin/ECS/Systems/EntitySystem.d.ts +0 -185
- package/bin/ECS/Systems/EntitySystem.d.ts.map +0 -1
- package/bin/ECS/Systems/EntitySystem.js +0 -278
- package/bin/ECS/Systems/EntitySystem.js.map +0 -1
- package/bin/ECS/Systems/IntervalSystem.d.ts +0 -33
- package/bin/ECS/Systems/IntervalSystem.d.ts.map +0 -1
- package/bin/ECS/Systems/IntervalSystem.js +0 -50
- package/bin/ECS/Systems/IntervalSystem.js.map +0 -1
- package/bin/ECS/Systems/PassiveSystem.d.ts +0 -20
- package/bin/ECS/Systems/PassiveSystem.d.ts.map +0 -1
- package/bin/ECS/Systems/PassiveSystem.js +0 -21
- package/bin/ECS/Systems/PassiveSystem.js.map +0 -1
- package/bin/ECS/Systems/ProcessingSystem.d.ts +0 -24
- package/bin/ECS/Systems/ProcessingSystem.d.ts.map +0 -1
- package/bin/ECS/Systems/ProcessingSystem.js +0 -22
- package/bin/ECS/Systems/ProcessingSystem.js.map +0 -1
- package/bin/ECS/Systems/index.d.ts +0 -5
- package/bin/ECS/Systems/index.d.ts.map +0 -1
- package/bin/ECS/Systems/index.js +0 -6
- package/bin/ECS/Systems/index.js.map +0 -1
- package/bin/ECS/Utils/Bits.d.ts +0 -74
- package/bin/ECS/Utils/Bits.d.ts.map +0 -1
- package/bin/ECS/Utils/Bits.js +0 -142
- package/bin/ECS/Utils/Bits.js.map +0 -1
- package/bin/ECS/Utils/ComponentTypeManager.d.ts +0 -50
- package/bin/ECS/Utils/ComponentTypeManager.d.ts.map +0 -1
- package/bin/ECS/Utils/ComponentTypeManager.js +0 -84
- package/bin/ECS/Utils/ComponentTypeManager.js.map +0 -1
- package/bin/ECS/Utils/EntityList.d.ts +0 -108
- package/bin/ECS/Utils/EntityList.d.ts.map +0 -1
- package/bin/ECS/Utils/EntityList.js +0 -249
- package/bin/ECS/Utils/EntityList.js.map +0 -1
- package/bin/ECS/Utils/EntityProcessorList.d.ts +0 -53
- package/bin/ECS/Utils/EntityProcessorList.d.ts.map +0 -1
- package/bin/ECS/Utils/EntityProcessorList.js +0 -96
- package/bin/ECS/Utils/EntityProcessorList.js.map +0 -1
- package/bin/ECS/Utils/IdentifierPool.d.ts +0 -18
- package/bin/ECS/Utils/IdentifierPool.d.ts.map +0 -1
- package/bin/ECS/Utils/IdentifierPool.js +0 -27
- package/bin/ECS/Utils/IdentifierPool.js.map +0 -1
- package/bin/ECS/Utils/Matcher.d.ts +0 -63
- package/bin/ECS/Utils/Matcher.d.ts.map +0 -1
- package/bin/ECS/Utils/Matcher.js +0 -140
- package/bin/ECS/Utils/Matcher.js.map +0 -1
- package/bin/ECS/Utils/index.d.ts +0 -7
- package/bin/ECS/Utils/index.d.ts.map +0 -1
- package/bin/ECS/Utils/index.js +0 -8
- package/bin/ECS/Utils/index.js.map +0 -1
- package/bin/ECS/index.d.ts +0 -7
- package/bin/ECS/index.d.ts.map +0 -1
- package/bin/ECS/index.js +0 -29
- package/bin/ECS/index.js.map +0 -1
- package/bin/Testing/Performance/benchmark.d.ts +0 -6
- package/bin/Testing/Performance/benchmark.d.ts.map +0 -1
- package/bin/Testing/Performance/benchmark.js +0 -639
- package/bin/Testing/Performance/benchmark.js.map +0 -1
- package/bin/Testing/Performance/component-performance.d.ts +0 -2
- package/bin/Testing/Performance/component-performance.d.ts.map +0 -1
- package/bin/Testing/Performance/component-performance.js +0 -43
- package/bin/Testing/Performance/component-performance.js.map +0 -1
- package/bin/Testing/Unit/bitmask-optimizer.test.d.ts +0 -2
- package/bin/Testing/Unit/bitmask-optimizer.test.d.ts.map +0 -1
- package/bin/Testing/Unit/bitmask-optimizer.test.js +0 -164
- package/bin/Testing/Unit/bitmask-optimizer.test.js.map +0 -1
- package/bin/Testing/Unit/component-pool.test.d.ts +0 -5
- package/bin/Testing/Unit/component-pool.test.d.ts.map +0 -1
- package/bin/Testing/Unit/component-pool.test.js +0 -149
- package/bin/Testing/Unit/component-pool.test.js.map +0 -1
- package/bin/Testing/test-runner.d.ts +0 -51
- package/bin/Testing/test-runner.d.ts.map +0 -1
- package/bin/Testing/test-runner.js +0 -159
- package/bin/Testing/test-runner.js.map +0 -1
- package/bin/Types/index.d.ts +0 -22
- package/bin/Types/index.d.ts.map +0 -1
- package/bin/Types/index.js +0 -20
- package/bin/Types/index.js.map +0 -1
- package/bin/Utils/Emitter.d.ts +0 -43
- package/bin/Utils/Emitter.d.ts.map +0 -1
- package/bin/Utils/Emitter.js +0 -69
- package/bin/Utils/Emitter.js.map +0 -1
- package/bin/Utils/Extensions/NumberExtension.d.ts +0 -13
- package/bin/Utils/Extensions/NumberExtension.d.ts.map +0 -1
- package/bin/Utils/Extensions/NumberExtension.js +0 -17
- package/bin/Utils/Extensions/NumberExtension.js.map +0 -1
- package/bin/Utils/Extensions/TypeUtils.d.ts +0 -13
- package/bin/Utils/Extensions/TypeUtils.d.ts.map +0 -1
- package/bin/Utils/Extensions/TypeUtils.js +0 -15
- package/bin/Utils/Extensions/TypeUtils.js.map +0 -1
- package/bin/Utils/Extensions/index.d.ts +0 -3
- package/bin/Utils/Extensions/index.d.ts.map +0 -1
- package/bin/Utils/Extensions/index.js +0 -4
- package/bin/Utils/Extensions/index.js.map +0 -1
- package/bin/Utils/GlobalManager.d.ts +0 -32
- package/bin/Utils/GlobalManager.d.ts.map +0 -1
- package/bin/Utils/GlobalManager.js +0 -53
- package/bin/Utils/GlobalManager.js.map +0 -1
- package/bin/Utils/PerformanceMonitor.d.ts +0 -211
- package/bin/Utils/PerformanceMonitor.d.ts.map +0 -1
- package/bin/Utils/PerformanceMonitor.js +0 -270
- package/bin/Utils/PerformanceMonitor.js.map +0 -1
- package/bin/Utils/Pool.d.ts +0 -239
- package/bin/Utils/Pool.d.ts.map +0 -1
- package/bin/Utils/Pool.js +0 -449
- package/bin/Utils/Pool.js.map +0 -1
- package/bin/Utils/Time.d.ts +0 -55
- package/bin/Utils/Time.d.ts.map +0 -1
- package/bin/Utils/Time.js +0 -78
- package/bin/Utils/Time.js.map +0 -1
- package/bin/Utils/Timers/ITimer.d.ts +0 -16
- package/bin/Utils/Timers/ITimer.d.ts.map +0 -1
- package/bin/Utils/Timers/ITimer.js +0 -2
- package/bin/Utils/Timers/ITimer.js.map +0 -1
- package/bin/Utils/Timers/Timer.d.ts +0 -22
- package/bin/Utils/Timers/Timer.d.ts.map +0 -1
- package/bin/Utils/Timers/Timer.js +0 -46
- package/bin/Utils/Timers/Timer.js.map +0 -1
- package/bin/Utils/Timers/TimerManager.d.ts +0 -19
- package/bin/Utils/Timers/TimerManager.d.ts.map +0 -1
- package/bin/Utils/Timers/TimerManager.js +0 -33
- package/bin/Utils/Timers/TimerManager.js.map +0 -1
- package/bin/Utils/WasmCore.d.ts +0 -234
- package/bin/Utils/WasmCore.d.ts.map +0 -1
- package/bin/Utils/WasmCore.js +0 -596
- package/bin/Utils/WasmCore.js.map +0 -1
- package/bin/Utils/index.d.ts +0 -16
- package/bin/Utils/index.d.ts.map +0 -1
- package/bin/Utils/index.js +0 -37
- package/bin/Utils/index.js.map +0 -1
- package/bin/index.cjs +0 -51
- package/bin/index.d.ts.map +0 -1
- package/bin/index.esm.d.ts +0 -45
- package/bin/index.esm.d.ts.map +0 -1
- package/bin/index.esm.js +0 -46
- package/bin/index.esm.js.map +0 -1
- package/bin/index.js.map +0 -1
- package/bin/wasm/ecs_wasm_core.d.ts +0 -141
- package/bin/wasm/ecs_wasm_core.js +0 -415
- package/bin/wasm/ecs_wasm_core_bg.wasm +0 -0
- package/bin/wasm/ecs_wasm_core_bg.wasm.d.ts +0 -29
- package/bin/wasm/package.json +0 -15
package/README.md
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# ECS Framework
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/%40esengine%2Fecs-framework)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
一个轻量级的 TypeScript ECS(Entity-Component-System)框架,专为小游戏开发设计,适用于 Laya、Cocos 等游戏引擎。
|
|
7
|
+
|
|
8
|
+
## ✨ 特性
|
|
9
|
+
|
|
10
|
+
- 🚀 **轻量级 ECS 架构** - 基于实体组件系统,提供清晰的代码结构
|
|
11
|
+
- ⚡ **高性能** - 实体创建速度可达64万实体/秒,支持大规模实体管理
|
|
12
|
+
- 🎯 **智能优化** - 组件对象池、位掩码优化器、延迟索引更新等性能优化技术
|
|
13
|
+
- 📡 **事件系统** - 内置 Emitter 事件发射器,支持类型安全的事件管理
|
|
14
|
+
- ⏰ **定时器系统** - 完整的定时器管理,支持延迟和重复任务
|
|
15
|
+
- 🔍 **查询系统** - 基于位掩码的高性能实体查询,支持批量操作
|
|
16
|
+
- 🛠️ **性能监控** - 内置性能监控工具,帮助优化游戏性能
|
|
17
|
+
- 🔧 **批量操作** - 支持批量实体创建、组件添加等高效操作
|
|
18
|
+
|
|
19
|
+
## 📦 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @esengine/ecs-framework
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 📊 性能基准
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# 运行快速性能基准测试
|
|
29
|
+
npm run benchmark
|
|
30
|
+
|
|
31
|
+
# 运行完整性能测试
|
|
32
|
+
npm run test:performance
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**框架性能数据**:
|
|
36
|
+
|
|
37
|
+
### 🚀 实体创建性能
|
|
38
|
+
- **小规模**: 640,697 实体/秒 (1,000个实体/1.56ms)
|
|
39
|
+
- **中规模**: 250,345 实体/秒 (10,000个实体/39.94ms)
|
|
40
|
+
- **大规模**: 161,990 实体/秒 (500,000个实体/3.09秒)
|
|
41
|
+
|
|
42
|
+
### 🎯 核心操作性能
|
|
43
|
+
```
|
|
44
|
+
📊 核心操作性能
|
|
45
|
+
实体创建: 640,697个/秒
|
|
46
|
+
组件添加: 596,929组件/秒
|
|
47
|
+
位掩码操作: 5,000,000次/秒
|
|
48
|
+
查询缓存: 零延迟访问
|
|
49
|
+
批量操作: 高效处理
|
|
50
|
+
|
|
51
|
+
🔧 优化技术效果
|
|
52
|
+
组件对象池: 减少30-50%内存分配
|
|
53
|
+
位掩码优化器: 提升20-40%掩码性能
|
|
54
|
+
批量操作: 大幅减少创建时间
|
|
55
|
+
索引优化: 避免O(n)重复检查
|
|
56
|
+
缓存策略: 延迟清理机制
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 🚀 快速开始
|
|
60
|
+
|
|
61
|
+
### 1. 初始化框架
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { Core, CoreEvents } from '@esengine/ecs-framework';
|
|
65
|
+
|
|
66
|
+
// 创建 Core 实例
|
|
67
|
+
const core = Core.create(true); // true 表示开启调试模式
|
|
68
|
+
|
|
69
|
+
// 在游戏循环中更新框架
|
|
70
|
+
function gameLoop() {
|
|
71
|
+
// 发送帧更新事件
|
|
72
|
+
Core.emitter.emit(CoreEvents.frameUpdated);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2. 高性能批量创建实体
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { Scene, EntitySystem } from '@esengine/ecs-framework';
|
|
80
|
+
|
|
81
|
+
class GameScene extends Scene {
|
|
82
|
+
public initialize() {
|
|
83
|
+
// 批量创建实体
|
|
84
|
+
const entities = this.createEntities(1000, "Enemy");
|
|
85
|
+
|
|
86
|
+
// 批量添加组件
|
|
87
|
+
entities.forEach((entity, index) => {
|
|
88
|
+
entity.addComponent(new PositionComponent(
|
|
89
|
+
Math.random() * 1000,
|
|
90
|
+
Math.random() * 1000
|
|
91
|
+
));
|
|
92
|
+
entity.addComponent(new VelocityComponent());
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// 添加系统
|
|
96
|
+
this.addEntityProcessor(new MovementSystem());
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3. 使用组件对象池优化内存
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { Component, ComponentPoolManager } from '@esengine/ecs-framework';
|
|
105
|
+
|
|
106
|
+
class BulletComponent extends Component {
|
|
107
|
+
public damage: number = 10;
|
|
108
|
+
public speed: number = 300;
|
|
109
|
+
|
|
110
|
+
// 重置方法用于对象池
|
|
111
|
+
public reset() {
|
|
112
|
+
this.damage = 10;
|
|
113
|
+
this.speed = 300;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 注册组件池
|
|
118
|
+
ComponentPoolManager.getInstance().registerPool(BulletComponent, 1000);
|
|
119
|
+
|
|
120
|
+
// 使用对象池获取组件
|
|
121
|
+
const bullet = ComponentPoolManager.getInstance().getComponent(BulletComponent);
|
|
122
|
+
entity.addComponent(bullet);
|
|
123
|
+
|
|
124
|
+
// 释放回对象池
|
|
125
|
+
ComponentPoolManager.getInstance().releaseComponent(bullet);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 4. 位掩码优化器加速查询
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { BitMaskOptimizer } from '@esengine/ecs-framework';
|
|
132
|
+
|
|
133
|
+
// 注册常用组件类型
|
|
134
|
+
const optimizer = BitMaskOptimizer.getInstance();
|
|
135
|
+
optimizer.registerComponentType(PositionComponent);
|
|
136
|
+
optimizer.registerComponentType(VelocityComponent);
|
|
137
|
+
optimizer.registerComponentType(RenderComponent);
|
|
138
|
+
|
|
139
|
+
// 预计算常用掩码组合
|
|
140
|
+
optimizer.precomputeCommonMasks();
|
|
141
|
+
|
|
142
|
+
// 高效的掩码操作
|
|
143
|
+
const positionMask = optimizer.getComponentMask(PositionComponent);
|
|
144
|
+
const movementMask = optimizer.getCombinedMask([PositionComponent, VelocityComponent]);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 📚 核心概念
|
|
148
|
+
|
|
149
|
+
### Entity(实体)
|
|
150
|
+
实体是游戏世界中的基本对象,支持批量操作和高性能创建。
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// 单个实体创建
|
|
154
|
+
const entity = scene.createEntity("MyEntity");
|
|
155
|
+
|
|
156
|
+
// 批量实体创建
|
|
157
|
+
const entities = scene.createEntities(1000, "Bullets");
|
|
158
|
+
|
|
159
|
+
// 实体属性设置
|
|
160
|
+
entity.tag = 1;
|
|
161
|
+
entity.updateOrder = 0;
|
|
162
|
+
entity.enabled = true;
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Component(组件)
|
|
166
|
+
组件包含数据和行为,支持对象池优化。
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { Component, ComponentPoolManager } from '@esengine/ecs-framework';
|
|
170
|
+
|
|
171
|
+
class HealthComponent extends Component {
|
|
172
|
+
public maxHealth: number = 100;
|
|
173
|
+
public currentHealth: number = 100;
|
|
174
|
+
|
|
175
|
+
// 对象池重置方法
|
|
176
|
+
public reset() {
|
|
177
|
+
this.maxHealth = 100;
|
|
178
|
+
this.currentHealth = 100;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public takeDamage(damage: number) {
|
|
182
|
+
this.currentHealth = Math.max(0, this.currentHealth - damage);
|
|
183
|
+
if (this.currentHealth <= 0) {
|
|
184
|
+
this.entity.destroy();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// 注册到对象池
|
|
190
|
+
ComponentPoolManager.getInstance().registerPool(HealthComponent, 500);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### System(系统)
|
|
194
|
+
系统处理实体集合,支持批量处理优化。
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { EntitySystem, Entity } from '@esengine/ecs-framework';
|
|
198
|
+
|
|
199
|
+
class HealthSystem extends EntitySystem {
|
|
200
|
+
protected process(entities: Entity[]) {
|
|
201
|
+
// 批量处理实体
|
|
202
|
+
const batchSize = 1000;
|
|
203
|
+
for (let i = 0; i < entities.length; i += batchSize) {
|
|
204
|
+
const batch = entities.slice(i, i + batchSize);
|
|
205
|
+
this.processBatch(batch);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private processBatch(entities: Entity[]) {
|
|
210
|
+
for (const entity of entities) {
|
|
211
|
+
const health = entity.getComponent(HealthComponent);
|
|
212
|
+
if (health && health.currentHealth <= 0) {
|
|
213
|
+
entity.destroy();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 🎮 高级功能
|
|
221
|
+
|
|
222
|
+
### 批量操作API
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// 批量创建实体
|
|
226
|
+
const entities = scene.createEntities(5000, "Enemies");
|
|
227
|
+
|
|
228
|
+
// 批量查询
|
|
229
|
+
const movingEntities = scene.getEntitiesWithComponents([PositionComponent, VelocityComponent]);
|
|
230
|
+
|
|
231
|
+
// 延迟缓存清理
|
|
232
|
+
scene.addEntity(entity, false); // 延迟缓存清理
|
|
233
|
+
// ... 添加更多实体
|
|
234
|
+
scene.querySystem.clearCache(); // 手动清理缓存
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 性能监控
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
import { Core } from '@esengine/ecs-framework';
|
|
241
|
+
|
|
242
|
+
// 获取性能统计
|
|
243
|
+
const stats = scene.getPerformanceStats();
|
|
244
|
+
console.log(`实体数量: ${stats.entityCount}`);
|
|
245
|
+
console.log(`查询缓存大小: ${stats.queryCacheSize}`);
|
|
246
|
+
console.log(`组件池统计:`, stats.componentPoolStats);
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 内存优化
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// 预热组件池
|
|
253
|
+
ComponentPoolManager.getInstance().preWarmPools({
|
|
254
|
+
BulletComponent: 1000,
|
|
255
|
+
EffectComponent: 500,
|
|
256
|
+
PickupComponent: 200
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// 清理未使用的组件
|
|
260
|
+
ComponentPoolManager.getInstance().clearUnusedComponents();
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## 🧪 测试和基准
|
|
264
|
+
|
|
265
|
+
### 运行测试套件
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# 运行所有测试
|
|
269
|
+
npm run test
|
|
270
|
+
|
|
271
|
+
# 单元测试
|
|
272
|
+
npm run test:unit
|
|
273
|
+
|
|
274
|
+
# 性能测试
|
|
275
|
+
npm run test:performance
|
|
276
|
+
|
|
277
|
+
# 快速基准测试
|
|
278
|
+
npm run benchmark
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 自定义性能测试
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import { runEntityCreationBenchmark } from './Testing/Performance/benchmark';
|
|
285
|
+
|
|
286
|
+
// 运行自定义基准测试
|
|
287
|
+
await runEntityCreationBenchmark();
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## 🔧 优化建议
|
|
291
|
+
|
|
292
|
+
### 大规模实体处理
|
|
293
|
+
|
|
294
|
+
1. **使用批量API**
|
|
295
|
+
```typescript
|
|
296
|
+
// ✅ 推荐:批量创建
|
|
297
|
+
const entities = scene.createEntities(10000, "Units");
|
|
298
|
+
|
|
299
|
+
// ❌ 避免:循环单个创建
|
|
300
|
+
for (let i = 0; i < 10000; i++) {
|
|
301
|
+
scene.createEntity("Unit" + i);
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
2. **启用对象池**
|
|
306
|
+
```typescript
|
|
307
|
+
// 预先注册常用组件池
|
|
308
|
+
ComponentPoolManager.getInstance().registerPool(BulletComponent, 2000);
|
|
309
|
+
ComponentPoolManager.getInstance().registerPool(EffectComponent, 1000);
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
3. **优化查询频率**
|
|
313
|
+
```typescript
|
|
314
|
+
// 缓存查询结果
|
|
315
|
+
if (frameCount % 5 === 0) {
|
|
316
|
+
this.cachedEnemies = scene.getEntitiesWithComponent(EnemyComponent);
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### 移动端优化
|
|
321
|
+
|
|
322
|
+
- 实体数量建议 ≤ 20,000
|
|
323
|
+
- 启用组件对象池
|
|
324
|
+
- 减少查询频率
|
|
325
|
+
- 使用批量操作
|
|
326
|
+
|
|
327
|
+
## 📈 版本更新
|
|
328
|
+
|
|
329
|
+
### v2.0.6 (最新)
|
|
330
|
+
- 🚀 **高性能实体创建**: 支持64万实体/秒的创建速度
|
|
331
|
+
- 🎯 **组件对象池**: 减少内存分配开销
|
|
332
|
+
- ⚡ **位掩码优化器**: 加速组件查询和操作
|
|
333
|
+
- 🔧 **批量操作API**: 支持高效的批量实体创建
|
|
334
|
+
- 📊 **性能监控**: 完整的性能分析工具
|
|
335
|
+
- 🧪 **测试套件**: 单元测试、性能测试、集成测试
|
|
336
|
+
|
|
337
|
+
### 历史版本
|
|
338
|
+
- v1.x.x: 基础ECS架构实现
|
|
339
|
+
|
|
340
|
+
## 📖 文档
|
|
341
|
+
|
|
342
|
+
- [快速入门](docs/getting-started.md) - 从零开始学习框架使用
|
|
343
|
+
- [实体使用指南](docs/entity-guide.md) - 详细了解实体的所有功能和用法
|
|
344
|
+
- [核心概念](docs/core-concepts.md) - 深入了解 ECS 架构和设计原理
|
|
345
|
+
- [查询系统使用指南](docs/query-system-usage.md) - 学习高性能查询系统的详细用法
|
|
346
|
+
|
|
347
|
+
## 🔗 扩展库
|
|
348
|
+
|
|
349
|
+
- [路径寻找库](https://github.com/esengine/ecs-astar) - A*、广度优先、Dijkstra、GOAP 算法
|
|
350
|
+
- [AI 系统](https://github.com/esengine/BehaviourTree-ai) - 行为树、效用 AI 系统
|
|
351
|
+
|
|
352
|
+
## 🤝 贡献
|
|
353
|
+
|
|
354
|
+
欢迎提交 Issue 和 Pull Request!
|
|
355
|
+
|
|
356
|
+
### 开发环境设置
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# 克隆项目
|
|
360
|
+
git clone https://github.com/esengine/ecs-framework.git
|
|
361
|
+
cd ecs-framework
|
|
362
|
+
|
|
363
|
+
# 运行基准测试
|
|
364
|
+
node benchmark.js
|
|
365
|
+
|
|
366
|
+
# 开发构建 (在source目录)
|
|
367
|
+
cd source && npm install && npm run build
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### 构建要求
|
|
371
|
+
|
|
372
|
+
- Node.js >= 14.0.0
|
|
373
|
+
- TypeScript >= 4.0.0
|
|
374
|
+
|
|
375
|
+
## 📄 许可证
|
|
376
|
+
|
|
377
|
+
本项目采用 [MIT](LICENSE) 许可证。
|
|
378
|
+
|
|
379
|
+
## 💬 交流群
|
|
380
|
+
|
|
381
|
+
加入 QQ 群讨论:[ecs游戏框架交流](https://jq.qq.com/?_wv=1027&k=29w1Nud6)
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
**ECS Framework** - 让游戏开发更简单、更高效!
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @esengine/ecs-framework
|
|
3
|
+
* 高性能ECS框架 - 适用于Cocos Creator和Laya引擎
|
|
4
|
+
* 版本: 2.1.5
|
|
5
|
+
* 构建时间: 2025-06-09T01:48:54.822Z
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
/**
|
|
2
9
|
* ECS Framework - 轻量级实体组件系统框架
|
|
3
10
|
* 适用于Laya、Cocos等游戏引擎的小游戏开发
|
|
@@ -7,13 +14,9 @@ export { CoreEvents } from './ECS/CoreEvents';
|
|
|
7
14
|
export { Emitter, FuncPack } from './Utils/Emitter';
|
|
8
15
|
export { GlobalManager } from './Utils/GlobalManager';
|
|
9
16
|
export { TimerManager } from './Utils/Timers/TimerManager';
|
|
10
|
-
export
|
|
17
|
+
export { ITimer } from './Utils/Timers/ITimer';
|
|
11
18
|
export { Timer } from './Utils/Timers/Timer';
|
|
12
19
|
export * from './ECS';
|
|
13
|
-
export * from './Utils
|
|
14
|
-
export * from './Utils/PerformanceMonitor';
|
|
15
|
-
export * from './Utils/Extensions';
|
|
16
|
-
export { WasmEcsCore, ecsCore, initializeEcs, Query } from './Utils/WasmCore';
|
|
17
|
-
export type { EntityId, ComponentMask, QueryResult } from './Utils/WasmCore';
|
|
20
|
+
export * from './Utils';
|
|
18
21
|
export * from './Types';
|
|
19
22
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var se=Object.defineProperty,ae=Object.defineProperties;var he=Object.getOwnPropertyDescriptors;var te=Object.getOwnPropertySymbols;var ce=Object.prototype.hasOwnProperty,le=Object.prototype.propertyIsEnumerable;var ee=(a,t,e)=>t in a?se(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e,g=(a,t)=>{for(var e in t||(t={}))ce.call(t,e)&&ee(a,e,t[e]);if(te)for(var e of te(t))le.call(t,e)&&ee(a,e,t[e]);return a},M=(a,t)=>ae(a,he(t)),r=(a,t)=>se(a,"name",{value:t,configurable:!0}),p=(a=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(a,{get:(t,e)=>(typeof require!="undefined"?require:t)[e]}):a)(function(a){if(typeof require!="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});var lt=class lt{constructor(t,e){this.func=t,this.context=e}};r(lt,"FuncPack");var H=lt,ut=class ut{constructor(){this._messageTable=new Map}addObserver(t,e,s){let i=this._messageTable.get(t);i||(i=[],this._messageTable.set(t,i)),this.hasObserver(t,e)||i.push(new H(e,s))}removeObserver(t,e){let s=this._messageTable.get(t);if(s){let i=s.findIndex(n=>n.func==e);i!=-1&&s.splice(i,1)}}emit(t,...e){let s=this._messageTable.get(t);if(s)for(let i of s)i.func.call(i.context,...e)}hasObserver(t,e){let s=this._messageTable.get(t);return s?s.some(i=>i.func===e):!1}};r(ut,"Emitter");var U=ut;var z;(function(a){a[a.sceneChanged=0]="sceneChanged",a[a.frameUpdated=1]="frameUpdated",a[a.renderChanged=2]="renderChanged"})(z||(z={}));var mt=class mt{constructor(){this._enabled=!1}get enabled(){return this._enabled}set enabled(t){this.setEnabled(t)}setEnabled(t){this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled())}onEnabled(){}onDisabled(){}update(){}};r(mt,"GlobalManager");var D=mt;var dt=class dt{static update(t=-1){if(t===-1&&(t=Date.now()),this._isFirstUpdate){this._lastTime=t,this._isFirstUpdate=!1;return}this.unscaledDeltaTime=(t-this._lastTime)/1e3,this.deltaTime=this.unscaledDeltaTime*this.timeScale,this.unscaledTotalTime+=this.unscaledDeltaTime,this.totalTime+=this.deltaTime,this.frameCount++,this._lastTime=t}static sceneChanged(){this._isFirstUpdate=!0}static checkEvery(t,e){return this.totalTime-e>=t}};r(dt,"Time");var l=dt;l.deltaTime=0;l.unscaledDeltaTime=0;l.totalTime=0;l.unscaledTotalTime=0;l.timeScale=1;l.frameCount=0;l._lastTime=0;l._isFirstUpdate=!0;var pt=class pt{constructor(){this._timeInSeconds=0,this._repeats=!1,this._isDone=!1,this._elapsedTime=0}getContext(){return this.context}reset(){this._elapsedTime=0}stop(){this._isDone=!0}tick(){return!this._isDone&&this._elapsedTime>this._timeInSeconds&&(this._elapsedTime-=this._timeInSeconds,this._onTime(this),!this._isDone&&!this._repeats&&(this._isDone=!0)),this._elapsedTime+=l.deltaTime,this._isDone}initialize(t,e,s,i){this._timeInSeconds=t,this._repeats=e,this.context=s,this._onTime=i.bind(s)}unload(){this.context=null,this._onTime=null}};r(pt,"Timer");var q=pt;var ft=class ft extends D{constructor(){super(...arguments),this._timers=[]}update(){for(let t=this._timers.length-1;t>=0;t--)this._timers[t].tick()&&(this._timers[t].unload(),this._timers.splice(t,1))}schedule(t,e,s,i){let n=new q;return n.initialize(t,e,s,i),this._timers.push(n),n}};r(ft,"TimerManager");var $=ft;var ie;(function(a){a.HIGH_EXECUTION_TIME="high_execution_time",a.HIGH_MEMORY_USAGE="high_memory_usage",a.HIGH_CPU_USAGE="high_cpu_usage",a.FREQUENT_GC="frequent_gc",a.LOW_FPS="low_fps",a.HIGH_ENTITY_COUNT="high_entity_count"})(ie||(ie={}));var b=class b{static get instance(){return b._instance||(b._instance=new b),b._instance}constructor(){this._systemData=new Map,this._systemStats=new Map,this._warnings=[],this._isEnabled=!1,this._maxRecentSamples=60,this._maxWarnings=100,this._thresholds={executionTime:{warning:16.67,critical:33.33},memoryUsage:{warning:100,critical:200},cpuUsage:{warning:70,critical:90},fps:{warning:45,critical:30},entityCount:{warning:1e3,critical:5e3}},this._fpsHistory=[],this._lastFrameTime=0,this._frameCount=0,this._fpsUpdateInterval=1e3,this._lastFpsUpdate=0,this._currentFps=60,this._memoryCheckInterval=5e3,this._lastMemoryCheck=0,this._memoryHistory=[],this._gcCount=0,this._lastGcCheck=0,this._gcCheckInterval=1e3}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}get isEnabled(){return this._isEnabled}startMonitoring(t){return this._isEnabled?performance.now():0}endMonitoring(t,e,s=0){if(!this._isEnabled||e===0)return;let i=performance.now(),n=i-e,o=s>0?n/s:0,h={name:t,executionTime:n,entityCount:s,averageTimePerEntity:o,lastUpdateTime:i};this._systemData.set(t,h),this.updateStats(t,n)}updateStats(t,e){let s=this._systemStats.get(t);s||(s={totalTime:0,averageTime:0,minTime:Number.MAX_VALUE,maxTime:0,executionCount:0,recentTimes:[],standardDeviation:0,percentile95:0,percentile99:0},this._systemStats.set(t,s)),s.totalTime+=e,s.executionCount++,s.averageTime=s.totalTime/s.executionCount,s.minTime=Math.min(s.minTime,e),s.maxTime=Math.max(s.maxTime,e),s.recentTimes.push(e),s.recentTimes.length>this._maxRecentSamples&&s.recentTimes.shift(),this.calculateAdvancedStats(s)}calculateAdvancedStats(t){if(t.recentTimes.length===0)return;let e=t.recentTimes.reduce((o,h)=>o+h,0)/t.recentTimes.length,s=t.recentTimes.reduce((o,h)=>o+Math.pow(h-e,2),0)/t.recentTimes.length;t.standardDeviation=Math.sqrt(s);let i=[...t.recentTimes].sort((o,h)=>o-h),n=i.length;t.percentile95=i[Math.floor(n*.95)]||0,t.percentile99=i[Math.floor(n*.99)]||0}getSystemData(t){return this._systemData.get(t)}getSystemStats(t){return this._systemStats.get(t)}getAllSystemData(){return new Map(this._systemData)}getAllSystemStats(){return new Map(this._systemStats)}getPerformanceReport(){if(!this._isEnabled)return"Performance monitoring is disabled.";let t=[];t.push("=== ECS Performance Report ==="),t.push("");let e=Array.from(this._systemStats.entries()).sort((i,n)=>n[1].averageTime-i[1].averageTime);for(let[i,n]of e){let o=this._systemData.get(i);t.push(`System: ${i}`),t.push(` Current: ${o==null?void 0:o.executionTime.toFixed(2)}ms (${o==null?void 0:o.entityCount} entities)`),t.push(` Average: ${n.averageTime.toFixed(2)}ms`),t.push(` Min/Max: ${n.minTime.toFixed(2)}ms / ${n.maxTime.toFixed(2)}ms`),t.push(` Total: ${n.totalTime.toFixed(2)}ms (${n.executionCount} calls)`),o!=null&&o.averageTimePerEntity&&o.averageTimePerEntity>0&&t.push(` Per Entity: ${o.averageTimePerEntity.toFixed(4)}ms`),t.push("")}let s=Array.from(this._systemData.values()).reduce((i,n)=>i+n.executionTime,0);return t.push(`Total Frame Time: ${s.toFixed(2)}ms`),t.push(`Systems Count: ${this._systemData.size}`),t.join(`
|
|
2
|
+
`)}reset(){this._systemData.clear(),this._systemStats.clear()}resetSystem(t){this._systemData.delete(t),this._systemStats.delete(t)}getPerformanceWarnings(t=16.67){let e=[];for(let[s,i]of this._systemData.entries())i.executionTime>t&&e.push(`${s}: ${i.executionTime.toFixed(2)}ms (>${t}ms)`);return e}setMaxRecentSamples(t){this._maxRecentSamples=t;for(let e of this._systemStats.values())for(;e.recentTimes.length>t;)e.recentTimes.shift()}};r(b,"PerformanceMonitor");var B=b;var G=class G{constructor(t,e=100,s=1024){this._objects=[],this._createFn=t,this._maxSize=e,this._objectSize=s,this._stats={size:0,maxSize:e,totalCreated:0,totalObtained:0,totalReleased:0,hitRate:0,estimatedMemoryUsage:0}}static getPool(t,e=100,s=1024){let i=this._pools.get(t);return i||(i=new G(()=>new t,e,s),this._pools.set(t,i)),i}obtain(){if(this._stats.totalObtained++,this._objects.length>0){let e=this._objects.pop();return this._stats.size--,this._updateHitRate(),this._updateMemoryUsage(),e}let t=this._createFn();return this._stats.totalCreated++,this._updateHitRate(),t}free(t){this._objects.length<this._maxSize&&(t.reset(),this._objects.push(t),this._stats.size++,this._stats.totalReleased++,this._updateMemoryUsage())}warmUp(t){let e=Math.min(t,this._maxSize);for(;this._objects.length<e;){let s=this._createFn();this._stats.totalCreated++,this._objects.push(s),this._stats.size++}this._updateMemoryUsage()}clear(){this._objects.length=0,this._stats.size=0,this._updateMemoryUsage()}get size(){return this._objects.length}get maxSize(){return this._maxSize}set maxSize(t){for(this._maxSize=t,this._stats.maxSize=t;this._objects.length>this._maxSize;)this._objects.pop(),this._stats.size--;this._updateMemoryUsage()}getStats(){return g({},this._stats)}resetStats(){this._stats.totalCreated=0,this._stats.totalObtained=0,this._stats.totalReleased=0,this._stats.hitRate=0}_updateHitRate(){if(this._stats.totalObtained>0){let t=this._stats.totalObtained-this._stats.totalCreated;this._stats.hitRate=t/this._stats.totalObtained}}_updateMemoryUsage(){this._stats.estimatedMemoryUsage=this._stats.size*this._objectSize}static obtain(t){return this.getPool(t).obtain()}static free(t,e){this.getPool(t).free(e)}static warmUp(t,e){this.getPool(t).warmUp(e)}static clearPool(t){let e=this._pools.get(t);e&&e.clear()}static clearAllPools(){for(let t of this._pools.values())t.clear();this._pools.clear()}static getStats(){let t={};for(let[e,s]of this._pools.entries()){let i=e.name||"Unknown";t[i]=s.getStats()}return t}static getTotalMemoryUsage(){let t=0;for(let e of this._pools.values())t+=e.getStats().estimatedMemoryUsage;return t}static getPerformanceReport(){let t=this.getStats(),e=[];e.push("=== Object Pool Performance Report ==="),e.push(`Total Memory Usage: ${(this.getTotalMemoryUsage()/1024/1024).toFixed(2)} MB`),e.push("");for(let[s,i]of Object.entries(t))e.push(`${s}:`),e.push(` Size: ${i.size}/${i.maxSize}`),e.push(` Hit Rate: ${(i.hitRate*100).toFixed(1)}%`),e.push(` Total Created: ${i.totalCreated}`),e.push(` Total Obtained: ${i.totalObtained}`),e.push(` Memory: ${(i.estimatedMemoryUsage/1024).toFixed(1)} KB`),e.push("");return e.join(`
|
|
3
|
+
`)}};r(G,"Pool");var E=G;E._pools=new Map;var gt=class gt{constructor(t,e,s=[10,50,200],i=1024){this.pools=[],this.totalObtained=0,this.totalReleased=0,this.createFn=t,this.resetFn=e,this.tierSizes=s;for(let n of s)this.pools.push(new E(t,n,i))}obtain(){this.totalObtained++;for(let t of this.pools)if(t.size>0)return t.obtain();return this.createFn()}release(t){this.totalReleased++,this.resetFn(t);for(let e of this.pools)if(e.size<e.maxSize){e.free(t);return}}warmUp(t){let e=t;for(let s of this.pools){let i=Math.min(e,s.maxSize);if(s.warmUp(i),e-=i,e<=0)break}}clear(){for(let t of this.pools)t.clear()}getStats(){let t=0,e=0,s=0,i=[];for(let o of this.pools){let h=o.getStats();i.push(h),t+=h.size,e+=h.maxSize,s+=h.estimatedMemoryUsage}let n=this.totalObtained>0?(this.totalObtained-this.getTotalCreated())/this.totalObtained:0;return{totalSize:t,totalMaxSize:e,totalMemoryUsage:s,tierStats:i,hitRate:n}}getTotalCreated(){return this.pools.reduce((t,e)=>t+e.getStats().totalCreated,0)}};r(gt,"TieredObjectPool");var L=gt,T=class T{constructor(){this.pools=new Map,this.autoCompactInterval=6e4,this.lastCompactTime=0}static getInstance(){return T.instance||(T.instance=new T),T.instance}registerPool(t,e){this.pools.set(t,e)}getPool(t){return this.pools.get(t)||null}update(){let t=Date.now();t-this.lastCompactTime>this.autoCompactInterval&&(this.compactAllPools(),this.lastCompactTime=t)}compactAllPools(){for(let t of this.pools.values())t instanceof E&&t.resetStats()}getAllStats(){let t=new Map;for(let[e,s]of this.pools.entries())(s instanceof E||s instanceof L)&&t.set(e,s.getStats());return t}generateReport(){let t=[];t.push("=== Pool Manager Report ===");let e=0;for(let[s,i]of this.pools.entries())if(t.push(`
|
|
4
|
+
${s}:`),i instanceof E){let n=i.getStats();t.push(" Type: Standard Pool"),t.push(` Size: ${n.size}/${n.maxSize}`),t.push(` Hit Rate: ${(n.hitRate*100).toFixed(1)}%`),t.push(` Memory: ${(n.estimatedMemoryUsage/1024).toFixed(1)} KB`),e+=n.estimatedMemoryUsage}else if(i instanceof L){let n=i.getStats();t.push(" Type: Tiered Pool"),t.push(` Total Size: ${n.totalSize}/${n.totalMaxSize}`),t.push(` Hit Rate: ${(n.hitRate*100).toFixed(1)}%`),t.push(` Memory: ${(n.totalMemoryUsage/1024).toFixed(1)} KB`),e+=n.totalMemoryUsage}return t.push(`
|
|
5
|
+
Total Memory Usage: ${(e/1024/1024).toFixed(2)} MB`),t.join(`
|
|
6
|
+
`)}};r(T,"PoolManager");var Q=T;var _t=class _t{static register(t){if(this.componentTypes.has(t))return this.componentTypes.get(t);if(this.nextBitIndex>=this.maxComponents)throw new Error(`Maximum number of component types (${this.maxComponents}) exceeded`);let e=this.nextBitIndex++;return this.componentTypes.set(t,e),e}static getBitMask(t){let e=this.componentTypes.get(t);if(e===void 0)throw new Error(`Component type ${t.name} is not registered`);return BigInt(1)<<BigInt(e)}static getBitIndex(t){let e=this.componentTypes.get(t);if(e===void 0)throw new Error(`Component type ${t.name} is not registered`);return e}static isRegistered(t){return this.componentTypes.has(t)}static getAllRegisteredTypes(){return new Map(this.componentTypes)}};r(_t,"ComponentRegistry");var c=_t;c.componentTypes=new Map;c.nextBitIndex=0;c.maxComponents=64;var xt=class xt{constructor(t){this.components=[],this.entityToIndex=new Map,this.indexToEntity=[],this.freeIndices=[],this._size=0,this.componentType=t,c.isRegistered(t)||c.register(t)}addComponent(t,e){if(this.entityToIndex.has(t))throw new Error(`Entity ${t} already has component ${this.componentType.name}`);let s;this.freeIndices.length>0?(s=this.freeIndices.pop(),this.components[s]=e,this.indexToEntity[s]=t):(s=this.components.length,this.components.push(e),this.indexToEntity.push(t)),this.entityToIndex.set(t,s),this._size++}getComponent(t){let e=this.entityToIndex.get(t);return e!==void 0?this.components[e]:null}hasComponent(t){return this.entityToIndex.has(t)}removeComponent(t){let e=this.entityToIndex.get(t);if(e===void 0)return null;let s=this.components[e];return this.entityToIndex.delete(t),this.components[e]=null,this.freeIndices.push(e),this._size--,s}forEach(t){for(let e=0;e<this.components.length;e++){let s=this.components[e];s&&t(s,this.indexToEntity[e],e)}}getDenseArray(){let t=[],e=[];for(let s=0;s<this.components.length;s++){let i=this.components[s];i&&(t.push(i),e.push(this.indexToEntity[s]))}return{components:t,entityIds:e}}clear(){this.components.length=0,this.entityToIndex.clear(),this.indexToEntity.length=0,this.freeIndices.length=0,this._size=0}get size(){return this._size}get type(){return this.componentType}compact(){if(this.freeIndices.length===0)return;let t=[],e=[],s=new Map,i=0;for(let n=0;n<this.components.length;n++){let o=this.components[n];o&&(t[i]=o,e[i]=this.indexToEntity[n],s.set(this.indexToEntity[n],i),i++)}this.components=t,this.indexToEntity=e,this.entityToIndex=s,this.freeIndices.length=0}getStats(){let t=this.components.length,e=this._size,s=this.freeIndices.length,i=t>0?s/t:0;return{totalSlots:t,usedSlots:e,freeSlots:s,fragmentation:i}}};r(xt,"ComponentStorage");var yt=xt,Ct=class Ct{constructor(){this.storages=new Map}getStorage(t){let e=this.storages.get(t);return e||(e=new yt(t),this.storages.set(t,e)),e}addComponent(t,e){let s=e.constructor;this.getStorage(s).addComponent(t,e)}getComponent(t,e){let s=this.storages.get(e);return s?s.getComponent(t):null}hasComponent(t,e){let s=this.storages.get(e);return s?s.hasComponent(t):!1}removeComponent(t,e){let s=this.storages.get(e);return s?s.removeComponent(t):null}removeAllComponents(t){for(let e of this.storages.values())e.removeComponent(t)}getComponentMask(t){let e=BigInt(0);for(let[s,i]of this.storages.entries())i.hasComponent(t)&&(e|=c.getBitMask(s));return e}compactAll(){for(let t of this.storages.values())t.compact()}getAllStats(){let t=new Map;for(let[e,s]of this.storages.entries()){let i=e.name||"Unknown";t.set(i,s.getStats())}return t}clear(){for(let t of this.storages.values())t.clear();this.storages.clear()}};r(Ct,"ComponentStorageManager");var J=Ct;var St=class St{compare(t,e){let s=t.updateOrder-e.updateOrder;return s==0&&(s=t.id-e.id),s}};r(St,"EntityComparer");var Y=St,Mt=class Mt{constructor(t={maxSize:16,ttl:5e3,enableLRU:!0}){this.cache=new Map,this.accessOrder=[],this.config=t}get(t){let e=this.cache.get(t);return e?Date.now()-e.lastAccessed>this.config.ttl?(this.cache.delete(t),this.removeFromAccessOrder(t),null):(e.lastAccessed=Date.now(),e.accessCount++,this.config.enableLRU&&this.updateAccessOrder(t),e.component):null}set(t,e){this.cache.size>=this.config.maxSize&&!this.cache.has(t)&&this.evictLeastRecentlyUsed();let s={component:e,lastAccessed:Date.now(),accessCount:1};this.cache.set(t,s),this.config.enableLRU&&this.updateAccessOrder(t)}delete(t){let e=this.cache.delete(t);return e&&this.removeFromAccessOrder(t),e}clear(){this.cache.clear(),this.accessOrder.length=0}has(t){return this.cache.has(t)}evictLeastRecentlyUsed(){if(this.accessOrder.length>0){let t=this.accessOrder[0];this.cache.delete(t),this.accessOrder.shift()}}updateAccessOrder(t){this.removeFromAccessOrder(t),this.accessOrder.push(t)}removeFromAccessOrder(t){let e=this.accessOrder.indexOf(t);e!==-1&&this.accessOrder.splice(e,1)}getStats(){let t=0,e=0;for(let s of this.cache.values())t+=s.accessCount,e++;return{size:this.cache.size,maxSize:this.config.maxSize,hitRate:t>0?e/t:0,averageAccessCount:this.cache.size>0?t/this.cache.size:0}}};r(Mt,"ComponentCache");var wt=Mt,bt=class bt{constructor(t,e){this.components=[],this.updateInterval=1,this._isDestroyed=!1,this._parent=null,this._children=[],this._active=!0,this._tag=0,this._enabled=!0,this._updateOrder=0,this._componentMask=BigInt(0),this._componentTypeToIndex=new Map,this._componentAccessStats=new Map,this.name=t,this.id=e,this._componentCache=new wt}get isDestroyed(){return this._isDestroyed}get parent(){return this._parent}get children(){return[...this._children]}get childCount(){return this._children.length}get active(){return this._active}set active(t){this._active!==t&&(this._active=t,this.onActiveChanged())}get activeInHierarchy(){return this._active?this._parent?this._parent.activeInHierarchy:!0:!1}get tag(){return this._tag}set tag(t){this._tag=t}get enabled(){return this._enabled}set enabled(t){this._enabled=t}get updateOrder(){return this._updateOrder}set updateOrder(t){this._updateOrder=t}get componentMask(){return this._componentMask}createComponent(t,...e){let s=new t(...e);return this.addComponent(s)}addComponentInternal(t){let e=t.constructor;c.isRegistered(e)||c.register(e),t.entity=this;let s=this.components.length;return this.components.push(t),this._componentTypeToIndex.set(e,s),this._componentMask|=c.getBitMask(e),this._componentCache.set(e,t),this._componentAccessStats.set(e,{accessCount:0,lastAccessed:Date.now(),cacheHits:0,cacheMisses:0}),t}addComponent(t){let e=t.constructor;if(this.hasComponent(e))throw new Error(`Entity ${this.name} already has component ${e.name}`);if(this.addComponentInternal(t),this.scene&&this.scene.componentStorageManager&&this.scene.componentStorageManager.addComponent(this.id,t),t.onAddedToEntity(),this.scene&&this.scene.entityProcessors)for(let s of this.scene.entityProcessors.processors)s.onChanged(this);return t}getComponent(t){if(this.updateComponentAccessStats(t),!c.isRegistered(t))return this.recordCacheMiss(t),null;let e=c.getBitMask(t);if((this._componentMask&e)===BigInt(0))return this.recordCacheMiss(t),null;let s=this._componentCache.get(t);if(s)return this.recordCacheHit(t),s;let i=this._componentTypeToIndex.get(t);if(i!==void 0&&i<this.components.length){let n=this.components[i];if(n&&n.constructor===t)return this._componentCache.set(t,n),this.recordCacheHit(t),n}if(this.scene&&this.scene.componentStorageManager){let n=this.scene.componentStorageManager.getComponent(this.id,t);if(n)return this._componentCache.set(t,n),this.rebuildComponentIndex(),this.recordCacheHit(t),n}for(let n=0;n<this.components.length;n++){let o=this.components[n];if(o instanceof t)return this._componentTypeToIndex.set(t,n),this._componentCache.set(t,o),this.recordCacheHit(t),o}return this.recordCacheMiss(t),null}updateComponentAccessStats(t){let e=this._componentAccessStats.get(t);e||(e={accessCount:0,lastAccessed:Date.now(),cacheHits:0,cacheMisses:0},this._componentAccessStats.set(t,e)),e.accessCount++,e.lastAccessed=Date.now()}recordCacheHit(t){let e=this._componentAccessStats.get(t);e&&e.cacheHits++}recordCacheMiss(t){let e=this._componentAccessStats.get(t);e&&e.cacheMisses++}rebuildComponentIndex(){this._componentTypeToIndex.clear();for(let t=0;t<this.components.length;t++){let s=this.components[t].constructor;this._componentTypeToIndex.set(s,t)}}hasComponent(t){if(!c.isRegistered(t))return!1;let e=c.getBitMask(t);return(this._componentMask&e)!==BigInt(0)}getOrCreateComponent(t,...e){let s=this.getComponent(t);return s||(s=this.createComponent(t,...e)),s}removeComponent(t){let e=t.constructor,s=this.components.indexOf(t);if(s!==-1&&(this.components.splice(s,1),this.rebuildComponentIndex()),this._componentCache.delete(e),this._componentAccessStats.delete(e),c.isRegistered(e)&&(this._componentMask&=~c.getBitMask(e)),this.scene&&this.scene.componentStorageManager&&this.scene.componentStorageManager.removeComponent(this.id,e),t.onRemovedFromEntity(),t.entity=null,this.scene&&this.scene.entityProcessors)for(let i of this.scene.entityProcessors.processors)i.onChanged(this)}removeComponentByType(t){let e=this.getComponent(t);return e?(this.removeComponent(e),e):null}removeAllComponents(){let t=[...this.components];this._componentCache.clear(),this._componentTypeToIndex.clear(),this._componentAccessStats.clear(),this._componentMask=BigInt(0);for(let e of t){let s=e.constructor;this.scene&&this.scene.componentStorageManager&&this.scene.componentStorageManager.removeComponent(this.id,s),e.onRemovedFromEntity(),e.entity=null}if(this.components.length=0,this.scene&&this.scene.entityProcessors)for(let e of this.scene.entityProcessors.processors)e.onChanged(this)}addComponents(t){let e=[];for(let s of t)try{e.push(this.addComponent(s))}catch(i){console.warn(`Failed to add component ${s.constructor.name}:`,i)}return e}removeComponentsByTypes(t){let e=[];for(let s of t)e.push(this.removeComponentByType(s));return e}getComponentCacheStats(){let t=new Map;for(let[e,s]of this._componentAccessStats){let i=s.cacheHits+s.cacheMisses;t.set(e.name,M(g({},s),{hitRate:i>0?s.cacheHits/i:0}))}return{cacheStats:this._componentCache.getStats(),accessStats:t,indexMappingSize:this._componentTypeToIndex.size,totalComponents:this.components.length}}warmUpComponentCache(){for(let t=0;t<this.components.length;t++){let e=this.components[t],s=e.constructor;this._componentTypeToIndex.set(s,t),this._componentCache.set(s,e)}}cleanupComponentCache(){let t=Date.now(),e=3e4;for(let[s,i]of this._componentAccessStats)t-i.lastAccessed>e&&i.accessCount<5&&this._componentCache.delete(s)}getComponents(t){let e=[];for(let s of this.components)s instanceof t&&e.push(s);return e}addChild(t){if(t===this)throw new Error("Entity cannot be its own child");return t._parent===this||(t._parent&&t._parent.removeChild(t),t._parent=this,this._children.push(t),!t.scene&&this.scene&&(t.scene=this.scene,this.scene.addEntity(t))),t}removeChild(t){let e=this._children.indexOf(t);return e===-1?!1:(this._children.splice(e,1),t._parent=null,!0)}removeAllChildren(){let t=[...this._children];for(let e of t)this.removeChild(e)}findChild(t,e=!1){for(let s of this._children)if(s.name===t)return s;if(e)for(let s of this._children){let i=s.findChild(t,!0);if(i)return i}return null}findChildrenByTag(t,e=!1){let s=[];for(let i of this._children)i.tag===t&&s.push(i);if(e)for(let i of this._children)s.push(...i.findChildrenByTag(t,!0));return s}getRoot(){let t=this;for(;t._parent;)t=t._parent;return t}isAncestorOf(t){let e=t._parent;for(;e;){if(e===this)return!0;e=e._parent}return!1}isDescendantOf(t){return t.isAncestorOf(this)}getDepth(){let t=0,e=this._parent;for(;e;)t++,e=e._parent;return t}forEachChild(t,e=!1){this._children.forEach((s,i)=>{t(s,i),e&&s.forEachChild(t,!0)})}onActiveChanged(){for(let t of this.components)"onActiveChanged"in t&&typeof t.onActiveChanged=="function"&&t.onActiveChanged();this.scene&&this.scene.eventSystem&&this.scene.eventSystem.emitSync("entity:activeChanged",{entity:this,active:this._active,activeInHierarchy:this.activeInHierarchy})}update(){if(!(!this.activeInHierarchy||this._isDestroyed)){for(let t of this.components)t.enabled&&t.update();for(let t of this._children)t.update()}}destroy(){if(this._isDestroyed)return;this._isDestroyed=!0;let t=[...this._children];for(let e of t)e.destroy();this._parent&&this._parent.removeChild(this),this.removeAllComponents(),this.scene&&this.scene.entities&&this.scene.entities.remove(this)}compareTo(t){return Y.prototype.compare(this,t)}toString(){return`Entity[${this.name}:${this.id}]`}getDebugInfo(){var s;let t=this.getComponentCacheStats(),e=Array.from(t.accessStats.entries()).map(([i,n])=>({componentType:i,accessCount:n.accessCount,cacheHits:n.cacheHits,cacheMisses:n.cacheMisses,hitRate:n.hitRate,lastAccessed:new Date(n.lastAccessed).toISOString()}));return{name:this.name,id:this.id,enabled:this._enabled,active:this._active,activeInHierarchy:this.activeInHierarchy,destroyed:this._isDestroyed,componentCount:this.components.length,componentTypes:this.components.map(i=>i.constructor.name),componentMask:this._componentMask.toString(2),parentId:((s=this._parent)==null?void 0:s.id)||null,childCount:this._children.length,childIds:this._children.map(i=>i.id),depth:this.getDepth(),componentCache:t.cacheStats,componentAccessStats:e,indexMappingSize:t.indexMappingSize}}};r(bt,"Entity");var y=bt;y.entityComparer=new Y;var Tt=class Tt{get count(){return this.buffer.length}constructor(t){this.buffer=[],this._idToEntity=new Map,this._nameToEntities=new Map,this._entitiesToAdd=[],this._entitiesToRemove=[],this._isUpdating=!1,this._scene=t}add(t){this._isUpdating?this._entitiesToAdd.push(t):this.addImmediate(t)}addImmediate(t){this._idToEntity.has(t.id)||(this.buffer.push(t),this._idToEntity.set(t.id,t),this.updateNameIndex(t,!0))}remove(t){this._isUpdating?this._entitiesToRemove.push(t):this.removeImmediate(t)}removeImmediate(t){let e=this.buffer.indexOf(t);e!==-1&&(this.buffer.splice(e,1),this._idToEntity.delete(t.id),this.updateNameIndex(t,!1))}removeAllEntities(){for(let t=this.buffer.length-1;t>=0;t--)this.buffer[t].destroy();this.buffer.length=0,this._idToEntity.clear(),this._nameToEntities.clear(),this._entitiesToAdd.length=0,this._entitiesToRemove.length=0}updateLists(){if(this._entitiesToAdd.length>0){for(let t of this._entitiesToAdd)this.addImmediate(t);this._entitiesToAdd.length=0}if(this._entitiesToRemove.length>0){for(let t of this._entitiesToRemove)this.removeImmediate(t);this._entitiesToRemove.length=0}}update(){this._isUpdating=!0;try{for(let t=0;t<this.buffer.length;t++){let e=this.buffer[t];e.enabled&&!e.isDestroyed&&e.update()}}finally{this._isUpdating=!1}this.updateLists()}findEntity(t){let e=this._nameToEntities.get(t);return e&&e.length>0?e[0]:null}findEntitiesByName(t){return this._nameToEntities.get(t)||[]}findEntityById(t){return this._idToEntity.get(t)||null}findEntitiesByTag(t){let e=[];for(let s of this.buffer)s.tag===t&&e.push(s);return e}findEntitiesWithComponent(t){let e=[];for(let s of this.buffer)s.hasComponent(t)&&e.push(s);return e}forEach(t){for(let e of this.buffer)t(e)}forEachWhere(t,e){for(let s of this.buffer)t(s)&&e(s)}updateNameIndex(t,e){if(t.name)if(e){let s=this._nameToEntities.get(t.name);s||(s=[],this._nameToEntities.set(t.name,s)),s.push(t)}else{let s=this._nameToEntities.get(t.name);if(s){let i=s.indexOf(t);i!==-1&&(s.splice(i,1),s.length===0&&this._nameToEntities.delete(t.name))}}}getStats(){let t=0;for(let e of this.buffer)e.enabled&&!e.isDestroyed&&t++;return{totalEntities:this.buffer.length,activeEntities:t,pendingAdd:this._entitiesToAdd.length,pendingRemove:this._entitiesToRemove.length,nameIndexSize:this._nameToEntities.size}}};r(Tt,"EntityList");var P=Tt;var Et=class Et{constructor(){this._processors=[],this._isDirty=!1}setDirty(){this._isDirty=!0}add(t){this._processors.push(t),this.setDirty()}remove(t){let e=this._processors.indexOf(t);e!==-1&&this._processors.splice(e,1)}getProcessor(t){for(let e of this._processors)if(e instanceof t)return e;return null}begin(){this.sortProcessors();for(let t of this._processors)t.initialize()}end(){}update(){this.sortProcessors();for(let t of this._processors)t.update()}lateUpdate(){for(let t of this._processors)t.lateUpdate()}sortProcessors(){this._isDirty&&(this._processors.sort((t,e)=>t.updateOrder-e.updateOrder),this._isDirty=!1)}get processors(){return this._processors}get count(){return this._processors.length}};r(Et,"EntityProcessorList");var R=Et;var It=class It{constructor(){this._nextAvailableId=0,this._ids=[]}checkOut(){return this._ids.length>0?this._ids.pop():this._nextAvailableId++}checkIn(t){this._ids.push(t)}};r(It,"IdentifierPool");var F=It;var At=class At{constructor(){this.wasmCore=null,this.wasmModule=null,this.initialized=!1,this.usingWasm=!1,this.silent=!1,this.jsEntityMasks=new Map,this.jsNextEntityId=1,this.jsQueryCount=0,this.jsUpdateCount=0}setSilent(t){this.silent=t}async initialize(){if(this.initialized)return!0;this.silent||console.log("\u{1F504} \u521D\u59CB\u5316ECS\u6838\u5FC3...");try{let t="../../bin/wasm/ecs_wasm_core";if(!this.silent&&(console.log(`\u{1F50D} \u5C1D\u8BD5\u52A0\u8F7DWASM\u6A21\u5757: ${t}`),console.log(`\u{1F4C1} \u5F53\u524D\u6587\u4EF6\u4F4D\u7F6E: ${typeof __filename!="undefined"?__filename:"unknown"}`),console.log(`\u{1F4C2} \u5DE5\u4F5C\u76EE\u5F55: ${typeof process!="undefined"?process.cwd():"unknown"}`),typeof __filename!="undefined"&&typeof p!="undefined")){let e=p("path"),s=p("fs"),i=e.dirname(__filename),n=e.resolve(i,t);console.log(`\u{1F4CD} \u8BA1\u7B97\u7684\u7EDD\u5BF9\u8DEF\u5F84: ${n}`);let o=n+".js",h=e.resolve(i,"../../bin/wasm/ecs_wasm_core_bg.wasm");console.log(`\u{1F4C4} \u68C0\u67E5JS\u6587\u4EF6: ${o} - ${s.existsSync(o)?"\u5B58\u5728":"\u4E0D\u5B58\u5728"}`),console.log(`\u{1F4C4} \u68C0\u67E5WASM\u6587\u4EF6: ${h} - ${s.existsSync(h)?"\u5B58\u5728":"\u4E0D\u5B58\u5728"}`)}if(this.wasmModule=await import(t),this.silent||console.log("\u2705 WASM\u6A21\u5757\u5BFC\u5165\u6210\u529F\uFF0C\u6B63\u5728\u521D\u59CB\u5316..."),this.wasmModule){if(!this.silent&&(console.log("\u{1F50D} WASM\u6A21\u5757\u5C06\u5C1D\u8BD5\u52A0\u8F7D .wasm \u6587\u4EF6..."),typeof __filename!="undefined"&&typeof p!="undefined")){let e=p("path"),{pathToFileURL:s}=p("url"),i=e.dirname(__filename),n=e.resolve(i,"../../bin/wasm/ecs_wasm_core.js"),o=e.resolve(i,"../../bin/wasm/ecs_wasm_core_bg.wasm"),h=s(n).href,m=new URL("ecs_wasm_core_bg.wasm",h).href;console.log(`\u{1F4CD} WASM JS\u6587\u4EF6URL: ${h}`),console.log(`\u{1F4CD} \u9884\u671F\u7684.wasm\u6587\u4EF6URL: ${m}`),console.log(`\u{1F4CD} \u5B9E\u9645.wasm\u6587\u4EF6\u8DEF\u5F84: ${o}`);let f=p("fs");console.log(`\u{1F4C4} .wasm\u6587\u4EF6\u662F\u5426\u5B58\u5728: ${f.existsSync(o)?"\u5B58\u5728":"\u4E0D\u5B58\u5728"}`)}if(typeof p!="undefined"){let e=p("fs"),s=p("path"),i=s.dirname(__filename),n=s.resolve(i,"../../bin/wasm/ecs_wasm_core_bg.wasm");if(this.silent||console.log(`\u{1F527} \u5728Node.js\u73AF\u5883\u4E2D\u624B\u52A8\u52A0\u8F7DWASM\u6587\u4EF6: ${n}`),e.existsSync(n)){let o=e.readFileSync(n);this.wasmModule.initSync?this.wasmModule.initSync(o):await this.wasmModule.default({module_or_path:o})}else throw new Error(`WASM\u6587\u4EF6\u4E0D\u5B58\u5728: ${n}`)}else await this.wasmModule.default();this.wasmCore=new this.wasmModule.EcsCore}this.usingWasm=!0,this.silent||console.log("\u2705 WASM\u6A21\u5757\u52A0\u8F7D\u6210\u529F")}catch(t){this.silent||(console.warn("\u26A0\uFE0F WASM\u52A0\u8F7D\u5931\u8D25\uFF0C\u4F7F\u7528JavaScript\u5B9E\u73B0"),console.warn(`\u274C \u9519\u8BEF\u8BE6\u60C5: ${t}`)),this.usingWasm=!1}return this.initialized=!0,this.silent||console.log(`\u{1F3AE} ECS\u6838\u5FC3\u521D\u59CB\u5316\u5B8C\u6210 (${this.usingWasm?"WASM":"JavaScript"})`),!0}createEntity(){if(this.ensureInitialized(),this.usingWasm&&this.wasmCore)return this.wasmCore.create_entity();{let t=this.jsNextEntityId++;return this.jsEntityMasks.set(t,BigInt(0)),t}}destroyEntity(t){return this.ensureInitialized(),this.usingWasm&&this.wasmCore?this.wasmCore.destroy_entity(t):this.jsEntityMasks.delete(t)}updateEntityMask(t,e){this.ensureInitialized(),this.usingWasm&&this.wasmCore?this.wasmCore.update_entity_mask(t,e):(this.jsEntityMasks.set(t,e),this.jsUpdateCount++)}batchUpdateMasks(t,e){if(this.ensureInitialized(),t.length!==e.length)throw new Error("\u5B9E\u4F53ID\u548C\u63A9\u7801\u6570\u7EC4\u957F\u5EA6\u5FC5\u987B\u76F8\u540C");if(this.usingWasm&&this.wasmCore){let s=new Uint32Array(t),i=new BigUint64Array(e);this.wasmCore.batch_update_masks(s,i)}else{for(let s=0;s<t.length;s++)this.jsEntityMasks.set(t[s],e[s]);this.jsUpdateCount+=t.length}}queryEntities(t,e=1e4){var i;if(this.ensureInitialized(),this.usingWasm&&this.wasmCore)try{let n=this.wasmCore.query_entities(t,e),o=this.wasmCore.get_query_result_count();if(n&&o>0&&((i=this.wasmModule)!=null&&i.memory)){let h=new Uint32Array(this.wasmModule.memory.buffer,n,o);return{entities:new Uint32Array(h),count:o}}else return{entities:new Uint32Array(0),count:0}}catch(n){this.silent||console.warn("WASM\u67E5\u8BE2\u5931\u8D25\uFF0C\u56DE\u9000\u5230JavaScript\u5B9E\u73B0:",n)}this.jsQueryCount++;let s=[];for(let[n,o]of this.jsEntityMasks)if((o&t)===t&&(s.push(n),s.length>=e))break;return{entities:new Uint32Array(s),count:s.length}}queryCached(t){var e;if(this.ensureInitialized(),this.usingWasm&&this.wasmCore)try{let s=this.wasmCore.query_cached(t),i=this.wasmCore.get_cached_query_count(t);if(s&&i>0&&((e=this.wasmModule)!=null&&e.memory)){let n=new Uint32Array(this.wasmModule.memory.buffer,s,i);return{entities:new Uint32Array(n),count:i}}return{entities:new Uint32Array(0),count:0}}catch(s){return this.silent||console.warn("WASM\u7F13\u5B58\u67E5\u8BE2\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u901A\u7528\u67E5\u8BE2:",s),this.queryEntities(t)}return this.queryEntities(t)}queryMultipleComponents(t,e=1e4){var i;if(this.ensureInitialized(),this.usingWasm&&this.wasmCore)try{let n=new BigUint64Array(t);return this.wasmCore.query_multiple_components(n,e)&&((i=this.wasmModule)!=null&&i.memory)?{entities:new Uint32Array(0),count:0}:{entities:new Uint32Array(0),count:0}}catch(n){this.silent||console.warn("WASM\u591A\u7EC4\u4EF6\u67E5\u8BE2\u5931\u8D25\uFF0C\u56DE\u9000\u5230JavaScript\u5B9E\u73B0:",n)}this.jsQueryCount++;let s=[];for(let[n,o]of this.jsEntityMasks){let h=!0;for(let m of t)if((o&m)!==m){h=!1;break}if(h&&(s.push(n),s.length>=e))break}return{entities:new Uint32Array(s),count:s.length}}queryWithExclusion(t,e,s=1e4){var n;if(this.ensureInitialized(),this.usingWasm&&this.wasmCore)try{return this.wasmCore.query_with_exclusion(t,e,s)&&((n=this.wasmModule)!=null&&n.memory)?{entities:new Uint32Array(0),count:0}:{entities:new Uint32Array(0),count:0}}catch(o){this.silent||console.warn("WASM\u6392\u9664\u67E5\u8BE2\u5931\u8D25\uFF0C\u56DE\u9000\u5230JavaScript\u5B9E\u73B0:",o)}this.jsQueryCount++;let i=[];for(let[o,h]of this.jsEntityMasks)if((h&t)===t&&(h&e)===BigInt(0)&&(i.push(o),i.length>=s))break;return{entities:new Uint32Array(i),count:i.length}}getEntityMask(t){return this.ensureInitialized(),this.usingWasm&&this.wasmCore?this.wasmCore.get_entity_mask(t)||null:this.jsEntityMasks.get(t)||null}entityExists(t){return this.ensureInitialized(),this.usingWasm&&this.wasmCore?this.wasmCore.entity_exists(t):this.jsEntityMasks.has(t)}createComponentMask(t){if(this.usingWasm&&this.wasmModule)return this.wasmModule.create_component_mask(new Uint32Array(t));{let e=BigInt(0);for(let s of t)s<64&&(e|=BigInt(1)<<BigInt(s));return e}}maskContainsComponent(t,e){return this.usingWasm&&this.wasmModule?this.wasmModule.mask_contains_component(t,e):e>=64?!1:(t&BigInt(1)<<BigInt(e))!==BigInt(0)}getPerformanceStats(){if(this.ensureInitialized(),this.usingWasm&&this.wasmCore){let t=Array.from(this.wasmCore.get_performance_stats());return{entityCount:t[0],indexCount:t[1],queryCount:t[2],updateCount:t[3],wasmEnabled:!0}}else return{entityCount:this.jsEntityMasks.size,indexCount:0,queryCount:this.jsQueryCount,updateCount:this.jsUpdateCount,wasmEnabled:!1}}clear(){this.ensureInitialized(),this.usingWasm&&this.wasmCore?this.wasmCore.clear():(this.jsEntityMasks.clear(),this.jsNextEntityId=1,this.jsQueryCount=0,this.jsUpdateCount=0)}isUsingWasm(){return this.usingWasm}isInitialized(){return this.initialized}ensureInitialized(){if(!this.initialized)throw new Error("ECS\u6838\u5FC3\u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u8C03\u7528 initialize()")}cleanup(){var t,e;if(this.usingWasm&&this.wasmCore)try{(e=(t=this.wasmCore).free)==null||e.call(t)}catch(s){this.silent||console.warn("\u26A0\uFE0F \u6E05\u7406WASM\u8D44\u6E90\u65F6\u51FA\u9519:",s)}this.wasmCore=null,this.wasmModule=null,this.jsEntityMasks.clear(),this.initialized=!1,this.usingWasm=!1}};r(At,"WasmEcsCore");var K=At,d=new K;async function ue(a=!1){return d.setSilent(a),d.initialize()}r(ue,"initializeEcs");var me={withComponent:r((a,t)=>{let e=d.createComponentMask([a]);return d.queryEntities(e,t)},"withComponent"),withComponents:r((a,t)=>{let e=a.map(s=>d.createComponentMask([s]));return d.queryMultipleComponents(e,t)},"withComponents"),withExclusion:r((a,t,e)=>{let s=d.createComponentMask(a),i=d.createComponentMask(t);return d.queryWithExclusion(s,i,e)},"withExclusion")};var kt=class kt{constructor(t,e,s=1e3){this.pool=[],this.createFn=t,this.resetFn=e,this.maxSize=s}acquire(){return this.pool.length>0?this.pool.pop():this.createFn()}release(t){this.pool.length<this.maxSize&&(this.resetFn&&this.resetFn(t),this.pool.push(t))}prewarm(t){for(let e=0;e<t&&this.pool.length<this.maxSize;e++)this.pool.push(this.createFn())}clear(){this.pool.length=0}getAvailableCount(){return this.pool.length}getMaxSize(){return this.maxSize}};r(kt,"ComponentPool");var vt=kt,I=class I{constructor(){this.pools=new Map}static getInstance(){return I.instance||(I.instance=new I),I.instance}registerPool(t,e,s,i){this.pools.set(t,new vt(e,s,i))}acquireComponent(t){let e=this.pools.get(t);return e?e.acquire():null}releaseComponent(t,e){let s=this.pools.get(t);s&&s.release(e)}prewarmAll(t=100){for(let e of this.pools.values())e.prewarm(t)}clearAll(){for(let t of this.pools.values())t.clear()}getPoolStats(){let t=new Map;for(let[e,s]of this.pools)t.set(e,{available:s.getAvailableCount(),maxSize:s.getMaxSize()});return t}};r(I,"ComponentPoolManager");var Z=I;var A=class A{constructor(){this.maskCache=new Map,this.componentTypeMap=new Map,this.nextComponentId=0}static getInstance(){return A.instance||(A.instance=new A),A.instance}registerComponentType(t){return this.componentTypeMap.has(t)||this.componentTypeMap.set(t,this.nextComponentId++),this.componentTypeMap.get(t)}getComponentTypeId(t){return this.componentTypeMap.get(t)}createSingleComponentMask(t){let e=`single:${t}`;if(this.maskCache.has(e))return this.maskCache.get(e);let s=this.getComponentTypeId(t);if(s===void 0)throw new Error(`Component type not registered: ${t}`);let i=BigInt(1)<<BigInt(s);return this.maskCache.set(e,i),i}createCombinedMask(t){let s=`combined:${[...t].sort().join(",")}`;if(this.maskCache.has(s))return this.maskCache.get(s);let i=BigInt(0);for(let n of t){let o=this.getComponentTypeId(n);if(o===void 0)throw new Error(`Component type not registered: ${n}`);i|=BigInt(1)<<BigInt(o)}return this.maskCache.set(s,i),i}maskContainsComponent(t,e){let s=this.createSingleComponentMask(e);return(t&s)!==BigInt(0)}maskContainsAllComponents(t,e){let s=this.createCombinedMask(e);return(t&s)===s}maskContainsAnyComponent(t,e){let s=this.createCombinedMask(e);return(t&s)!==BigInt(0)}addComponentToMask(t,e){let s=this.createSingleComponentMask(e);return t|s}removeComponentFromMask(t,e){let s=this.createSingleComponentMask(e);return t&~s}precomputeCommonMasks(t){for(let e of t)this.createCombinedMask(e)}getCacheStats(){return{size:this.maskCache.size,componentTypes:this.componentTypeMap.size}}clearCache(){this.maskCache.clear()}reset(){this.maskCache.clear(),this.componentTypeMap.clear(),this.nextComponentId=0}maskToComponentNames(t){let e=[];for(let[s,i]of this.componentTypeMap){let n=BigInt(1)<<BigInt(i);(t&n)!==BigInt(0)&&e.push(s)}return e}getComponentCount(t){let e=0,s=t;for(;s!==BigInt(0);)(s&BigInt(1))!==BigInt(0)&&e++,s>>=BigInt(1);return e}};r(A,"BitMaskOptimizer");var V=A;var w;(function(a){a.ADD_ENTITY="add_entity",a.REMOVE_ENTITY="remove_entity",a.UPDATE_ENTITY="update_entity"})(w||(w={}));var zt=class zt{constructor(){this.pendingOperations=[],this.isProcessing=!1,this.batchSize=1e3,this.flushTimeout=null,this.flushDelay=16}addOperation(t){this.pendingOperations.push(t),this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}addEntities(t){for(let e of t)this.pendingOperations.push({type:w.ADD_ENTITY,entity:e});this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}removeEntities(t){for(let e of t)this.pendingOperations.push({type:w.REMOVE_ENTITY,entity:e});this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}updateEntities(t){for(let e of t)this.pendingOperations.push({type:w.UPDATE_ENTITY,entity:e.entity,oldMask:e.oldMask,newMask:e.newMask});this.pendingOperations.length>=this.batchSize?this.flush():this.scheduleFlush()}scheduleFlush(){this.flushTimeout||(this.flushTimeout=setTimeout(()=>{this.flush()},this.flushDelay))}flush(){if(!(this.isProcessing||this.pendingOperations.length===0)){this.isProcessing=!0,this.flushTimeout&&(clearTimeout(this.flushTimeout),this.flushTimeout=null);try{this.processBatch()}finally{this.isProcessing=!1}}}processBatch(){let t=this.pendingOperations;this.pendingOperations=[];let e=[],s=[],i=[];for(let n of t)switch(n.type){case w.ADD_ENTITY:e.push(n.entity);break;case w.REMOVE_ENTITY:s.push(n.entity);break;case w.UPDATE_ENTITY:n.oldMask!==void 0&&n.newMask!==void 0&&i.push({entity:n.entity,oldMask:n.oldMask,newMask:n.newMask});break}e.length>0&&this.processBatchAdd(e),s.length>0&&this.processBatchRemove(s),i.length>0&&this.processBatchUpdate(i)}processBatchAdd(t){this.onBatchAdd&&this.onBatchAdd(t)}processBatchRemove(t){this.onBatchRemove&&this.onBatchRemove(t)}processBatchUpdate(t){this.onBatchUpdate&&this.onBatchUpdate(t)}setBatchSize(t){this.batchSize=Math.max(1,t)}setFlushDelay(t){this.flushDelay=Math.max(0,t)}getPendingCount(){return this.pendingOperations.length}clear(){this.pendingOperations.length=0,this.flushTimeout&&(clearTimeout(this.flushTimeout),this.flushTimeout=null)}hasPendingOperations(){return this.pendingOperations.length>0}};r(zt,"IndexUpdateBatcher");var X=zt;var S;(function(a){a.ALL="all",a.ANY="any",a.NONE="none"})(S||(S={}));var Bt=class Bt{constructor(){this.entities=[],this.wasmAvailable=!1,this.indexDirty=!0,this.queryCache=new Map,this.cacheMaxSize=1e3,this.cacheTimeout=5e3,this.queryStats={totalQueries:0,cacheHits:0,indexHits:0,linearScans:0},this.entityIndex={byMask:new Map,byComponentType:new Map,byTag:new Map,byName:new Map},this.componentPoolManager=Z.getInstance(),this.bitMaskOptimizer=V.getInstance(),this.indexUpdateBatcher=new X,this.indexUpdateBatcher.onBatchAdd=t=>{for(let e of t)this.addEntityToIndexes(e)},this.indexUpdateBatcher.onBatchRemove=t=>{for(let e of t)this.removeEntityFromIndexes(e)},this.indexUpdateBatcher.onBatchUpdate=t=>{for(let e of t)this.removeEntityFromIndexes(e.entity),this.addEntityToIndexes(e.entity)},this.initializeWasm()}async initializeWasm(){try{let t=await d.initialize();this.wasmAvailable=t&&d.isUsingWasm(),this.wasmAvailable?console.log("QuerySystem: WebAssembly\u8BA1\u7B97\u52A0\u901F\u5DF2\u542F\u7528"):console.log("QuerySystem: \u4F7F\u7528JavaScript\u5B9E\u73B0")}catch(t){console.warn("QuerySystem: WebAssembly\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u4F7F\u7528JavaScript\u5B9E\u73B0:",t),this.wasmAvailable=!1}}setEntities(t){this.entities=t,this.clearQueryCache(),this.rebuildIndexes()}addEntity(t,e=!1){this.entities.includes(t)||(this.entities.push(t),this.addEntityToIndexes(t),e||this.clearQueryCache())}addEntities(t){if(t.length===0)return;let e=new Set(this.entities.map(i=>i.id)),s=0;for(let i of t)e.has(i.id)||(this.entities.push(i),this.addEntityToIndexes(i),e.add(i.id),s++);s>0&&this.clearQueryCache()}addEntitiesUnchecked(t){if(t.length!==0){for(let e of t)this.entities.push(e);for(let e of t)this.addEntityToIndexes(e);this.clearQueryCache()}}removeEntity(t){let e=this.entities.indexOf(t);e!==-1&&(this.entities.splice(e,1),this.removeEntityFromIndexes(t),this.clearQueryCache())}addEntityToIndexes(t){let e=t.componentMask,s=this.entityIndex.byMask.get(e);s||(s=new Set,this.entityIndex.byMask.set(e,s)),s.add(t);let i=t.components;for(let h=0;h<i.length;h++){let m=i[h].constructor,f=this.entityIndex.byComponentType.get(m);f||(f=new Set,this.entityIndex.byComponentType.set(m,f)),f.add(t)}let n=t.tag;if(n!==void 0){let h=this.entityIndex.byTag.get(n);h||(h=new Set,this.entityIndex.byTag.set(n,h)),h.add(t)}let o=t.name;if(o){let h=this.entityIndex.byName.get(o);h||(h=new Set,this.entityIndex.byName.set(o,h)),h.add(t)}}removeEntityFromIndexes(t){let e=t.componentMask,s=this.entityIndex.byMask.get(e);s&&(s.delete(t),s.size===0&&this.entityIndex.byMask.delete(e));for(let i of t.components){let n=i.constructor,o=this.entityIndex.byComponentType.get(n);o&&(o.delete(t),o.size===0&&this.entityIndex.byComponentType.delete(n))}if(t.tag!==void 0){let i=this.entityIndex.byTag.get(t.tag);i&&(i.delete(t),i.size===0&&this.entityIndex.byTag.delete(t.tag))}if(t.name){let i=this.entityIndex.byName.get(t.name);i&&(i.delete(t),i.size===0&&this.entityIndex.byName.delete(t.name))}}rebuildIndexes(){this.entityIndex.byMask.clear(),this.entityIndex.byComponentType.clear(),this.entityIndex.byTag.clear(),this.entityIndex.byName.clear();for(let t of this.entities)this.addEntityToIndexes(t);this.indexDirty=!1}queryAll(...t){let e=performance.now();this.queryStats.totalQueries++;let s=`all:${t.map(o=>o.name).sort().join(",")}`,i=this.getFromCache(s);if(i)return this.queryStats.cacheHits++,{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!0};let n;return t.length===1?(this.queryStats.indexHits++,n=Array.from(this.entityIndex.byComponentType.get(t[0])||[])):n=this.queryMultipleComponents(t),this.addToCache(s,n),{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!1}}queryMultipleComponents(t){let e=null,s=1/0;for(let o of t){let h=this.entityIndex.byComponentType.get(o);if(!h||h.size===0)return[];h.size<s&&(s=h.size,e=h)}if(!e)return this.queryStats.linearScans++,this.queryByLinearScan(t);let i=this.createComponentMask(t),n=[];for(let o of e)(o.componentMask&i)===i&&n.push(o);return n}queryByLinearScan(t){let e=this.createComponentMask(t);return this.entities.filter(s=>(s.componentMask&e)===e)}queryAny(...t){let e=performance.now();this.queryStats.totalQueries++;let s=`any:${t.map(h=>h.name).sort().join(",")}`,i=this.getFromCache(s);if(i)return this.queryStats.cacheHits++,{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!0};let n=new Set;for(let h of t){let m=this.entityIndex.byComponentType.get(h);if(m)for(let f of m)n.add(f)}let o=Array.from(n);return this.addToCache(s,o),{entities:o,count:o.length,executionTime:performance.now()-e,fromCache:!1}}queryNone(...t){let e=performance.now();this.queryStats.totalQueries++;let s=`none:${t.map(h=>h.name).sort().join(",")}`,i=this.getFromCache(s);if(i)return this.queryStats.cacheHits++,{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!0};let n=this.createComponentMask(t),o=this.entities.filter(h=>(h.componentMask&n)===BigInt(0));return this.addToCache(s,o),{entities:o,count:o.length,executionTime:performance.now()-e,fromCache:!1}}queryByTag(t){let e=performance.now();this.queryStats.totalQueries++;let s=`tag:${t}`,i=this.getFromCache(s);if(i)return this.queryStats.cacheHits++,{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;let n=Array.from(this.entityIndex.byTag.get(t)||[]);return this.addToCache(s,n),{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!1}}queryByName(t){let e=performance.now();this.queryStats.totalQueries++;let s=`name:${t}`,i=this.getFromCache(s);if(i)return this.queryStats.cacheHits++,{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;let n=Array.from(this.entityIndex.byName.get(t)||[]);return this.addToCache(s,n),{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!1}}queryByComponent(t){let e=performance.now();this.queryStats.totalQueries++;let s=`component:${t.name}`,i=this.getFromCache(s);if(i)return this.queryStats.cacheHits++,{entities:i,count:i.length,executionTime:performance.now()-e,fromCache:!0};this.queryStats.indexHits++;let n=Array.from(this.entityIndex.byComponentType.get(t)||[]);return this.addToCache(s,n),{entities:n,count:n.length,executionTime:performance.now()-e,fromCache:!1}}getFromCache(t){let e=this.queryCache.get(t);return e?Date.now()-e.timestamp>this.cacheTimeout?(this.queryCache.delete(t),null):(e.hitCount++,e.entities):null}addToCache(t,e){this.queryCache.size>=this.cacheMaxSize&&this.cleanupCache(),this.queryCache.set(t,{entities:[...e],timestamp:Date.now(),hitCount:0})}cleanupCache(){let t=Date.now();for(let[e,s]of this.queryCache.entries())t-s.timestamp>this.cacheTimeout&&this.queryCache.delete(e);if(this.queryCache.size>=this.cacheMaxSize){let e=Array.from(this.queryCache.entries());e.sort((i,n)=>i[1].hitCount-n[1].hitCount);let s=Math.floor(this.cacheMaxSize*.2);for(let i=0;i<s&&i<e.length;i++)this.queryCache.delete(e[i][0])}}clearQueryCache(){this.queryCache.clear()}clearCache(){this.clearQueryCache()}batchUpdateComponents(t){if(this.wasmAvailable&&t.length>100)try{let e=t.map(i=>i.entityId),s=t.map(i=>i.componentMask);d.batchUpdateMasks(e,s),console.log(`WebAssembly\u52A0\u901F\u6279\u91CF\u66F4\u65B0 ${t.length} \u4E2A\u5B9E\u4F53`)}catch(e){console.warn("WebAssembly\u6279\u91CF\u66F4\u65B0\u5931\u8D25\uFF0C\u56DE\u9000\u5230JavaScript\u5B9E\u73B0:",e),this.batchUpdateComponentsJS(t)}else this.batchUpdateComponentsJS(t);this.clearQueryCache()}batchUpdateComponentsJS(t){for(let e of t)this.entities.find(i=>i.id===e.entityId)&&console.log(`\u66F4\u65B0\u5B9E\u4F53 ${e.entityId} \u7684\u7EC4\u4EF6\u63A9\u7801: ${e.componentMask}`);this.rebuildIndexes()}getAccelerationStatus(){return{wasmEnabled:this.wasmAvailable,currentProvider:this.wasmAvailable?"hybrid":"javascript",availableProviders:["javascript","hybrid"],performanceInfo:{entityCount:this.entities.length,wasmEnabled:this.wasmAvailable,cacheStats:{size:this.queryCache.size,hitRate:this.queryStats.totalQueries>0?(this.queryStats.cacheHits/this.queryStats.totalQueries*100).toFixed(2)+"%":"0%"}}}}async switchAccelerationProvider(t){return!0}createComponentMask(t){let e=t.map(s=>s.name);for(let s of e)this.bitMaskOptimizer.registerComponentType(s);return this.bitMaskOptimizer.createCombinedMask(e)}getStats(){return{entityCount:this.entities.length,indexStats:{maskIndexSize:this.entityIndex.byMask.size,componentIndexSize:this.entityIndex.byComponentType.size,tagIndexSize:this.entityIndex.byTag.size,nameIndexSize:this.entityIndex.byName.size},accelerationStatus:this.getAccelerationStatus(),queryStats:M(g({},this.queryStats),{cacheHitRate:this.queryStats.totalQueries>0?(this.queryStats.cacheHits/this.queryStats.totalQueries*100).toFixed(2)+"%":"0%"})}}};r(Bt,"QuerySystem");var tt=Bt,Ot=class Ot{constructor(t){this.conditions=[],this.querySystem=t}withAll(...t){return this.conditions.push({type:S.ALL,componentTypes:t,mask:this.createComponentMask(t)}),this}withAny(...t){return this.conditions.push({type:S.ANY,componentTypes:t,mask:this.createComponentMask(t)}),this}without(...t){return this.conditions.push({type:S.NONE,componentTypes:t,mask:this.createComponentMask(t)}),this}execute(){let t=performance.now();if(this.conditions.length===1){let e=this.conditions[0];switch(e.type){case S.ALL:return this.querySystem.queryAll(...e.componentTypes);case S.ANY:return this.querySystem.queryAny(...e.componentTypes);case S.NONE:return this.querySystem.queryNone(...e.componentTypes)}}return{entities:[],count:0,executionTime:performance.now()-t,fromCache:!1}}createComponentMask(t){let e=BigInt(0);for(let s of t)try{let i=c.getBitMask(s);e|=i}catch(i){console.warn(`\u7EC4\u4EF6\u7C7B\u578B ${s.name} \u672A\u6CE8\u518C\uFF0C\u8DF3\u8FC7`)}return e}reset(){return this.conditions=[],this}};r(Ot,"QueryBuilder");var et=Ot;var Ut=class Ut{constructor(){this.listeners=new Map,this.stats=new Map,this.batchQueue=new Map,this.batchTimers=new Map,this.batchConfigs=new Map,this.nextListenerId=0,this.isEnabled=!0,this.maxListeners=100}on(t,e,s={}){return this.addListener(t,e,s)}once(t,e,s={}){return this.addListener(t,e,M(g({},s),{once:!0}))}onAsync(t,e,s={}){return this.addListener(t,e,M(g({},s),{async:!0}))}off(t,e){let s=this.listeners.get(t);if(!s)return!1;let i=s.findIndex(n=>n.id===e);return i===-1?!1:(s.splice(i,1),s.length===0&&(this.listeners.delete(t),this.stats.delete(t)),!0)}offAll(t){this.listeners.delete(t),this.stats.delete(t),this.clearBatch(t)}async emit(t,e){if(!this.isEnabled)return;let s=this.batchConfigs.get(t);if(s!=null&&s.enabled){this.addToBatch(t,e);return}await this.executeEvent(t,e)}emitSync(t,e){if(!this.isEnabled)return;let s=this.listeners.get(t);if(!s||s.length===0)return;let i=performance.now(),n=[],o=this.sortListenersByPriority(s);for(let h of o)if(!h.config.async)try{h.config.context?h.handler.call(h.config.context,e):h.handler(e),h.config.once&&n.push(h.id)}catch(m){console.error(`Error in event handler for ${t}:`,m)}this.removeListeners(t,n),this.updateStats(t,performance.now()-i)}setBatchConfig(t,e){this.batchConfigs.set(t,e)}flushBatch(t){let e=this.batchQueue.get(t);if(!e||e.length===0)return;let s=this.batchTimers.get(t);s&&(clearTimeout(s),this.batchTimers.delete(t)),this.processBatch(t,e),this.batchQueue.delete(t)}getStats(t){return t?this.stats.get(t)||this.createEmptyStats(t):new Map(this.stats)}resetStats(t){t?this.stats.delete(t):this.stats.clear()}setEnabled(t){this.isEnabled=t}hasListeners(t){let e=this.listeners.get(t);return e?e.length>0:!1}getListenerCount(t){let e=this.listeners.get(t);return e?e.length:0}clear(){this.listeners.clear(),this.stats.clear(),this.clearAllBatches()}setMaxListeners(t){this.maxListeners=t}addListener(t,e,s){let i=this.listeners.get(t);if(i||(i=[],this.listeners.set(t,i)),i.length>=this.maxListeners)return console.warn(`Maximum listeners (${this.maxListeners}) exceeded for event type: ${t}`),"";let n=`listener_${this.nextListenerId++}`,o={handler:e,config:g({priority:0},s),id:n};return i.push(o),this.stats.has(t)||this.stats.set(t,this.createEmptyStats(t)),n}async executeEvent(t,e){let s=this.listeners.get(t);if(!s||s.length===0)return;let i=performance.now(),n=[],o=this.sortListenersByPriority(s),h=o.filter(u=>!u.config.async),m=o.filter(u=>u.config.async);for(let u of h)try{u.config.context?u.handler.call(u.config.context,e):u.handler(e),u.config.once&&n.push(u.id)}catch(ct){console.error(`Error in sync event handler for ${t}:`,ct)}let f=m.map(async u=>{try{u.config.context?await u.handler.call(u.config.context,e):await u.handler(e),u.config.once&&n.push(u.id)}catch(ct){console.error(`Error in async event handler for ${t}:`,ct)}});await Promise.all(f),this.removeListeners(t,n),this.updateStats(t,performance.now()-i)}sortListenersByPriority(t){return t.slice().sort((e,s)=>(s.config.priority||0)-(e.config.priority||0))}removeListeners(t,e){if(e.length===0)return;let s=this.listeners.get(t);if(s){for(let i of e){let n=s.findIndex(o=>o.id===i);n!==-1&&s.splice(n,1)}s.length===0&&(this.listeners.delete(t),this.stats.delete(t))}}addToBatch(t,e){let s=this.batchQueue.get(t);s||(s=[],this.batchQueue.set(t,s)),s.push(e);let i=this.batchConfigs.get(t);if(s.length>=i.batchSize){this.flushBatch(t);return}if(!this.batchTimers.has(t)){let n=setTimeout(()=>{this.flushBatch(t)},i.delay);this.batchTimers.set(t,n)}}async processBatch(t,e){let s={type:t,events:e,count:e.length,timestamp:Date.now()};await this.executeEvent(`${t}:batch`,s)}clearBatch(t){this.batchQueue.delete(t);let e=this.batchTimers.get(t);e&&(clearTimeout(e),this.batchTimers.delete(t))}clearAllBatches(){this.batchQueue.clear();for(let t of this.batchTimers.values())clearTimeout(t);this.batchTimers.clear(),this.batchConfigs.clear()}updateStats(t,e){let s=this.stats.get(t);s||(s=this.createEmptyStats(t),this.stats.set(t,s)),s.triggerCount++,s.totalExecutionTime+=e,s.averageExecutionTime=s.totalExecutionTime/s.triggerCount,s.lastTriggerTime=Date.now(),s.listenerCount=this.getListenerCount(t)}createEmptyStats(t){return{eventType:t,listenerCount:0,triggerCount:0,totalExecutionTime:0,averageExecutionTime:0,lastTriggerTime:0}}};r(Ut,"TypeSafeEventSystem");var N=Ut,ns=new N;var Dt=class Dt{get systems(){return this.entityProcessors.processors}constructor(t=!0){this.name="",this._didSceneBegin=!1,this.entities=new P(this),this.entityProcessors=new R,this.identifierPool=new F,this.componentStorageManager=new J,this.querySystem=new tt,this.eventSystem=new N,this.initialize()}initialize(){}onStart(){}unload(){}begin(){this.entityProcessors!=null&&this.entityProcessors.begin(),this._didSceneBegin=!0,this.onStart()}end(){this._didSceneBegin=!1,this.entities.removeAllEntities(),this.componentStorageManager.clear(),this.entityProcessors&&this.entityProcessors.end(),this.unload()}update(){this.entities.updateLists(),this.entityProcessors!=null&&this.entityProcessors.update(),this.entities.update(),this.entityProcessors!=null&&this.entityProcessors.lateUpdate()}createEntity(t){let e=new y(t,this.identifierPool.checkOut());return this.addEntity(e)}addEntity(t,e=!1){return this.entities.add(t),t.scene=this,this.querySystem.addEntity(t,e),this.eventSystem.emitSync("entity:added",{entity:t,scene:this}),t}createEntities(t,e="Entity"){let s=[];for(let i=0;i<t;i++){let n=new y(`${e}_${i}`,this.identifierPool.checkOut());n.scene=this,s.push(n)}for(let i of s)this.entities.add(i);return this.querySystem.addEntitiesUnchecked(s),this.eventSystem.emitSync("entities:batch_added",{entities:s,scene:this,count:t}),s}createEntitiesOld(t,e="Entity"){let s=[];for(let i=0;i<t;i++){let n=new y(`${e}_${i}`,this.identifierPool.checkOut());s.push(n),this.addEntity(n,!0)}return this.querySystem.clearCache(),s}destroyAllEntities(){for(let t=0;t<this.entities.count;t++)this.entities.buffer[t].destroy()}findEntity(t){return this.entities.findEntity(t)}findEntityById(t){return this.entities.findEntityById(t)}findEntitiesByTag(t){let e=[];for(let s of this.entities.buffer)s.tag===t&&e.push(s);return e}getEntityByName(t){return this.findEntity(t)}getEntitiesByTag(t){return this.findEntitiesByTag(t)}addEntityProcessor(t){return t.scene=this,this.entityProcessors.add(t),t.setUpdateOrder(this.entityProcessors.count-1),t}addSystem(t){return this.addEntityProcessor(t)}removeEntityProcessor(t){this.entityProcessors.remove(t)}getEntityProcessor(t){return this.entityProcessors.getProcessor(t)}getStats(){return{entityCount:this.entities.count,processorCount:this.entityProcessors.count,componentStorageStats:this.componentStorageManager.getAllStats()}}compactComponentStorage(){this.componentStorageManager.compactAll()}getDebugInfo(){return{name:this.constructor.name,entityCount:this.entities.count,processorCount:this.entityProcessors.count,isRunning:this._didSceneBegin,entities:this.entities.buffer.map(t=>({name:t.name,id:t.id,componentCount:t.components.length,componentTypes:t.components.map(e=>e.constructor.name)})),processors:this.entityProcessors.processors.map(t=>{var e;return{name:t.constructor.name,updateOrder:t.updateOrder,entityCount:((e=t._entities)==null?void 0:e.length)||0}}),componentStats:this.componentStorageManager.getAllStats()}}};r(Dt,"Scene");var W=Dt;var it=class it{constructor(t,e){this.scene=t,this.storageManager=e,this.entity=new y("",t.identifierPool.checkOut())}named(t){return this.entity.name=t,this}tagged(t){return this.entity.tag=t,this}with(t){return this.entity.addComponent(t),this}withComponents(...t){for(let e of t)this.entity.addComponent(e);return this}withIf(t,e){return t&&this.entity.addComponent(e),this}withFactory(t){let e=t();return this.entity.addComponent(e),this}configure(t,e){let s=this.entity.getComponent(t);return s&&e(s),this}enabled(t=!0){return this.entity.enabled=t,this}active(t=!0){return this.entity.active=t,this}withChild(t){let e=t.build();return this.entity.addChild(e),this}withChildren(...t){for(let e of t){let s=e.build();this.entity.addChild(s)}return this}withChildFactory(t){let s=t(this.entity).build();return this.entity.addChild(s),this}withChildIf(t,e){if(t){let s=e.build();this.entity.addChild(s)}return this}build(){return this.entity}spawn(){return this.scene.addEntity(this.entity),this.entity}clone(){let t=new it(this.scene,this.storageManager);return t.entity=this.entity,t}};r(it,"EntityBuilder");var st=it,Ft=class Ft{constructor(){this.scene=new W}named(t){return this.scene.name=t,this}withEntity(t){return this.scene.addEntity(t),this}withEntityBuilder(t){let e=new st(this.scene,this.scene.componentStorageManager),i=t(e).build();return this.scene.addEntity(i),this}withEntities(...t){for(let e of t)this.scene.addEntity(e);return this}withSystem(t){return this.scene.addSystem(t),this}withSystems(...t){for(let e of t)this.scene.addSystem(e);return this}build(){return this.scene}};r(Ft,"SceneBuilder");var qt=Ft,Nt=class Nt{constructor(t,...e){this.component=new t(...e)}set(t,e){return this.component[t]=e,this}configure(t){return t(this.component),this}setIf(t,e,s){return t&&(this.component[e]=s),this}build(){return this.component}};r(Nt,"ComponentBuilder");var $t=Nt,Wt=class Wt{constructor(t,e,s){this.scene=t,this.querySystem=e,this.eventSystem=s}createEntity(){return new st(this.scene,this.scene.componentStorageManager)}createScene(){return new qt}createComponent(t,...e){return new $t(t,...e)}query(){return new et(this.querySystem)}find(...t){return this.querySystem.queryAll(...t).entities}findFirst(...t){let e=this.querySystem.queryAll(...t);return e.entities.length>0?e.entities[0]:null}findByName(t){return this.scene.getEntityByName(t)}findByTag(t){return this.scene.getEntitiesByTag(t)}emit(t,e){this.eventSystem.emitSync(t,e)}async emitAsync(t,e){await this.eventSystem.emit(t,e)}on(t,e){return this.eventSystem.on(t,e)}once(t,e){return this.eventSystem.once(t,e)}off(t,e){this.eventSystem.off(t,e)}batch(t){return new Rt(t)}getStats(){return{entityCount:this.scene.entities.count,systemCount:this.scene.systems.length,componentStats:this.scene.componentStorageManager.getAllStats(),queryStats:this.querySystem.getStats(),eventStats:this.eventSystem.getStats()}}};r(Wt,"ECSFluentAPI");var Pt=Wt,nt=class nt{constructor(t){this.entities=t}addComponent(t){for(let e of this.entities)e.addComponent(t);return this}removeComponent(t){for(let e of this.entities)e.removeComponentByType(t);return this}setActive(t){for(let e of this.entities)e.active=t;return this}setTag(t){for(let e of this.entities)e.tag=t;return this}forEach(t){return this.entities.forEach(t),this}filter(t){return new nt(this.entities.filter(t))}toArray(){return this.entities.slice()}count(){return this.entities.length}};r(nt,"EntityBatchOperator");var Rt=nt;function ne(a,t,e){return new Pt(a,t,e)}r(ne,"createECSAPI");var _=class _{constructor(t=!0,e=!0){this._nextScene=null,this._globalManagers=[],_._instance=this,_.emitter=new U,_.emitter.addObserver(z.frameUpdated,this.update,this),this._timerManager=new $,_.registerGlobalManager(this._timerManager),this._performanceMonitor=B.instance,this._poolManager=Q.getInstance(),_.entitySystemsEnabled=e,this.debug=t,this.initialize()}static get Instance(){return this._instance}static get scene(){return this._instance&&this._instance._scene||null}static set scene(t){if(t){if(!t)throw new Error("\u573A\u666F\u4E0D\u80FD\u4E3A\u7A7A");this._instance._scene==null?(this._instance._scene=t,this._instance.onSceneChanged(),this._instance._scene.begin()):this._instance._nextScene=t}}static create(t=!0){return this._instance==null&&(this._instance=new _(t)),this._instance}static registerGlobalManager(t){this._instance._globalManagers.push(t),t.enabled=!0}static unregisterGlobalManager(t){this._instance._globalManagers.splice(this._instance._globalManagers.indexOf(t),1),t.enabled=!1}static getGlobalManager(t){for(let e of this._instance._globalManagers)if(e instanceof t)return e;return null}static schedule(t,e=!1,s=null,i){return this._instance._timerManager.schedule(t,e,s,i)}static get ecsAPI(){var t;return((t=this._instance)==null?void 0:t._ecsAPI)||null}onSceneChanged(){if(l.sceneChanged(),this._scene&&typeof this._scene.querySystem!="undefined"){let t=this._scene;this._ecsAPI=ne(t,t.querySystem,t.eventSystem)}}initialize(){}update(t=-1){var i;if(_.paused)return;let e=this._performanceMonitor.startMonitoring("Core.update");l.update(t),typeof this._performanceMonitor.updateFPS=="function"&&this._performanceMonitor.updateFPS(l.deltaTime);let s=this._performanceMonitor.startMonitoring("GlobalManagers.update");for(let n of this._globalManagers)n.enabled&&n.update();if(this._performanceMonitor.endMonitoring("GlobalManagers.update",s,this._globalManagers.length),this._poolManager.update(),this._nextScene!=null&&(this._scene!=null&&this._scene.end(),this._scene=this._nextScene,this._nextScene=null,this.onSceneChanged(),this._scene.begin()),this._scene!=null&&this._scene.update){let n=this._performanceMonitor.startMonitoring("Scene.update");this._scene.update();let o=((i=this._scene.entities)==null?void 0:i.count)||0;this._performanceMonitor.endMonitoring("Scene.update",n,o)}this._performanceMonitor.endMonitoring("Core.update",e)}};r(_,"Core");var ot=_;ot.paused=!1;var at=class at{constructor(){this._enabled=!0,this._updateOrder=0,this.id=at._idGenerator++}get enabled(){return this.entity?this.entity.enabled&&this._enabled:this._enabled}set enabled(t){this._enabled!==t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled())}get updateOrder(){return this._updateOrder}set updateOrder(t){this._updateOrder=t}onAddedToEntity(){}onRemovedFromEntity(){}onEnabled(){}onDisabled(){}update(){}};r(at,"Component");var rt=at;rt._idGenerator=0;var x=class x{constructor(){this._words=[],this._words=[]}set(t){let e=Math.floor(t/x.WORD_SIZE),s=t%x.WORD_SIZE;for(;this._words.length<=e;)this._words.push(0);this._words[e]|=1<<s}clear(t){let e=Math.floor(t/x.WORD_SIZE),s=t%x.WORD_SIZE;e<this._words.length&&(this._words[e]&=~(1<<s))}get(t){let e=Math.floor(t/x.WORD_SIZE),s=t%x.WORD_SIZE;return e>=this._words.length?!1:(this._words[e]&1<<s)!==0}containsAll(t){let e=Math.max(this._words.length,t._words.length);for(let s=0;s<e;s++){let i=s<this._words.length?this._words[s]:0,n=s<t._words.length?t._words[s]:0;if((i&n)!==n)return!1}return!0}intersects(t){let e=Math.min(this._words.length,t._words.length);for(let s=0;s<e;s++)if((this._words[s]&t._words[s])!==0)return!0;return!1}excludes(t){return!this.intersects(t)}clearAll(){this._words.length=0}isEmpty(){for(let t of this._words)if(t!==0)return!1;return!0}cardinality(){let t=0;for(let e of this._words)t+=this.popCount(e);return t}popCount(t){return t=t-(t>>>1&1431655765),t=(t&858993459)+(t>>>2&858993459),(t+(t>>>4)&252645135)*16843009>>>24}copyFrom(t){this._words=[...t._words]}clone(){let t=new x;return t.copyFrom(this),t}};r(x,"Bits");var v=x;v.WORD_SIZE=32;var k=class k{static get instance(){return k._instance||(k._instance=new k),k._instance}constructor(){this._componentTypes=new Map,this._typeNames=new Map,this._nextTypeId=0}getTypeId(t){let e=this._componentTypes.get(t);return e===void 0&&(e=this._nextTypeId++,this._componentTypes.set(t,e),this._typeNames.set(e,t.name)),e}getTypeName(t){return this._typeNames.get(t)||"Unknown"}createBits(...t){let e=new v;for(let s of t){let i=this.getTypeId(s);e.set(i)}return e}getEntityBits(t){let e=new v;for(let s of t){let i=this.getTypeId(s.constructor);e.set(i)}return e}reset(){this._componentTypes.clear(),this._typeNames.clear(),this._nextTypeId=0}get registeredTypeCount(){return this._componentTypes.size}};r(k,"ComponentTypeManager");var O=k;var ht=class ht{constructor(){this.allSet=[],this.exclusionSet=[],this.oneSet=[],this._isDirty=!0}static empty(){return new ht}getAllSet(){return this.allSet}getExclusionSet(){return this.exclusionSet}getOneSet(){return this.oneSet}isInterestedEntity(t){let e=this.getEntityBits(t);return this.isInterested(e)}isInterested(t){return this.updateBitsIfDirty(),!(this._allBits&&!t.containsAll(this._allBits)||this._exclusionBits&&t.intersects(this._exclusionBits)||this._oneBits&&!t.intersects(this._oneBits))}all(...t){return this.allSet.push(...t),this._isDirty=!0,this}exclude(...t){return this.exclusionSet.push(...t),this._isDirty=!0,this}one(...t){return this.oneSet.push(...t),this._isDirty=!0,this}getEntityBits(t){let e=t.components;return O.instance.getEntityBits(e)}updateBitsIfDirty(){if(!this._isDirty)return;let t=O.instance;this.allSet.length>0?this._allBits=t.createBits(...this.allSet):this._allBits=void 0,this.exclusionSet.length>0?this._exclusionBits=t.createBits(...this.exclusionSet):this._exclusionBits=void 0,this.oneSet.length>0?this._oneBits=t.createBits(...this.oneSet):this._oneBits=void 0,this._isDirty=!1}toString(){let t=[];return this.allSet.length>0&&t.push(`all: [${this.allSet.map(e=>e.name).join(", ")}]`),this.exclusionSet.length>0&&t.push(`exclude: [${this.exclusionSet.map(e=>e.name).join(", ")}]`),this.oneSet.length>0&&t.push(`one: [${this.oneSet.map(e=>e.name).join(", ")}]`),`Matcher(${t.join(", ")})`}};r(ht,"Matcher");var j=ht;var jt=class jt{get entities(){return this._entities}get updateOrder(){return this._updateOrder}set updateOrder(t){this.setUpdateOrder(t)}get enabled(){return this._enabled}set enabled(t){this._enabled=t}get systemName(){return this._systemName}constructor(t){this._entities=[],this._updateOrder=0,this._enabled=!0,this._performanceMonitor=B.instance,this._matcher=t||j.empty(),this._systemName=this.constructor.name,this.initialize()}get scene(){return this._scene}set scene(t){this._scene=t,this._entities=[]}get matcher(){return this._matcher}setUpdateOrder(t){this._updateOrder=t,this.scene.entityProcessors.setDirty()}initialize(){}onChanged(t){let e=this._entities.includes(t),s=this._matcher.isInterestedEntity(t);s&&!e?this.add(t):!s&&e&&this.remove(t)}add(t){this._entities.includes(t)||(this._entities.push(t),this.onAdded(t))}onAdded(t){}remove(t){let e=this._entities.indexOf(t);e!==-1&&(this._entities.splice(e,1),this.onRemoved(t))}onRemoved(t){}update(){if(!this._enabled||!this.checkProcessing())return;let t=this._performanceMonitor.startMonitoring(this._systemName);try{this.begin(),this.process(this._entities)}finally{this._performanceMonitor.endMonitoring(this._systemName,t,this._entities.length)}}lateUpdate(){if(!this._enabled||!this.checkProcessing())return;let t=this._performanceMonitor.startMonitoring(`${this._systemName}_Late`);try{this.lateProcess(this._entities),this.end()}finally{this._performanceMonitor.endMonitoring(`${this._systemName}_Late`,t,this._entities.length)}}begin(){}process(t){}lateProcess(t){}end(){}checkProcessing(){return!0}getPerformanceData(){return this._performanceMonitor.getSystemData(this._systemName)}getPerformanceStats(){return this._performanceMonitor.getSystemStats(this._systemName)}resetPerformanceData(){this._performanceMonitor.resetSystem(this._systemName)}toString(){let t=this._entities.length,e=this.getPerformanceData(),s=e?` (${e.executionTime.toFixed(2)}ms)`:"";return`${this._systemName}[${t} entities]${s}`}};r(jt,"EntitySystem");var C=jt;var Lt=class Lt extends C{onChanged(t){}process(t){this.processSystem()}};r(Lt,"ProcessingSystem");var Ht=Lt;var Gt=class Gt extends C{onChanged(t){}process(t){}};r(Gt,"PassiveSystem");var Qt=Gt;var Yt=class Yt extends C{constructor(t,e){super(t),this.acc=0,this.intervalRemainder=0,this.interval=e}checkProcessing(){return this.acc+=l.deltaTime,this.acc>=this.interval?(this.intervalRemainder=this.acc-this.interval,this.acc=0,!0):!1}getIntervalDelta(){return this.interval+this.intervalRemainder}};r(Yt,"IntervalSystem");var Jt=Yt;var Zt=class Zt{static getType(t){return t.constructor}};r(Zt,"TypeUtils");var Kt=Zt;var Xt=class Xt{static toNumber(t){return t==null?0:Number(t)}};r(Xt,"NumberExtension");var Vt=Xt;var oe;(function(a){a[a.Error=0]="Error",a[a.Assert=1]="Assert",a[a.Warning=2]="Warning",a[a.Log=3]="Log",a[a.Exception=4]="Exception"})(oe||(oe={}));var re;(function(a){a[a.Position=1]="Position",a[a.Scale=2]="Scale",a[a.Rotation=4]="Rotation"})(re||(re={}));export{v as Bits,rt as Component,re as ComponentTransform,O as ComponentTypeManager,ot as Core,z as CoreEvents,U as Emitter,y as Entity,P as EntityList,R as EntityProcessorList,C as EntitySystem,H as FuncPack,D as GlobalManager,F as IdentifierPool,Jt as IntervalSystem,oe as LogType,j as Matcher,Vt as NumberExtension,Qt as PassiveSystem,B as PerformanceMonitor,ie as PerformanceWarningType,E as Pool,Q as PoolManager,Ht as ProcessingSystem,me as Query,W as Scene,L as TieredObjectPool,l as Time,q as Timer,$ as TimerManager,Kt as TypeUtils,K as WasmEcsCore,d as ecsCore,ue as initializeEcs};
|
|
7
|
+
//# sourceMappingURL=index.js.map
|