@codehz/ecs 0.3.3 → 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 +86 -11
- package/multi-map.d.ts +19 -0
- package/package.json +1 -1
- package/world.d.ts +1 -1
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);
|
|
@@ -878,7 +958,7 @@ class World {
|
|
|
878
958
|
return;
|
|
879
959
|
}
|
|
880
960
|
const componentReferences = this.getEntityReferences(entityId);
|
|
881
|
-
for (const
|
|
961
|
+
for (const [sourceEntityId, componentType] of componentReferences) {
|
|
882
962
|
const sourceArchetype = this.entityToArchetype.get(sourceEntityId);
|
|
883
963
|
if (sourceArchetype) {
|
|
884
964
|
const currentComponents = new Map;
|
|
@@ -1206,26 +1286,21 @@ class World {
|
|
|
1206
1286
|
}
|
|
1207
1287
|
trackEntityReference(sourceEntityId, componentType, targetEntityId) {
|
|
1208
1288
|
if (!this.entityReferences.has(targetEntityId)) {
|
|
1209
|
-
this.entityReferences.set(targetEntityId, new
|
|
1289
|
+
this.entityReferences.set(targetEntityId, new MultiMap);
|
|
1210
1290
|
}
|
|
1211
|
-
this.entityReferences.get(targetEntityId).add(
|
|
1291
|
+
this.entityReferences.get(targetEntityId).add(sourceEntityId, componentType);
|
|
1212
1292
|
}
|
|
1213
1293
|
untrackEntityReference(sourceEntityId, componentType, targetEntityId) {
|
|
1214
1294
|
const references = this.entityReferences.get(targetEntityId);
|
|
1215
1295
|
if (references) {
|
|
1216
|
-
references.
|
|
1217
|
-
|
|
1218
|
-
references.delete(reference);
|
|
1219
|
-
}
|
|
1220
|
-
});
|
|
1221
|
-
if (references.size === 0) {
|
|
1296
|
+
references.get(sourceEntityId).delete(componentType);
|
|
1297
|
+
if (references.keyCount === 0) {
|
|
1222
1298
|
this.entityReferences.delete(targetEntityId);
|
|
1223
1299
|
}
|
|
1224
1300
|
}
|
|
1225
1301
|
}
|
|
1226
1302
|
getEntityReferences(targetEntityId) {
|
|
1227
|
-
|
|
1228
|
-
return references ? Array.from(references) : [];
|
|
1303
|
+
return this.entityReferences.get(targetEntityId) ?? [];
|
|
1229
1304
|
}
|
|
1230
1305
|
cleanupEmptyArchetype(archetype) {
|
|
1231
1306
|
if (archetype.getEntities().length > 0) {
|
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
|
/**
|