@codehz/ecs 0.0.10 → 0.1.1
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 +24 -24
- package/archetype.d.ts +4 -4
- package/changeset.d.ts +2 -2
- package/command-buffer.d.ts +5 -5
- package/index.js +52 -50
- package/package.json +1 -1
- package/world.d.ts +10 -10
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
180
|
- `update(...params)`: 更新世界(参数取决于泛型配置)
|
|
181
|
-
- `
|
|
181
|
+
- `sync()`: 应用命令缓冲区
|
|
182
182
|
|
|
183
183
|
### Entity
|
|
184
184
|
|
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
|
@@ -259,7 +259,7 @@ class Archetype {
|
|
|
259
259
|
this.entityToIndex.set(entityId, index);
|
|
260
260
|
for (const componentType of this.componentTypes) {
|
|
261
261
|
const data = componentData.get(componentType);
|
|
262
|
-
this.
|
|
262
|
+
this.getComponentData(componentType).push(data === undefined ? MISSING_COMPONENT : data);
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
removeEntity(entityId) {
|
|
@@ -271,7 +271,7 @@ class Archetype {
|
|
|
271
271
|
this.entityToIndex.delete(entityId);
|
|
272
272
|
const removedData = new Map;
|
|
273
273
|
for (const componentType of this.componentTypes) {
|
|
274
|
-
const dataArray = this.
|
|
274
|
+
const dataArray = this.getComponentData(componentType);
|
|
275
275
|
removedData.set(componentType, dataArray[index]);
|
|
276
276
|
dataArray.splice(index, 1);
|
|
277
277
|
}
|
|
@@ -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`);
|
|
@@ -295,7 +295,7 @@ class Archetype {
|
|
|
295
295
|
for (const relType of this.componentTypes) {
|
|
296
296
|
const relDetailed = getDetailedIdType(relType);
|
|
297
297
|
if ((relDetailed.type === "entity-relation" || relDetailed.type === "component-relation") && relDetailed.componentId === componentId) {
|
|
298
|
-
const dataArray = this.
|
|
298
|
+
const dataArray = this.getComponentData(relType);
|
|
299
299
|
if (dataArray && dataArray[index] !== undefined) {
|
|
300
300
|
const data = dataArray[index];
|
|
301
301
|
relations.push([relDetailed.targetId, data === MISSING_COMPONENT ? undefined : data]);
|
|
@@ -304,11 +304,11 @@ class Archetype {
|
|
|
304
304
|
}
|
|
305
305
|
return relations;
|
|
306
306
|
} else {
|
|
307
|
-
const data = this.
|
|
307
|
+
const data = this.getComponentData(componentType)[index];
|
|
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
|
}
|
|
@@ -316,14 +316,18 @@ class Archetype {
|
|
|
316
316
|
if (index === undefined) {
|
|
317
317
|
throw new Error(`Entity ${entityId} is not in this archetype`);
|
|
318
318
|
}
|
|
319
|
-
const dataArray = this.
|
|
319
|
+
const dataArray = this.getComponentData(componentType);
|
|
320
320
|
dataArray[index] = data;
|
|
321
321
|
}
|
|
322
322
|
getEntities() {
|
|
323
|
-
return
|
|
323
|
+
return this.entities;
|
|
324
324
|
}
|
|
325
325
|
getComponentData(componentType) {
|
|
326
|
-
|
|
326
|
+
const data = this.componentData.get(componentType);
|
|
327
|
+
if (!data) {
|
|
328
|
+
throw new Error(`Component type ${componentType} is not in this archetype`);
|
|
329
|
+
}
|
|
330
|
+
return data;
|
|
327
331
|
}
|
|
328
332
|
getEntitiesWithComponents(componentTypes) {
|
|
329
333
|
const result = [];
|
|
@@ -347,7 +351,7 @@ class Archetype {
|
|
|
347
351
|
});
|
|
348
352
|
return matchingRelations;
|
|
349
353
|
} else {
|
|
350
|
-
return this.
|
|
354
|
+
return this.getComponentData(compType);
|
|
351
355
|
}
|
|
352
356
|
});
|
|
353
357
|
});
|
|
@@ -359,12 +363,10 @@ class Archetype {
|
|
|
359
363
|
const matchingRelations = dataSource;
|
|
360
364
|
const relations = [];
|
|
361
365
|
for (const relType of matchingRelations) {
|
|
362
|
-
const dataArray = this.
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
relations.push([decodedRel.targetId, data === MISSING_COMPONENT ? undefined : data]);
|
|
367
|
-
}
|
|
366
|
+
const dataArray = this.getComponentData(relType);
|
|
367
|
+
const data = dataArray[entityIndex];
|
|
368
|
+
const decodedRel = decodeRelationId(relType);
|
|
369
|
+
relations.push([decodedRel.targetId, data === MISSING_COMPONENT ? undefined : data]);
|
|
368
370
|
}
|
|
369
371
|
return relations;
|
|
370
372
|
} else {
|
|
@@ -380,7 +382,7 @@ class Archetype {
|
|
|
380
382
|
for (let i = 0;i < this.entities.length; i++) {
|
|
381
383
|
const components = new Map;
|
|
382
384
|
for (const componentType of this.componentTypes) {
|
|
383
|
-
const data = this.
|
|
385
|
+
const data = this.getComponentData(componentType)[i];
|
|
384
386
|
components.set(componentType, data === MISSING_COMPONENT ? undefined : data);
|
|
385
387
|
}
|
|
386
388
|
callback(this.entities[i], components);
|
|
@@ -392,11 +394,11 @@ class Archetype {
|
|
|
392
394
|
class ComponentChangeset {
|
|
393
395
|
adds = new Map;
|
|
394
396
|
removes = new Set;
|
|
395
|
-
|
|
397
|
+
set(componentType, component2) {
|
|
396
398
|
this.adds.set(componentType, component2);
|
|
397
399
|
this.removes.delete(componentType);
|
|
398
400
|
}
|
|
399
|
-
|
|
401
|
+
delete(componentType) {
|
|
400
402
|
this.removes.add(componentType);
|
|
401
403
|
this.adds.delete(componentType);
|
|
402
404
|
}
|
|
@@ -440,14 +442,14 @@ class CommandBuffer {
|
|
|
440
442
|
constructor(executeEntityCommands) {
|
|
441
443
|
this.executeEntityCommands = executeEntityCommands;
|
|
442
444
|
}
|
|
443
|
-
|
|
444
|
-
this.commands.push({ type: "
|
|
445
|
+
set(entityId, componentType, component2) {
|
|
446
|
+
this.commands.push({ type: "set", entityId, componentType, component: component2 });
|
|
445
447
|
}
|
|
446
|
-
|
|
447
|
-
this.commands.push({ type: "
|
|
448
|
+
delete(entityId, componentType) {
|
|
449
|
+
this.commands.push({ type: "delete", entityId, componentType });
|
|
448
450
|
}
|
|
449
|
-
|
|
450
|
-
this.commands.push({ type: "
|
|
451
|
+
destroy(entityId) {
|
|
452
|
+
this.commands.push({ type: "destroy", entityId });
|
|
451
453
|
}
|
|
452
454
|
execute() {
|
|
453
455
|
const MAX_ITERATIONS = 100;
|
|
@@ -664,7 +666,7 @@ class World {
|
|
|
664
666
|
getComponentTypesHash(componentTypes) {
|
|
665
667
|
return componentTypes.join(",");
|
|
666
668
|
}
|
|
667
|
-
|
|
669
|
+
new() {
|
|
668
670
|
const entityId = this.entityIdManager.allocate();
|
|
669
671
|
let emptyArchetype = this.getOrCreateArchetype([]);
|
|
670
672
|
emptyArchetype.addEntity(entityId, new Map);
|
|
@@ -683,7 +685,7 @@ class World {
|
|
|
683
685
|
const currentComponents = new Map;
|
|
684
686
|
for (const compType of sourceArchetype.componentTypes) {
|
|
685
687
|
if (compType !== componentType) {
|
|
686
|
-
const data = sourceArchetype.
|
|
688
|
+
const data = sourceArchetype.get(sourceEntityId, compType);
|
|
687
689
|
if (data !== undefined) {
|
|
688
690
|
currentComponents.set(compType, data);
|
|
689
691
|
}
|
|
@@ -709,11 +711,11 @@ class World {
|
|
|
709
711
|
this.entityToArchetype.delete(entityId);
|
|
710
712
|
this.entityIdManager.deallocate(entityId);
|
|
711
713
|
}
|
|
712
|
-
|
|
714
|
+
exists(entityId) {
|
|
713
715
|
return this.entityToArchetype.has(entityId);
|
|
714
716
|
}
|
|
715
|
-
|
|
716
|
-
if (!this.
|
|
717
|
+
set(entityId, componentType, component2) {
|
|
718
|
+
if (!this.exists(entityId)) {
|
|
717
719
|
throw new Error(`Entity ${entityId} does not exist`);
|
|
718
720
|
}
|
|
719
721
|
const detailedType = getDetailedIdType(componentType);
|
|
@@ -723,31 +725,31 @@ class World {
|
|
|
723
725
|
if (detailedType.type === "wildcard-relation") {
|
|
724
726
|
throw new Error(`Cannot directly add wildcard relation components: ${componentType}`);
|
|
725
727
|
}
|
|
726
|
-
this.commandBuffer.
|
|
728
|
+
this.commandBuffer.set(entityId, componentType, component2);
|
|
727
729
|
}
|
|
728
|
-
|
|
729
|
-
if (!this.
|
|
730
|
+
delete(entityId, componentType) {
|
|
731
|
+
if (!this.exists(entityId)) {
|
|
730
732
|
throw new Error(`Entity ${entityId} does not exist`);
|
|
731
733
|
}
|
|
732
734
|
const detailedType = getDetailedIdType(componentType);
|
|
733
735
|
if (detailedType.type === "invalid") {
|
|
734
736
|
throw new Error(`Invalid component type: ${componentType}`);
|
|
735
737
|
}
|
|
736
|
-
this.commandBuffer.
|
|
738
|
+
this.commandBuffer.delete(entityId, componentType);
|
|
737
739
|
}
|
|
738
|
-
|
|
739
|
-
this.commandBuffer.
|
|
740
|
+
destroy(entityId) {
|
|
741
|
+
this.commandBuffer.destroy(entityId);
|
|
740
742
|
}
|
|
741
|
-
|
|
743
|
+
has(entityId, componentType) {
|
|
742
744
|
const archetype = this.entityToArchetype.get(entityId);
|
|
743
745
|
return archetype ? archetype.componentTypes.includes(componentType) : false;
|
|
744
746
|
}
|
|
745
|
-
|
|
747
|
+
get(entityId, componentType) {
|
|
746
748
|
const archetype = this.entityToArchetype.get(entityId);
|
|
747
749
|
if (!archetype) {
|
|
748
750
|
throw new Error(`Entity ${entityId} does not exist`);
|
|
749
751
|
}
|
|
750
|
-
return archetype.
|
|
752
|
+
return archetype.get(entityId, componentType);
|
|
751
753
|
}
|
|
752
754
|
registerSystem(system) {
|
|
753
755
|
this.systemScheduler.addSystem(system);
|
|
@@ -777,7 +779,7 @@ class World {
|
|
|
777
779
|
}
|
|
778
780
|
this.commandBuffer.execute();
|
|
779
781
|
}
|
|
780
|
-
|
|
782
|
+
sync() {
|
|
781
783
|
this.commandBuffer.execute();
|
|
782
784
|
}
|
|
783
785
|
createQuery(componentTypes, filter = {}) {
|
|
@@ -895,7 +897,7 @@ class World {
|
|
|
895
897
|
}
|
|
896
898
|
executeEntityCommands(entityId, commands) {
|
|
897
899
|
const changeset = new ComponentChangeset;
|
|
898
|
-
const hasDestroy = commands.some((cmd) => cmd.type === "
|
|
900
|
+
const hasDestroy = commands.some((cmd) => cmd.type === "destroy");
|
|
899
901
|
if (hasDestroy) {
|
|
900
902
|
this._destroyEntity(entityId);
|
|
901
903
|
return changeset;
|
|
@@ -906,26 +908,26 @@ class World {
|
|
|
906
908
|
}
|
|
907
909
|
const currentComponents = new Map;
|
|
908
910
|
for (const componentType of currentArchetype.componentTypes) {
|
|
909
|
-
const data = currentArchetype.
|
|
911
|
+
const data = currentArchetype.get(entityId, componentType);
|
|
910
912
|
currentComponents.set(componentType, data);
|
|
911
913
|
}
|
|
912
914
|
for (const cmd of commands) {
|
|
913
915
|
switch (cmd.type) {
|
|
914
|
-
case "
|
|
916
|
+
case "set":
|
|
915
917
|
if (cmd.componentType) {
|
|
916
918
|
const detailedType = getDetailedIdType(cmd.componentType);
|
|
917
919
|
if ((detailedType.type === "entity-relation" || detailedType.type === "component-relation") && this.exclusiveComponents.has(detailedType.componentId)) {
|
|
918
920
|
for (const componentType of currentArchetype.componentTypes) {
|
|
919
921
|
const componentDetailedType = getDetailedIdType(componentType);
|
|
920
922
|
if ((componentDetailedType.type === "entity-relation" || componentDetailedType.type === "component-relation") && componentDetailedType.componentId === detailedType.componentId) {
|
|
921
|
-
changeset.
|
|
923
|
+
changeset.delete(componentType);
|
|
922
924
|
}
|
|
923
925
|
}
|
|
924
926
|
}
|
|
925
|
-
changeset.
|
|
927
|
+
changeset.set(cmd.componentType, cmd.component);
|
|
926
928
|
}
|
|
927
929
|
break;
|
|
928
|
-
case "
|
|
930
|
+
case "delete":
|
|
929
931
|
if (cmd.componentType) {
|
|
930
932
|
const detailedType = getDetailedIdType(cmd.componentType);
|
|
931
933
|
if (detailedType.type === "wildcard-relation") {
|
|
@@ -934,12 +936,12 @@ class World {
|
|
|
934
936
|
const componentDetailedType = getDetailedIdType(componentType);
|
|
935
937
|
if (componentDetailedType.type === "entity-relation" || componentDetailedType.type === "component-relation") {
|
|
936
938
|
if (componentDetailedType.componentId === baseComponentId) {
|
|
937
|
-
changeset.
|
|
939
|
+
changeset.delete(componentType);
|
|
938
940
|
}
|
|
939
941
|
}
|
|
940
942
|
}
|
|
941
943
|
} else {
|
|
942
|
-
changeset.
|
|
944
|
+
changeset.delete(cmd.componentType);
|
|
943
945
|
}
|
|
944
946
|
}
|
|
945
947
|
break;
|
|
@@ -956,7 +958,7 @@ class World {
|
|
|
956
958
|
this.entityToArchetype.set(entityId, newArchetype);
|
|
957
959
|
} else {
|
|
958
960
|
for (const [componentType, component2] of changeset.adds) {
|
|
959
|
-
currentArchetype.
|
|
961
|
+
currentArchetype.set(entityId, componentType, component2);
|
|
960
962
|
}
|
|
961
963
|
}
|
|
962
964
|
for (const componentType of changeset.removes) {
|
package/package.json
CHANGED
package/world.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export declare class World<UpdateParams extends any[] = []> {
|
|
|
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,37 +51,37 @@ export declare class World<UpdateParams extends any[] = []> {
|
|
|
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
|
*/
|
|
@@ -106,7 +106,7 @@ export declare class World<UpdateParams extends any[] = []> {
|
|
|
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
|
*/
|