@codehz/ecs 0.3.14 → 0.4.0
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 +65 -44
- package/index.d.mts +2 -783
- package/index.mjs +2 -2137
- package/package.json +6 -2
- package/testing.d.mts +305 -0
- package/testing.mjs +429 -0
- package/testing.mjs.map +1 -0
- package/world.d.mts +766 -0
- package/world.mjs +2081 -0
- package/world.mjs.map +1 -0
- package/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
- 🚀 高性能:基于 Archetype 的组件存储和高效的查询系统
|
|
8
8
|
- 🔧 类型安全:完整的 TypeScript 支持
|
|
9
|
-
- 🏗️
|
|
9
|
+
- 🏗️ 模块化:清晰的架构,支持自定义组件
|
|
10
10
|
- 📦 轻量级:零依赖,易于集成
|
|
11
11
|
- ⚡ 内存高效:连续内存布局,优化的迭代性能
|
|
12
12
|
- 🎣 生命周期钩子:支持组件和通配符关系的事件监听
|
|
13
|
-
- 🔄 系统调度:支持系统依赖关系和拓扑排序执行
|
|
14
13
|
|
|
15
14
|
## 安装
|
|
16
15
|
|
|
@@ -180,11 +179,9 @@ bun run examples/simple/demo.ts
|
|
|
180
179
|
- `delete(entity, componentId)`: 从实体移除组件
|
|
181
180
|
- `setExclusive(componentId)`: 将组件标记为独占关系
|
|
182
181
|
- `createQuery(componentIds)`: 创建查询
|
|
183
|
-
- `registerSystem(system, dependencies?)`: 注册系统
|
|
184
182
|
- `hook(componentId, hook)`: 注册组件或通配符关系生命周期钩子
|
|
185
183
|
- `unhook(componentId, hook)`: 注销组件或通配符关系生命周期钩子
|
|
186
|
-
- `
|
|
187
|
-
- `sync()`: 应用命令缓冲区
|
|
184
|
+
- `sync()`: 执行所有延迟命令
|
|
188
185
|
|
|
189
186
|
### 序列化(快照)
|
|
190
187
|
|
|
@@ -258,7 +255,7 @@ const restored = World.deserialize(readySnapshot);
|
|
|
258
255
|
注意事项
|
|
259
256
|
|
|
260
257
|
- **重要警告**:`get()` 方法只能获取实体已设置的组件。如果尝试获取不存在的组件,会抛出错误。由于 `undefined` 是组件的有效值,不能使用 `get()` 的返回值是否为 `undefined` 来判断组件是否存在。请在使用 `get()` 之前先用 `has()` 方法检查组件是否存在。
|
|
261
|
-
- 快照只包含实体、组件、以及 `EntityIdManager` 的分配器状态(用于保留下一次分配的 ID
|
|
258
|
+
- 快照只包含实体、组件、以及 `EntityIdManager` 的分配器状态(用于保留下一次分配的 ID);并不会自动恢复查询缓存或生命周期钩子。恢复后应由应用负责重新注册钩子。
|
|
262
259
|
- 若需要跨版本兼容,建议在持久化格式中包含 `version` 字段,并在恢复时进行格式兼容性检查与迁移。
|
|
263
260
|
|
|
264
261
|
### Entity
|
|
@@ -271,57 +268,81 @@ const restored = World.deserialize(readySnapshot);
|
|
|
271
268
|
- `getEntities()`: 获取所有匹配实体的ID列表
|
|
272
269
|
- `getEntitiesWithComponents(componentIds)`: 获取实体及其组件数据
|
|
273
270
|
|
|
274
|
-
|
|
271
|
+
## 从 System 迁移到 Pipeline
|
|
275
272
|
|
|
276
|
-
|
|
273
|
+
从 v0.4.0 开始,本库移除了内置的 `System` 和 `SystemScheduler` 功能。推荐使用 `@codehz/pipeline` 作为替代方案来组织游戏循环逻辑。
|
|
277
274
|
|
|
278
|
-
|
|
279
|
-
class MySystem implements System {
|
|
280
|
-
update(): void {
|
|
281
|
-
// 系统逻辑
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
```
|
|
275
|
+
### 为什么移除 System?
|
|
285
276
|
|
|
286
|
-
|
|
277
|
+
- **简化库的维护**:System 调度器增加了代码复杂度,但其功能可以通过更通用的 pipeline 模式实现
|
|
278
|
+
- **更灵活的执行控制**:Pipeline 模式允许更细粒度的控制,支持异步操作和条件执行
|
|
279
|
+
- **更好的关注点分离**:ECS 库专注于实体和组件管理,系统调度由外部库处理
|
|
287
280
|
|
|
288
|
-
|
|
289
|
-
class MovementSystem implements System<[deltaTime: number]> {
|
|
290
|
-
update(deltaTime: number): void {
|
|
291
|
-
// 使用 deltaTime 更新位置
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
```
|
|
281
|
+
### 迁移示例
|
|
295
282
|
|
|
296
|
-
|
|
283
|
+
**旧代码(使用 System)**:
|
|
297
284
|
|
|
298
285
|
```typescript
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
update(deltaTime: number): void {
|
|
302
|
-
// 处理输入
|
|
303
|
-
}
|
|
304
|
-
}
|
|
286
|
+
import { World, component } from "@codehz/ecs";
|
|
287
|
+
import type { System } from "@codehz/ecs";
|
|
305
288
|
|
|
306
289
|
class MovementSystem implements System<[deltaTime: number]> {
|
|
307
|
-
|
|
290
|
+
private query: Query;
|
|
308
291
|
|
|
309
|
-
constructor(
|
|
310
|
-
this.
|
|
292
|
+
constructor(world: World<[deltaTime: number]>) {
|
|
293
|
+
this.query = world.createQuery([PositionId, VelocityId]);
|
|
311
294
|
}
|
|
312
295
|
|
|
313
296
|
update(deltaTime: number): void {
|
|
314
|
-
|
|
297
|
+
this.query.forEach([PositionId, VelocityId], (entity, position, velocity) => {
|
|
298
|
+
position.x += velocity.x * deltaTime;
|
|
299
|
+
position.y += velocity.y * deltaTime;
|
|
300
|
+
});
|
|
315
301
|
}
|
|
316
302
|
}
|
|
317
303
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
world.
|
|
321
|
-
|
|
304
|
+
const world = new World<[deltaTime: number]>();
|
|
305
|
+
world.registerSystem(new MovementSystem(world));
|
|
306
|
+
world.update(0.016); // 自动调用 sync()
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**新代码(使用 Pipeline)**:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { pipeline } from "@codehz/pipeline";
|
|
313
|
+
import { World, component } from "@codehz/ecs";
|
|
314
|
+
|
|
315
|
+
const world = new World();
|
|
316
|
+
const movementQuery = world.createQuery([PositionId, VelocityId]);
|
|
317
|
+
|
|
318
|
+
const gameLoop = pipeline<{ deltaTime: number }>()
|
|
319
|
+
.addPass((env) => {
|
|
320
|
+
movementQuery.forEach([PositionId, VelocityId], (entity, position, velocity) => {
|
|
321
|
+
position.x += velocity.x * env.deltaTime;
|
|
322
|
+
position.y += velocity.y * env.deltaTime;
|
|
323
|
+
});
|
|
324
|
+
})
|
|
325
|
+
// 重要:world.sync() 必须作为最后一个 pass 调用,以还原之前 world.update() 的自动提交行为
|
|
326
|
+
.addPass(() => {
|
|
327
|
+
world.sync();
|
|
328
|
+
})
|
|
329
|
+
.build();
|
|
330
|
+
|
|
331
|
+
gameLoop({ deltaTime: 0.016 });
|
|
322
332
|
```
|
|
323
333
|
|
|
324
|
-
|
|
334
|
+
### 关键变化
|
|
335
|
+
|
|
336
|
+
1. **移除泛型参数**:`World` 不再需要 `UpdateParams` 泛型参数
|
|
337
|
+
2. **移除的方法**:`registerSystem()` 和 `update()` 方法已移除
|
|
338
|
+
3. **手动调用 sync()**:之前 `world.update()` 会自动调用 `sync()`,现在需要在 pipeline 末尾显式调用
|
|
339
|
+
4. **执行顺序**:Pass 的执行顺序由添加顺序决定,无需手动声明依赖关系
|
|
340
|
+
|
|
341
|
+
### 安装 Pipeline
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
bun add @codehz/pipeline
|
|
345
|
+
```
|
|
325
346
|
|
|
326
347
|
## 性能特点
|
|
327
348
|
|
|
@@ -354,8 +375,6 @@ src/
|
|
|
354
375
|
├── archetype.ts # Archetype 系统(高效组件存储)
|
|
355
376
|
├── query.ts # 查询系统
|
|
356
377
|
├── query-filter.ts # 查询过滤器
|
|
357
|
-
├── system.ts # 系统接口
|
|
358
|
-
├── system-scheduler.ts # 系统调度器
|
|
359
378
|
├── command-buffer.ts # 命令缓冲区
|
|
360
379
|
├── types.ts # 类型定义
|
|
361
380
|
├── utils.ts # 工具函数
|
|
@@ -364,9 +383,11 @@ src/
|
|
|
364
383
|
└── *.perf.test.ts # 性能测试
|
|
365
384
|
|
|
366
385
|
examples/
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
386
|
+
├── simple/
|
|
387
|
+
│ ├── demo.ts # 基本示例
|
|
388
|
+
│ └── README.md # 示例说明
|
|
389
|
+
└── advanced-scheduling/
|
|
390
|
+
└── demo.ts # Pipeline 调度示例
|
|
370
391
|
|
|
371
392
|
scripts/
|
|
372
393
|
├── build.ts # 构建脚本
|