@codehz/ecs 0.3.2 → 0.3.4
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/index.js +92 -19
- package/multi-map.d.ts +19 -0
- package/package.json +1 -1
- package/world.d.ts +1 -2
package/index.js
CHANGED
|
@@ -594,6 +594,86 @@ class CommandBuffer {
|
|
|
594
594
|
}
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
// src/multi-map.ts
|
|
598
|
+
class MultiMap {
|
|
599
|
+
map = new Map;
|
|
600
|
+
_valueCount = 0;
|
|
601
|
+
get valueCount() {
|
|
602
|
+
return this._valueCount;
|
|
603
|
+
}
|
|
604
|
+
get keyCount() {
|
|
605
|
+
return this.map.size;
|
|
606
|
+
}
|
|
607
|
+
hasKey(key) {
|
|
608
|
+
return this.map.has(key);
|
|
609
|
+
}
|
|
610
|
+
has(key, value) {
|
|
611
|
+
const set = this.map.get(key);
|
|
612
|
+
if (!set)
|
|
613
|
+
return false;
|
|
614
|
+
if (arguments.length === 1)
|
|
615
|
+
return true;
|
|
616
|
+
return set.has(value);
|
|
617
|
+
}
|
|
618
|
+
add(key, value) {
|
|
619
|
+
let set = this.map.get(key);
|
|
620
|
+
if (!set) {
|
|
621
|
+
set = new Set;
|
|
622
|
+
this.map.set(key, set);
|
|
623
|
+
}
|
|
624
|
+
if (!set.has(value)) {
|
|
625
|
+
set.add(value);
|
|
626
|
+
this._valueCount++;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
remove(key, value) {
|
|
630
|
+
const set = this.map.get(key);
|
|
631
|
+
if (!set)
|
|
632
|
+
return false;
|
|
633
|
+
if (!set.has(value))
|
|
634
|
+
return false;
|
|
635
|
+
set.delete(value);
|
|
636
|
+
this._valueCount--;
|
|
637
|
+
if (set.size === 0)
|
|
638
|
+
this.map.delete(key);
|
|
639
|
+
return true;
|
|
640
|
+
}
|
|
641
|
+
deleteKey(key) {
|
|
642
|
+
const set = this.map.get(key);
|
|
643
|
+
if (!set)
|
|
644
|
+
return false;
|
|
645
|
+
this._valueCount -= set.size;
|
|
646
|
+
this.map.delete(key);
|
|
647
|
+
return true;
|
|
648
|
+
}
|
|
649
|
+
get(key) {
|
|
650
|
+
const set = this.map.get(key);
|
|
651
|
+
return set ? new Set(set) : new Set;
|
|
652
|
+
}
|
|
653
|
+
*keys() {
|
|
654
|
+
yield* this.map.keys();
|
|
655
|
+
}
|
|
656
|
+
*values() {
|
|
657
|
+
for (const set of this.map.values()) {
|
|
658
|
+
for (const v of set)
|
|
659
|
+
yield v;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
[Symbol.iterator]() {
|
|
663
|
+
return this.entries();
|
|
664
|
+
}
|
|
665
|
+
*entries() {
|
|
666
|
+
for (const [k, set] of this.map.entries()) {
|
|
667
|
+
for (const v of set)
|
|
668
|
+
yield [k, v];
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
clear() {
|
|
672
|
+
this.map.clear();
|
|
673
|
+
this._valueCount = 0;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
597
677
|
// src/query-filter.ts
|
|
598
678
|
function serializeQueryFilter(filter = {}) {
|
|
599
679
|
const negative = (filter.negativeComponentTypes || []).slice().sort((a, b) => a - b);
|
|
@@ -809,11 +889,6 @@ class World {
|
|
|
809
889
|
if (snapshot.entityManager) {
|
|
810
890
|
this.entityIdManager.deserializeState(snapshot.entityManager);
|
|
811
891
|
}
|
|
812
|
-
if (Array.isArray(snapshot.exclusiveComponents)) {
|
|
813
|
-
for (const id of snapshot.exclusiveComponents) {
|
|
814
|
-
this.exclusiveComponents.add(id);
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
892
|
if (Array.isArray(snapshot.entities)) {
|
|
818
893
|
for (const entry of snapshot.entities) {
|
|
819
894
|
const entityId = entry.id;
|
|
@@ -883,7 +958,7 @@ class World {
|
|
|
883
958
|
return;
|
|
884
959
|
}
|
|
885
960
|
const componentReferences = this.getEntityReferences(entityId);
|
|
886
|
-
for (const
|
|
961
|
+
for (const [sourceEntityId, componentType] of componentReferences) {
|
|
887
962
|
const sourceArchetype = this.entityToArchetype.get(sourceEntityId);
|
|
888
963
|
if (sourceArchetype) {
|
|
889
964
|
const currentComponents = new Map;
|
|
@@ -1083,8 +1158,12 @@ class World {
|
|
|
1083
1158
|
matchingArchetypes = [...this.archetypes];
|
|
1084
1159
|
}
|
|
1085
1160
|
for (const wildcard of wildcardRelations) {
|
|
1086
|
-
|
|
1087
|
-
|
|
1161
|
+
matchingArchetypes = matchingArchetypes.filter((archetype) => archetype.componentTypes.some((archetypeType) => {
|
|
1162
|
+
if (!isRelationId(archetypeType))
|
|
1163
|
+
return false;
|
|
1164
|
+
const decoded = decodeRelationId(archetypeType);
|
|
1165
|
+
return decoded.componentId === wildcard.componentId;
|
|
1166
|
+
}));
|
|
1088
1167
|
}
|
|
1089
1168
|
return matchingArchetypes;
|
|
1090
1169
|
}
|
|
@@ -1207,26 +1286,21 @@ class World {
|
|
|
1207
1286
|
}
|
|
1208
1287
|
trackEntityReference(sourceEntityId, componentType, targetEntityId) {
|
|
1209
1288
|
if (!this.entityReferences.has(targetEntityId)) {
|
|
1210
|
-
this.entityReferences.set(targetEntityId, new
|
|
1289
|
+
this.entityReferences.set(targetEntityId, new MultiMap);
|
|
1211
1290
|
}
|
|
1212
|
-
this.entityReferences.get(targetEntityId).add(
|
|
1291
|
+
this.entityReferences.get(targetEntityId).add(sourceEntityId, componentType);
|
|
1213
1292
|
}
|
|
1214
1293
|
untrackEntityReference(sourceEntityId, componentType, targetEntityId) {
|
|
1215
1294
|
const references = this.entityReferences.get(targetEntityId);
|
|
1216
1295
|
if (references) {
|
|
1217
|
-
references.
|
|
1218
|
-
|
|
1219
|
-
references.delete(reference);
|
|
1220
|
-
}
|
|
1221
|
-
});
|
|
1222
|
-
if (references.size === 0) {
|
|
1296
|
+
references.get(sourceEntityId).delete(componentType);
|
|
1297
|
+
if (references.keyCount === 0) {
|
|
1223
1298
|
this.entityReferences.delete(targetEntityId);
|
|
1224
1299
|
}
|
|
1225
1300
|
}
|
|
1226
1301
|
}
|
|
1227
1302
|
getEntityReferences(targetEntityId) {
|
|
1228
|
-
|
|
1229
|
-
return references ? Array.from(references) : [];
|
|
1303
|
+
return this.entityReferences.get(targetEntityId) ?? [];
|
|
1230
1304
|
}
|
|
1231
1305
|
cleanupEmptyArchetype(archetype) {
|
|
1232
1306
|
if (archetype.getEntities().length > 0) {
|
|
@@ -1331,7 +1405,6 @@ class World {
|
|
|
1331
1405
|
return {
|
|
1332
1406
|
version: 1,
|
|
1333
1407
|
entityManager: this.entityIdManager.serializeState(),
|
|
1334
|
-
exclusiveComponents: Array.from(this.exclusiveComponents),
|
|
1335
1408
|
entities
|
|
1336
1409
|
};
|
|
1337
1410
|
}
|
package/multi-map.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare class MultiMap<K, V> {
|
|
2
|
+
private map;
|
|
3
|
+
private _valueCount;
|
|
4
|
+
get valueCount(): number;
|
|
5
|
+
get keyCount(): number;
|
|
6
|
+
hasKey(key: K): boolean;
|
|
7
|
+
has(key: K, value?: V): boolean;
|
|
8
|
+
add(key: K, value: V): void;
|
|
9
|
+
remove(key: K, value: V): boolean;
|
|
10
|
+
deleteKey(key: K): boolean;
|
|
11
|
+
get(key: K): Set<V>;
|
|
12
|
+
keys(): IterableIterator<K>;
|
|
13
|
+
values(): IterableIterator<V>;
|
|
14
|
+
[Symbol.iterator](): IterableIterator<[K, V]>;
|
|
15
|
+
entries(): IterableIterator<[K, V]>;
|
|
16
|
+
clear(): void;
|
|
17
|
+
}
|
|
18
|
+
export { MultiMap };
|
|
19
|
+
export type { MultiMap as MultiMapType };
|
package/package.json
CHANGED
package/world.d.ts
CHANGED
|
@@ -176,7 +176,7 @@ export declare class World<UpdateParams extends any[] = []> {
|
|
|
176
176
|
/**
|
|
177
177
|
* Get all component references where a target entity is used as a component type
|
|
178
178
|
* @param targetEntityId The target entity
|
|
179
|
-
* @returns
|
|
179
|
+
* @returns A MultiMap of sourceEntityId to componentTypes that reference the target entity
|
|
180
180
|
*/
|
|
181
181
|
private getEntityReferences;
|
|
182
182
|
/**
|
|
@@ -197,7 +197,6 @@ export declare class World<UpdateParams extends any[] = []> {
|
|
|
197
197
|
export type SerializedWorld = {
|
|
198
198
|
version: number;
|
|
199
199
|
entityManager: any;
|
|
200
|
-
exclusiveComponents: EntityId[];
|
|
201
200
|
entities: SerializedEntity[];
|
|
202
201
|
};
|
|
203
202
|
export type SerializedEntity = {
|