@codehz/ecs 0.0.9 → 0.1.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 +59 -30
- package/archetype.d.ts +4 -4
- package/changeset.d.ts +2 -2
- package/command-buffer.d.ts +5 -5
- package/index.js +36 -36
- package/package.json +1 -1
- package/system-scheduler.d.ts +3 -3
- package/system.d.ts +3 -4
- package/world.d.ts +13 -13
package/README.md
CHANGED
|
@@ -38,12 +38,12 @@ const VelocityId = component<Velocity>(2);
|
|
|
38
38
|
const world = new World();
|
|
39
39
|
|
|
40
40
|
// 创建实体
|
|
41
|
-
const entity = world.
|
|
42
|
-
world.
|
|
43
|
-
world.
|
|
41
|
+
const entity = world.new();
|
|
42
|
+
world.set(entity, PositionId, { x: 0, y: 0 });
|
|
43
|
+
world.set(entity, VelocityId, { x: 1, y: 0.5 });
|
|
44
44
|
|
|
45
45
|
// 应用更改
|
|
46
|
-
world.
|
|
46
|
+
world.sync();
|
|
47
47
|
|
|
48
48
|
// 创建查询并更新
|
|
49
49
|
const query = world.createQuery([PositionId, VelocityId]);
|
|
@@ -77,8 +77,8 @@ world.registerLifecycleHook(VelocityId, {
|
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
// 添加组件时会触发钩子
|
|
80
|
-
world.
|
|
81
|
-
world.
|
|
80
|
+
world.set(entity, PositionId, { x: 0, y: 0 });
|
|
81
|
+
world.sync(); // 钩子在这里被调用
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
### 通配符关系生命周期钩子
|
|
@@ -98,7 +98,7 @@ const PositionId = component<Position>(1);
|
|
|
98
98
|
const world = new World();
|
|
99
99
|
|
|
100
100
|
// 创建实体
|
|
101
|
-
const entity = world.
|
|
101
|
+
const entity = world.new();
|
|
102
102
|
|
|
103
103
|
// 创建通配符关系ID,用于监听所有 Position 相关的关系
|
|
104
104
|
const wildcardPositionRelation = relation(PositionId, "*");
|
|
@@ -114,10 +114,10 @@ world.registerLifecycleHook(wildcardPositionRelation, {
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
// 创建实体间的关系
|
|
117
|
-
const entity2 = world.
|
|
117
|
+
const entity2 = world.new();
|
|
118
118
|
const positionRelation = relation(PositionId, entity2);
|
|
119
|
-
world.
|
|
120
|
-
world.
|
|
119
|
+
world.set(entity, positionRelation, { x: 10, y: 20 });
|
|
120
|
+
world.sync(); // 通配符钩子会被触发
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
### Exclusive Relations
|
|
@@ -137,20 +137,20 @@ const world = new World();
|
|
|
137
137
|
world.setExclusive(ChildOf);
|
|
138
138
|
|
|
139
139
|
// 创建实体
|
|
140
|
-
const child = world.
|
|
141
|
-
const parent1 = world.
|
|
142
|
-
const parent2 = world.
|
|
140
|
+
const child = world.new();
|
|
141
|
+
const parent1 = world.new();
|
|
142
|
+
const parent2 = world.new();
|
|
143
143
|
|
|
144
144
|
// 添加第一个关系
|
|
145
|
-
world.
|
|
146
|
-
world.
|
|
147
|
-
console.log(world.
|
|
145
|
+
world.set(child, relation(ChildOf, parent1));
|
|
146
|
+
world.sync();
|
|
147
|
+
console.log(world.has(child, relation(ChildOf, parent1))); // true
|
|
148
148
|
|
|
149
149
|
// 添加第二个关系 - 会自动移除第一个
|
|
150
|
-
world.
|
|
151
|
-
world.
|
|
152
|
-
console.log(world.
|
|
153
|
-
console.log(world.
|
|
150
|
+
world.set(child, relation(ChildOf, parent2));
|
|
151
|
+
world.sync();
|
|
152
|
+
console.log(world.has(child, relation(ChildOf, parent1))); // false
|
|
153
|
+
console.log(world.has(child, relation(ChildOf, parent2))); // true
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
### 运行示例
|
|
@@ -169,16 +169,16 @@ bun run examples/simple/demo.ts
|
|
|
169
169
|
|
|
170
170
|
### World
|
|
171
171
|
|
|
172
|
-
- `
|
|
173
|
-
- `
|
|
174
|
-
- `
|
|
172
|
+
- `new()`: 创建新实体
|
|
173
|
+
- `set(entity, componentId, data)`: 向实体添加组件
|
|
174
|
+
- `delete(entity, componentId)`: 从实体移除组件
|
|
175
175
|
- `setExclusive(componentId)`: 将组件标记为独占关系
|
|
176
176
|
- `createQuery(componentIds)`: 创建查询
|
|
177
177
|
- `registerSystem(system)`: 注册系统
|
|
178
178
|
- `registerLifecycleHook(componentId, hook)`: 注册组件或通配符关系生命周期钩子
|
|
179
179
|
- `unregisterLifecycleHook(componentId, hook)`: 注销组件或通配符关系生命周期钩子
|
|
180
|
-
- `update(
|
|
181
|
-
- `
|
|
180
|
+
- `update(...params)`: 更新世界(参数取决于泛型配置)
|
|
181
|
+
- `sync()`: 应用命令缓冲区
|
|
182
182
|
|
|
183
183
|
### Entity
|
|
184
184
|
|
|
@@ -196,19 +196,48 @@ bun run examples/simple/demo.ts
|
|
|
196
196
|
|
|
197
197
|
```typescript
|
|
198
198
|
class MySystem implements System {
|
|
199
|
-
update(
|
|
199
|
+
update(): void {
|
|
200
200
|
// 系统逻辑
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
-
|
|
205
|
+
如果需要接收额外参数(如时间增量),可以指定泛型参数:
|
|
206
206
|
|
|
207
207
|
```typescript
|
|
208
|
-
|
|
208
|
+
class MovementSystem implements System<[deltaTime: number]> {
|
|
209
|
+
update(deltaTime: number): void {
|
|
210
|
+
// 使用 deltaTime 更新位置
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
系统支持依赖关系排序,确保正确的执行顺序。依赖关系通过系统的 `dependencies` 属性指定:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
class InputSystem implements System<[deltaTime: number]> {
|
|
219
|
+
readonly dependencies: readonly System<[deltaTime: number]>[] = [];
|
|
220
|
+
update(deltaTime: number): void {
|
|
221
|
+
// 处理输入
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
class MovementSystem implements System<[deltaTime: number]> {
|
|
226
|
+
readonly dependencies: readonly System<[deltaTime: number]>[];
|
|
227
|
+
|
|
228
|
+
constructor(inputSystem: InputSystem) {
|
|
229
|
+
this.dependencies = [inputSystem]; // 指定依赖
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
update(deltaTime: number): void {
|
|
233
|
+
// 更新位置
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 注册系统
|
|
238
|
+
const inputSystem = new InputSystem();
|
|
209
239
|
world.registerSystem(inputSystem);
|
|
210
|
-
world.registerSystem(
|
|
211
|
-
world.registerSystem(renderSystem, [movementSystem]); // renderSystem 依赖 movementSystem
|
|
240
|
+
world.registerSystem(new MovementSystem(inputSystem));
|
|
212
241
|
```
|
|
213
242
|
|
|
214
243
|
系统将按照拓扑排序执行,依赖系统始终在被依赖系统之前运行。
|
package/archetype.d.ts
CHANGED
|
@@ -59,27 +59,27 @@ export declare class Archetype {
|
|
|
59
59
|
* Check if an entity is in this archetype
|
|
60
60
|
* @param entityId The entity to check
|
|
61
61
|
*/
|
|
62
|
-
|
|
62
|
+
exists(entityId: EntityId): boolean;
|
|
63
63
|
/**
|
|
64
64
|
* Get component data for a specific entity and wildcard relation type
|
|
65
65
|
* Returns an array of all matching relation instances
|
|
66
66
|
* @param entityId The entity
|
|
67
67
|
* @param componentType The wildcard relation type
|
|
68
68
|
*/
|
|
69
|
-
|
|
69
|
+
get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, any][];
|
|
70
70
|
/**
|
|
71
71
|
* Get component data for a specific entity and component type
|
|
72
72
|
* @param entityId The entity
|
|
73
73
|
* @param componentType The component type
|
|
74
74
|
*/
|
|
75
|
-
|
|
75
|
+
get<T>(entityId: EntityId, componentType: EntityId<T>): T;
|
|
76
76
|
/**
|
|
77
77
|
* Set component data for a specific entity and component type
|
|
78
78
|
* @param entityId The entity
|
|
79
79
|
* @param componentType The component type
|
|
80
80
|
* @param data The component data
|
|
81
81
|
*/
|
|
82
|
-
|
|
82
|
+
set<T>(entityId: EntityId, componentType: EntityId<T>, data: T): void;
|
|
83
83
|
/**
|
|
84
84
|
* Get all entities in this archetype
|
|
85
85
|
*/
|
package/changeset.d.ts
CHANGED
|
@@ -8,11 +8,11 @@ export declare class ComponentChangeset {
|
|
|
8
8
|
/**
|
|
9
9
|
* Add a component to the changeset
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
set<T>(componentType: EntityId<T>, component: T): void;
|
|
12
12
|
/**
|
|
13
13
|
* Remove a component from the changeset
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
delete<T>(componentType: EntityId<T>): void;
|
|
16
16
|
/**
|
|
17
17
|
* Check if the changeset has any changes
|
|
18
18
|
*/
|
package/command-buffer.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { EntityId } from "./entity";
|
|
|
3
3
|
* Command for deferred execution
|
|
4
4
|
*/
|
|
5
5
|
export interface Command {
|
|
6
|
-
type: "
|
|
6
|
+
type: "set" | "delete" | "destroy";
|
|
7
7
|
entityId: EntityId;
|
|
8
8
|
componentType?: EntityId<any>;
|
|
9
9
|
component?: any;
|
|
@@ -21,16 +21,16 @@ export declare class CommandBuffer {
|
|
|
21
21
|
/**
|
|
22
22
|
* Add a component to an entity (deferred)
|
|
23
23
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
set(entityId: EntityId, componentType: EntityId<void>): void;
|
|
25
|
+
set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
|
|
26
26
|
/**
|
|
27
27
|
* Remove a component from an entity (deferred)
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
delete<T>(entityId: EntityId, componentType: EntityId<T>): void;
|
|
30
30
|
/**
|
|
31
31
|
* Destroy an entity (deferred)
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
destroy(entityId: EntityId): void;
|
|
34
34
|
/**
|
|
35
35
|
* Execute all commands and clear the buffer
|
|
36
36
|
*/
|
package/index.js
CHANGED
|
@@ -280,10 +280,10 @@ class Archetype {
|
|
|
280
280
|
}
|
|
281
281
|
return removedData;
|
|
282
282
|
}
|
|
283
|
-
|
|
283
|
+
exists(entityId) {
|
|
284
284
|
return this.entityToIndex.has(entityId);
|
|
285
285
|
}
|
|
286
|
-
|
|
286
|
+
get(entityId, componentType) {
|
|
287
287
|
const index = this.entityToIndex.get(entityId);
|
|
288
288
|
if (index === undefined) {
|
|
289
289
|
throw new Error(`Entity ${entityId} is not in this archetype`);
|
|
@@ -308,7 +308,7 @@ class Archetype {
|
|
|
308
308
|
return data === MISSING_COMPONENT ? undefined : data;
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
|
-
|
|
311
|
+
set(entityId, componentType, data) {
|
|
312
312
|
if (!this.componentData.has(componentType)) {
|
|
313
313
|
throw new Error(`Component type ${componentType} is not in this archetype`);
|
|
314
314
|
}
|
|
@@ -392,11 +392,11 @@ class Archetype {
|
|
|
392
392
|
class ComponentChangeset {
|
|
393
393
|
adds = new Map;
|
|
394
394
|
removes = new Set;
|
|
395
|
-
|
|
395
|
+
set(componentType, component2) {
|
|
396
396
|
this.adds.set(componentType, component2);
|
|
397
397
|
this.removes.delete(componentType);
|
|
398
398
|
}
|
|
399
|
-
|
|
399
|
+
delete(componentType) {
|
|
400
400
|
this.removes.add(componentType);
|
|
401
401
|
this.adds.delete(componentType);
|
|
402
402
|
}
|
|
@@ -440,14 +440,14 @@ class CommandBuffer {
|
|
|
440
440
|
constructor(executeEntityCommands) {
|
|
441
441
|
this.executeEntityCommands = executeEntityCommands;
|
|
442
442
|
}
|
|
443
|
-
|
|
444
|
-
this.commands.push({ type: "
|
|
443
|
+
set(entityId, componentType, component2) {
|
|
444
|
+
this.commands.push({ type: "set", entityId, componentType, component: component2 });
|
|
445
445
|
}
|
|
446
|
-
|
|
447
|
-
this.commands.push({ type: "
|
|
446
|
+
delete(entityId, componentType) {
|
|
447
|
+
this.commands.push({ type: "delete", entityId, componentType });
|
|
448
448
|
}
|
|
449
|
-
|
|
450
|
-
this.commands.push({ type: "
|
|
449
|
+
destroy(entityId) {
|
|
450
|
+
this.commands.push({ type: "destroy", entityId });
|
|
451
451
|
}
|
|
452
452
|
execute() {
|
|
453
453
|
const MAX_ITERATIONS = 100;
|
|
@@ -664,7 +664,7 @@ class World {
|
|
|
664
664
|
getComponentTypesHash(componentTypes) {
|
|
665
665
|
return componentTypes.join(",");
|
|
666
666
|
}
|
|
667
|
-
|
|
667
|
+
new() {
|
|
668
668
|
const entityId = this.entityIdManager.allocate();
|
|
669
669
|
let emptyArchetype = this.getOrCreateArchetype([]);
|
|
670
670
|
emptyArchetype.addEntity(entityId, new Map);
|
|
@@ -683,7 +683,7 @@ class World {
|
|
|
683
683
|
const currentComponents = new Map;
|
|
684
684
|
for (const compType of sourceArchetype.componentTypes) {
|
|
685
685
|
if (compType !== componentType) {
|
|
686
|
-
const data = sourceArchetype.
|
|
686
|
+
const data = sourceArchetype.get(sourceEntityId, compType);
|
|
687
687
|
if (data !== undefined) {
|
|
688
688
|
currentComponents.set(compType, data);
|
|
689
689
|
}
|
|
@@ -709,11 +709,11 @@ class World {
|
|
|
709
709
|
this.entityToArchetype.delete(entityId);
|
|
710
710
|
this.entityIdManager.deallocate(entityId);
|
|
711
711
|
}
|
|
712
|
-
|
|
712
|
+
exists(entityId) {
|
|
713
713
|
return this.entityToArchetype.has(entityId);
|
|
714
714
|
}
|
|
715
|
-
|
|
716
|
-
if (!this.
|
|
715
|
+
set(entityId, componentType, component2) {
|
|
716
|
+
if (!this.exists(entityId)) {
|
|
717
717
|
throw new Error(`Entity ${entityId} does not exist`);
|
|
718
718
|
}
|
|
719
719
|
const detailedType = getDetailedIdType(componentType);
|
|
@@ -723,31 +723,31 @@ class World {
|
|
|
723
723
|
if (detailedType.type === "wildcard-relation") {
|
|
724
724
|
throw new Error(`Cannot directly add wildcard relation components: ${componentType}`);
|
|
725
725
|
}
|
|
726
|
-
this.commandBuffer.
|
|
726
|
+
this.commandBuffer.set(entityId, componentType, component2);
|
|
727
727
|
}
|
|
728
|
-
|
|
729
|
-
if (!this.
|
|
728
|
+
delete(entityId, componentType) {
|
|
729
|
+
if (!this.exists(entityId)) {
|
|
730
730
|
throw new Error(`Entity ${entityId} does not exist`);
|
|
731
731
|
}
|
|
732
732
|
const detailedType = getDetailedIdType(componentType);
|
|
733
733
|
if (detailedType.type === "invalid") {
|
|
734
734
|
throw new Error(`Invalid component type: ${componentType}`);
|
|
735
735
|
}
|
|
736
|
-
this.commandBuffer.
|
|
736
|
+
this.commandBuffer.delete(entityId, componentType);
|
|
737
737
|
}
|
|
738
|
-
|
|
739
|
-
this.commandBuffer.
|
|
738
|
+
destroy(entityId) {
|
|
739
|
+
this.commandBuffer.destroy(entityId);
|
|
740
740
|
}
|
|
741
|
-
|
|
741
|
+
has(entityId, componentType) {
|
|
742
742
|
const archetype = this.entityToArchetype.get(entityId);
|
|
743
743
|
return archetype ? archetype.componentTypes.includes(componentType) : false;
|
|
744
744
|
}
|
|
745
|
-
|
|
745
|
+
get(entityId, componentType) {
|
|
746
746
|
const archetype = this.entityToArchetype.get(entityId);
|
|
747
747
|
if (!archetype) {
|
|
748
748
|
throw new Error(`Entity ${entityId} does not exist`);
|
|
749
749
|
}
|
|
750
|
-
return archetype.
|
|
750
|
+
return archetype.get(entityId, componentType);
|
|
751
751
|
}
|
|
752
752
|
registerSystem(system) {
|
|
753
753
|
this.systemScheduler.addSystem(system);
|
|
@@ -773,11 +773,11 @@ class World {
|
|
|
773
773
|
update(...params) {
|
|
774
774
|
const systems = this.systemScheduler.getExecutionOrder();
|
|
775
775
|
for (const system of systems) {
|
|
776
|
-
system.update(
|
|
776
|
+
system.update(...params);
|
|
777
777
|
}
|
|
778
778
|
this.commandBuffer.execute();
|
|
779
779
|
}
|
|
780
|
-
|
|
780
|
+
sync() {
|
|
781
781
|
this.commandBuffer.execute();
|
|
782
782
|
}
|
|
783
783
|
createQuery(componentTypes, filter = {}) {
|
|
@@ -895,7 +895,7 @@ class World {
|
|
|
895
895
|
}
|
|
896
896
|
executeEntityCommands(entityId, commands) {
|
|
897
897
|
const changeset = new ComponentChangeset;
|
|
898
|
-
const hasDestroy = commands.some((cmd) => cmd.type === "
|
|
898
|
+
const hasDestroy = commands.some((cmd) => cmd.type === "destroy");
|
|
899
899
|
if (hasDestroy) {
|
|
900
900
|
this._destroyEntity(entityId);
|
|
901
901
|
return changeset;
|
|
@@ -906,26 +906,26 @@ class World {
|
|
|
906
906
|
}
|
|
907
907
|
const currentComponents = new Map;
|
|
908
908
|
for (const componentType of currentArchetype.componentTypes) {
|
|
909
|
-
const data = currentArchetype.
|
|
909
|
+
const data = currentArchetype.get(entityId, componentType);
|
|
910
910
|
currentComponents.set(componentType, data);
|
|
911
911
|
}
|
|
912
912
|
for (const cmd of commands) {
|
|
913
913
|
switch (cmd.type) {
|
|
914
|
-
case "
|
|
914
|
+
case "set":
|
|
915
915
|
if (cmd.componentType) {
|
|
916
916
|
const detailedType = getDetailedIdType(cmd.componentType);
|
|
917
917
|
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && this.exclusiveComponents.has(detailedType.componentId)) {
|
|
918
918
|
for (const componentType of currentArchetype.componentTypes) {
|
|
919
919
|
const componentDetailedType = getDetailedIdType(componentType);
|
|
920
920
|
if ((componentDetailedType.type === "entity-relation" || componentDetailedType.type === "component-relation") && componentDetailedType.componentId === detailedType.componentId) {
|
|
921
|
-
changeset.
|
|
921
|
+
changeset.delete(componentType);
|
|
922
922
|
}
|
|
923
923
|
}
|
|
924
924
|
}
|
|
925
|
-
changeset.
|
|
925
|
+
changeset.set(cmd.componentType, cmd.component);
|
|
926
926
|
}
|
|
927
927
|
break;
|
|
928
|
-
case "
|
|
928
|
+
case "delete":
|
|
929
929
|
if (cmd.componentType) {
|
|
930
930
|
const detailedType = getDetailedIdType(cmd.componentType);
|
|
931
931
|
if (detailedType.type === "wildcard-relation") {
|
|
@@ -934,12 +934,12 @@ class World {
|
|
|
934
934
|
const componentDetailedType = getDetailedIdType(componentType);
|
|
935
935
|
if (componentDetailedType.type === "entity-relation" || componentDetailedType.type === "component-relation") {
|
|
936
936
|
if (componentDetailedType.componentId === baseComponentId) {
|
|
937
|
-
changeset.
|
|
937
|
+
changeset.delete(componentType);
|
|
938
938
|
}
|
|
939
939
|
}
|
|
940
940
|
}
|
|
941
941
|
} else {
|
|
942
|
-
changeset.
|
|
942
|
+
changeset.delete(cmd.componentType);
|
|
943
943
|
}
|
|
944
944
|
}
|
|
945
945
|
break;
|
|
@@ -956,7 +956,7 @@ class World {
|
|
|
956
956
|
this.entityToArchetype.set(entityId, newArchetype);
|
|
957
957
|
} else {
|
|
958
958
|
for (const [componentType, component2] of changeset.adds) {
|
|
959
|
-
currentArchetype.
|
|
959
|
+
currentArchetype.set(entityId, componentType, component2);
|
|
960
960
|
}
|
|
961
961
|
}
|
|
962
962
|
for (const componentType of changeset.removes) {
|
package/package.json
CHANGED
package/system-scheduler.d.ts
CHANGED
|
@@ -2,19 +2,19 @@ import type { System } from "./system";
|
|
|
2
2
|
/**
|
|
3
3
|
* System Scheduler for managing system dependencies and execution order
|
|
4
4
|
*/
|
|
5
|
-
export declare class SystemScheduler<
|
|
5
|
+
export declare class SystemScheduler<UpdateParams extends any[] = [deltaTime: number]> {
|
|
6
6
|
private systems;
|
|
7
7
|
private cachedExecutionOrder;
|
|
8
8
|
/**
|
|
9
9
|
* Add a system with optional dependencies
|
|
10
10
|
* @param system The system to add
|
|
11
11
|
*/
|
|
12
|
-
addSystem(system: System<
|
|
12
|
+
addSystem(system: System<UpdateParams>): void;
|
|
13
13
|
/**
|
|
14
14
|
* Get the execution order of systems based on dependencies
|
|
15
15
|
* Uses topological sort
|
|
16
16
|
*/
|
|
17
|
-
getExecutionOrder(): System<
|
|
17
|
+
getExecutionOrder(): System<UpdateParams>[];
|
|
18
18
|
/**
|
|
19
19
|
* Clear all systems and dependencies
|
|
20
20
|
*/
|
package/system.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { World } from "./world";
|
|
2
1
|
/**
|
|
3
2
|
* Base System interface
|
|
4
3
|
*/
|
|
5
|
-
export interface System<
|
|
4
|
+
export interface System<UpdateParams extends any[] = []> {
|
|
6
5
|
/**
|
|
7
6
|
* Update the system
|
|
8
7
|
*/
|
|
9
|
-
update(
|
|
8
|
+
update(...params: UpdateParams): void;
|
|
10
9
|
/**
|
|
11
10
|
* Dependencies of this system (systems that must run before this one)
|
|
12
11
|
*/
|
|
13
|
-
readonly dependencies?: readonly System<
|
|
12
|
+
readonly dependencies?: readonly System<UpdateParams>[];
|
|
14
13
|
}
|
package/world.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import type { ComponentTuple, LifecycleHook } from "./types";
|
|
|
10
10
|
* World class for ECS architecture
|
|
11
11
|
* Manages entities, components, and systems
|
|
12
12
|
*/
|
|
13
|
-
export declare class World<
|
|
13
|
+
export declare class World<UpdateParams extends any[] = []> {
|
|
14
14
|
private entityIdManager;
|
|
15
15
|
private archetypes;
|
|
16
16
|
private archetypeMap;
|
|
@@ -43,7 +43,7 @@ export declare class World<ExtraParams extends any[] = [deltaTime: number]> {
|
|
|
43
43
|
/**
|
|
44
44
|
* Create a new entity
|
|
45
45
|
*/
|
|
46
|
-
|
|
46
|
+
new(): EntityId;
|
|
47
47
|
/**
|
|
48
48
|
* Destroy an entity and remove all its components (immediate execution)
|
|
49
49
|
*/
|
|
@@ -51,41 +51,41 @@ export declare class World<ExtraParams extends any[] = [deltaTime: number]> {
|
|
|
51
51
|
/**
|
|
52
52
|
* Check if an entity exists
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
exists(entityId: EntityId): boolean;
|
|
55
55
|
/**
|
|
56
56
|
* Add a component to an entity (deferred)
|
|
57
57
|
*/
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
set(entityId: EntityId, componentType: EntityId<void>): void;
|
|
59
|
+
set<T>(entityId: EntityId, componentType: EntityId<T>, component: NoInfer<T>): void;
|
|
60
60
|
/**
|
|
61
61
|
* Remove a component from an entity (deferred)
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
delete<T>(entityId: EntityId, componentType: EntityId<T>): void;
|
|
64
64
|
/**
|
|
65
65
|
* Destroy an entity and remove all its components (deferred)
|
|
66
66
|
*/
|
|
67
|
-
|
|
67
|
+
destroy(entityId: EntityId): void;
|
|
68
68
|
/**
|
|
69
69
|
* Check if an entity has a specific component
|
|
70
70
|
*/
|
|
71
|
-
|
|
71
|
+
has<T>(entityId: EntityId, componentType: EntityId<T>): boolean;
|
|
72
72
|
/**
|
|
73
73
|
* Get component data for a specific entity and wildcard relation type
|
|
74
74
|
* Returns an array of all matching relation instances
|
|
75
75
|
* @param entityId The entity
|
|
76
76
|
* @param componentType The wildcard relation type
|
|
77
77
|
*/
|
|
78
|
-
|
|
78
|
+
get<T>(entityId: EntityId, componentType: WildcardRelationId<T>): [EntityId<unknown>, T][];
|
|
79
79
|
/**
|
|
80
80
|
* Get component data for a specific entity and component type
|
|
81
81
|
* @param entityId The entity
|
|
82
82
|
* @param componentType The component type
|
|
83
83
|
*/
|
|
84
|
-
|
|
84
|
+
get<T>(entityId: EntityId, componentType: EntityId<T>): T;
|
|
85
85
|
/**
|
|
86
86
|
* Register a system with optional dependencies
|
|
87
87
|
*/
|
|
88
|
-
registerSystem(system: System<
|
|
88
|
+
registerSystem(system: System<UpdateParams>): void;
|
|
89
89
|
/**
|
|
90
90
|
* Register a lifecycle hook for component or wildcard relation events
|
|
91
91
|
*/
|
|
@@ -102,11 +102,11 @@ export declare class World<ExtraParams extends any[] = [deltaTime: number]> {
|
|
|
102
102
|
/**
|
|
103
103
|
* Update the world (run all systems in dependency order)
|
|
104
104
|
*/
|
|
105
|
-
update(...params:
|
|
105
|
+
update(...params: UpdateParams): void;
|
|
106
106
|
/**
|
|
107
107
|
* Execute all deferred commands immediately without running systems
|
|
108
108
|
*/
|
|
109
|
-
|
|
109
|
+
sync(): void;
|
|
110
110
|
/**
|
|
111
111
|
* Create a cached query for efficient entity lookups
|
|
112
112
|
*/
|