@woosh/meep-engine 2.123.6 → 2.123.7
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/package.json +1 -1
- package/src/core/binary/clz32.d.ts +2 -3
- package/src/core/binary/clz32.d.ts.map +1 -1
- package/src/core/binary/clz32.js +2 -34
- package/src/core/binary/msb_32.d.ts +0 -1
- package/src/core/binary/msb_32.d.ts.map +1 -1
- package/src/core/binary/msb_32.js +1 -4
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +9 -10
- package/src/core/collection/queue/Deque.d.ts.map +1 -1
- package/src/core/collection/queue/Deque.js +10 -2
- package/src/core/collection/queue/Queue.d.ts +7 -0
- package/src/core/collection/queue/Queue.d.ts.map +1 -0
- package/src/core/collection/queue/Queue.js +7 -0
- package/src/engine/ecs/Entity.d.ts.map +1 -1
- package/src/engine/ecs/Entity.js +6 -24
- package/src/engine/ecs/EntityComponentDataset.d.ts.map +1 -1
- package/src/engine/ecs/EntityComponentDataset.js +187 -155
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clz32.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/clz32.js"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"clz32.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/clz32.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH,0CAAgC"}
|
package/src/core/binary/clz32.js
CHANGED
|
@@ -1,37 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Count leading zeroes in a 32bit integer
|
|
3
|
-
* @
|
|
4
|
-
* @returns {number}
|
|
3
|
+
* @deprecated use Math.clz32 directly
|
|
5
4
|
*/
|
|
6
|
-
export
|
|
7
|
-
if (x === 0) {
|
|
8
|
-
return 32;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
let v = x >>> 0;
|
|
12
|
-
let result = 0;
|
|
13
|
-
|
|
14
|
-
// Binary search.
|
|
15
|
-
if ((v & 0xFFFF0000) === 0) {
|
|
16
|
-
v <<= 16;
|
|
17
|
-
result += 16;
|
|
18
|
-
}
|
|
19
|
-
if ((v & 0xFF000000) === 0) {
|
|
20
|
-
v <<= 8;
|
|
21
|
-
result += 8;
|
|
22
|
-
}
|
|
23
|
-
if ((v & 0xF0000000) === 0) {
|
|
24
|
-
v <<= 4;
|
|
25
|
-
result += 4;
|
|
26
|
-
}
|
|
27
|
-
if ((v & 0xC0000000) === 0) {
|
|
28
|
-
v <<= 2;
|
|
29
|
-
result += 2;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if ((v & 0x80000000) === 0) {
|
|
33
|
-
result += 1;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return result;
|
|
37
|
-
}
|
|
5
|
+
export const clz32 = Math.clz32;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"msb_32.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/msb_32.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"msb_32.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/msb_32.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,0BAHW,MAAM,GACJ,MAAM,CAIlB"}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { clz32 } from "./clz32.js";
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* get most significant set bit
|
|
5
|
-
* @see https://graphics.stanford.edu/~seander/bithacks.html
|
|
6
3
|
* @param {number} x 32 bit integer
|
|
7
4
|
* @returns {number} integer position of most significant bit
|
|
8
5
|
*/
|
|
9
6
|
export function msb_32(x) {
|
|
10
|
-
return 31 - clz32(x);
|
|
7
|
+
return 31 - Math.clz32(x);
|
|
11
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ebvh_build_hierarchy_radix.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ebvh_build_hierarchy_radix.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js"],"names":[],"mappings":"AA2MA;;;;;;;;GAQG;AACH,gDAPW,GAAG,cACH,MAAM,EAAE,GAAC,WAAW,uBACpB,MAAM,EAAE,cACR,MAAM,kBACN,MAAM,EAAE,GACN,MAAM,CAqElB"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { assert } from "../../assert.js";
|
|
2
|
-
import { clz32 } from "../../binary/clz32.js";
|
|
3
2
|
import { clamp } from "../../math/clamp.js";
|
|
4
3
|
import { NULL_NODE } from "./BVH.js";
|
|
5
4
|
import { ebvh_update_hierarchy_bounds } from "./ebvh_update_hierarchy_bounds.js";
|
|
@@ -30,7 +29,7 @@ function find_split(
|
|
|
30
29
|
// Calculate the number of highest bits that are the same
|
|
31
30
|
// for all objects, using the count-leading-zeros intrinsic.
|
|
32
31
|
|
|
33
|
-
const commonPrefix = clz32(firstCode ^ lastCode);
|
|
32
|
+
const commonPrefix = Math.clz32(firstCode ^ lastCode);
|
|
34
33
|
|
|
35
34
|
// Use binary search to find where the next bit differs.
|
|
36
35
|
// Specifically, we are looking for the highest object that
|
|
@@ -45,7 +44,7 @@ function find_split(
|
|
|
45
44
|
|
|
46
45
|
if (newSplit < last) {
|
|
47
46
|
const splitCode = sortedMortonCodes[newSplit];
|
|
48
|
-
const splitPrefix = clz32(firstCode ^ splitCode);
|
|
47
|
+
const splitPrefix = Math.clz32(firstCode ^ splitCode);
|
|
49
48
|
if (splitPrefix > commonPrefix) {
|
|
50
49
|
split = newSplit; // accept proposal
|
|
51
50
|
}
|
|
@@ -75,10 +74,10 @@ function GetLongestCommonPrefix(indexA, indexB, elementCount, mortonCodes) {
|
|
|
75
74
|
const mortonCodeA = mortonCodes[indexA];
|
|
76
75
|
const mortonCodeB = mortonCodes[indexB];
|
|
77
76
|
if (mortonCodeA !== mortonCodeB) {
|
|
78
|
-
return clz32(mortonCodeA ^ mortonCodeB);
|
|
77
|
+
return Math.clz32(mortonCodeA ^ mortonCodeB);
|
|
79
78
|
} else {
|
|
80
79
|
// TODO: Technically this should be primitive ID
|
|
81
|
-
return clz32(indexA ^ indexB) + 31;
|
|
80
|
+
return Math.clz32(indexA ^ indexB) + 31;
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
}
|
|
@@ -140,12 +139,12 @@ function determineRange(output, sortedMortonCodes, numTriangles, idx) {
|
|
|
140
139
|
let common_prefix_with_left = 0;
|
|
141
140
|
let common_prefix_with_right = 0;
|
|
142
141
|
|
|
143
|
-
common_prefix_with_right = clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx + 1]);
|
|
142
|
+
common_prefix_with_right = Math.clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx + 1]);
|
|
144
143
|
|
|
145
144
|
if (idx === 0) {
|
|
146
145
|
common_prefix_with_left = -1;
|
|
147
146
|
} else {
|
|
148
|
-
common_prefix_with_left = clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx - 1]);
|
|
147
|
+
common_prefix_with_left = Math.clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx - 1]);
|
|
149
148
|
|
|
150
149
|
}
|
|
151
150
|
|
|
@@ -157,13 +156,13 @@ function determineRange(output, sortedMortonCodes, numTriangles, idx) {
|
|
|
157
156
|
min_prefix_range = -1;
|
|
158
157
|
|
|
159
158
|
} else {
|
|
160
|
-
min_prefix_range = clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx - direction]);
|
|
159
|
+
min_prefix_range = Math.clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx - direction]);
|
|
161
160
|
}
|
|
162
161
|
|
|
163
162
|
let lmax = 2;
|
|
164
163
|
let next_key = idx + lmax * direction;
|
|
165
164
|
|
|
166
|
-
while ((next_key >= 0) && (next_key < numTriangles) && (clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[next_key]) > min_prefix_range)) {
|
|
165
|
+
while ((next_key >= 0) && (next_key < numTriangles) && (Math.clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[next_key]) > min_prefix_range)) {
|
|
167
166
|
lmax *= 2;
|
|
168
167
|
next_key = idx + lmax * direction;
|
|
169
168
|
}
|
|
@@ -176,7 +175,7 @@ function determineRange(output, sortedMortonCodes, numTriangles, idx) {
|
|
|
176
175
|
|
|
177
176
|
if (new_val >= 0 && new_val < numTriangles) {
|
|
178
177
|
const Code = sortedMortonCodes[new_val];
|
|
179
|
-
const Prefix = clz32(sortedMortonCodes[idx] ^ Code);
|
|
178
|
+
const Prefix = Math.clz32(sortedMortonCodes[idx] ^ Code);
|
|
180
179
|
if (Prefix > min_prefix_range) {
|
|
181
180
|
l = l + lmax;
|
|
182
181
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Deque.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/queue/Deque.js"],"names":[],"mappings":"AAqBA
|
|
1
|
+
{"version":3,"file":"Deque.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/queue/Deque.js"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,mBAFa,CAAC;IAkCV;;;OAGG;IACH,uBAFW,MAAM,EAUhB;IAuFD;;;OAGG;IACH,WAFY,OAAO,CAIlB;IAED;;;;OAIG;IACH,SAFa,IAAI,CAiBhB;IAED;;;OAGG;IACH,QAFa,MAAM,CAalB;IA6BD;;;;OAIG;IACH,UAHW,CAAC,GACC,OAAO,CAYnB;IA4BD;;;;OAIG;IACH,OAHW,CAAC,GACC,OAAO,CAInB;IAED;;;OAGG;IACH,YAFW,CAAC,QAOX;IAED;;;OAGG;IACH,eAFa,CAAC,GAAC,SAAS,CAQvB;IAED;;;OAGG;IACH,YAFa,CAAC,GAAC,SAAS,CAIvB;IAED;;;;OAIG;IACH,WAHW,CAAC,GACC,IAAI,CAOhB;IAED;;;OAGG;IACH,cAFa,CAAC,CASb;IAGD;;;OAGG;IACH,WAFa,CAAC,GAAC,SAAS,CAKvB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,CAAC,GAAC,SAAS,CAmBvB;IAED;;;;;OAKG;IACH,iBAJW,CAAC,EAAE,kBACH,MAAM,GACJ,CAAC,EAAE,CAUf;IAoBL;;OAEG;IACH,gBAAoB;IACpB;;OAEG;IACH,uBAAoB;IACpB;;OAEG;IACH,eAAmB;IAEnB;;OAEG;IACH,iBA1GiB,IAAI,CA0GF;IAlCf;;;OAGG;IACH,qBAFa,SAAS,CAAC,CAAC,EAAC,IAAI,CAAC,CAS7B;;CACJ"}
|
|
@@ -20,7 +20,9 @@ const GROWTH_FACTOR = 2;
|
|
|
20
20
|
const EMPTY_ARRAY = new Array(0);
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Queue data structure, first-in-first-out (FIFO).
|
|
24
|
+
* Double-ended queue backed by an array.
|
|
25
|
+
* The fact that it's double-ended means you can add and remove from both ends.
|
|
24
26
|
* @template T
|
|
25
27
|
*/
|
|
26
28
|
export class Deque {
|
|
@@ -162,6 +164,11 @@ export class Deque {
|
|
|
162
164
|
return this.#status === STATUS_EMPTY;
|
|
163
165
|
}
|
|
164
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Clear data from the queue.
|
|
169
|
+
* Makes the queue empty.
|
|
170
|
+
* @returns {void}
|
|
171
|
+
*/
|
|
165
172
|
clear() {
|
|
166
173
|
if (this.#status !== STATUS_EMPTY) {
|
|
167
174
|
let cursor = this.#head;
|
|
@@ -309,6 +316,7 @@ export class Deque {
|
|
|
309
316
|
/**
|
|
310
317
|
* Add element at the end of the queue
|
|
311
318
|
* @param {T} e
|
|
319
|
+
* @returns {void}
|
|
312
320
|
*/
|
|
313
321
|
addLast(e) {
|
|
314
322
|
this.#check_and_expand();
|
|
@@ -374,7 +382,7 @@ export class Deque {
|
|
|
374
382
|
const size = this.size();
|
|
375
383
|
|
|
376
384
|
for (let i = 0; i < size; i++) {
|
|
377
|
-
result[i] = this.getElementByIndex(i);
|
|
385
|
+
result[result_offset + i] = this.getElementByIndex(i);
|
|
378
386
|
}
|
|
379
387
|
|
|
380
388
|
return result;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../../../src/core/collection/queue/Queue.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,+BAA2B;sBANL,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Entity.d.ts","sourceRoot":"","sources":["../../../../src/engine/ecs/Entity.js"],"names":[],"mappings":"AAgBA
|
|
1
|
+
{"version":3,"file":"Entity.d.ts","sourceRoot":"","sources":["../../../../src/engine/ecs/Entity.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH;IA2aI;;;;;OAKG;IACH,+BAJW,MAAM,WACN,sBAAsB,GACpB,MAAM,CAgBlB;IA7bD;;;OAGG;IACH,oBAFU,eAAe,CAES;IAWlC;;;OAGG;IACH,UAFW,MAAM,EAIhB;IAdD;;;OAGG;IACH,UAFa,MAAM,CAIlB;IAmBD;;;OAGG;IACH,kBAFW,MAAM,EAIhB;IAfD;;;OAGG;IACH,kBAFa,MAAM,CAIlB;IAWD;;;;OAIG;IACH,2BAAgB;IAQhB;;;;OAIG;IACH,SAFU,sBAAsB,CAEjB;IAEf;;;OAGG;IACH,OAFU,WAAW,GAAC,MAAM,CAEN;IAEtB;;;;OAIG;IACH,yBAAgB;IAEhB;;OAEG;IACH;QACI;;WAEG;;MAEL;IAUF;;;OAGG;IACH,eAFW,MAAM,GAAC,WAAW,QAI5B;IAED;;;;OAIG;IACH,cAHW,MAAM,GAAC,WAAW,GAChB,OAAO,CAMnB;IAED;;;OAGG;IACH,gBAFW,MAAM,GAAC,WAAW,QAI5B;IAED;;;OAGG;IACH,eAFa,OAAO,CAInB;IAED;;OAEG;IACH,4BAQC;IAED;;;OAGG;IACH,aAFY,MAAM,CAIjB;IAED;;;;OAIG;IACH,IAJa,CAAC,qBACH,CAAC,GACC,MAAM,CAuBlB;IAED;;;;OAIG;IACH,aAJa,CAAC,SACH,CAAC,GACC,OAAO,CAInB;IAED;;;;OAIG;IACH,aAJa,CAAC,SACH,KAAK,CAAC,CAAC,CAAC,GACN,CAAC,GAAC,IAAI,CAclB;IAED;;;;;OAKG;IACH,iBAJa,CAAC,SACH,KAAK,CAAC,CAAC,CAAC,GACN,CAAC,CAUb;IAED;;;;OAIG;IACH,kCAFa,GAAC,GAAC,IAAI,CA0BlB;IAED;;;;OAIG;IACH,qBAHW,MAAM,UACN,GAAC,QAQX;IAED;;;OAGG;IACH,wBAFW,MAAM,gBAiBhB;IAED;;;;;;OAMG;IACH,4BALW,MAAM,gCAEN,GAAC,GACC,MAAM,CAalB;IAED;;;;;;OAMG;IACH,+BALW,MAAM,gCAEN,GAAC,GACC,MAAM,CAyBlB;IAED;;;OAGG;IACH,WAFa,OAAO,CAwBnB;IAED;;;;OAIG;IACH,eAFW,sBAAsB,GADpB,MAAM,CAyDlB;IAyBL;;;;OAIG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;;gCAxe+B,sBAAsB;4BAD1B,kBAAkB;mBAF3B,oCAAoC"}
|
package/src/engine/ecs/Entity.js
CHANGED
|
@@ -19,42 +19,24 @@ const DEFAULT_FLAGS =
|
|
|
19
19
|
*
|
|
20
20
|
*
|
|
21
21
|
* @example
|
|
22
|
-
* // Create a new entity (initially has no components).
|
|
23
22
|
* const entity = new Entity();
|
|
24
23
|
*
|
|
25
|
-
* // Define some components (simple data containers).
|
|
26
|
-
* class PositionComponent {
|
|
27
|
-
* constructor(x, y) {
|
|
28
|
-
* this.x = x;
|
|
29
|
-
* this.y = y;
|
|
30
|
-
* }
|
|
31
|
-
* }
|
|
32
|
-
*
|
|
33
|
-
* class VelocityComponent {
|
|
34
|
-
* constructor(x, y) {
|
|
35
|
-
* this.x = x;
|
|
36
|
-
* this.y = y;
|
|
37
|
-
* }
|
|
38
|
-
* }
|
|
39
|
-
*
|
|
40
24
|
* // Add components to the entity.
|
|
41
|
-
* entity.add(new
|
|
42
|
-
* entity.add(new
|
|
43
|
-
|
|
25
|
+
* entity.add(new Position(10, 20));
|
|
26
|
+
* entity.add(new Velocity(1, 2));
|
|
44
27
|
*
|
|
45
28
|
* // Get a component (would return null if the entity doesn't have it).
|
|
46
|
-
* const position = entity.getComponent(
|
|
29
|
+
* const position = entity.getComponent(Position); // { x:10, y:20 }
|
|
47
30
|
*
|
|
48
31
|
* // Remove a component.
|
|
49
|
-
* entity.removeComponent(
|
|
32
|
+
* entity.removeComponent(Velocity);
|
|
50
33
|
*
|
|
51
34
|
* // To actually use the entity in a game, you need to build it using an EntityComponentDataset.
|
|
52
35
|
* const dataset = new EntityComponentDataset(); // You would typically have one already
|
|
53
36
|
*
|
|
54
|
-
* entity.build(dataset);
|
|
55
|
-
* // Now the entity and its components are managed by the ECS.
|
|
37
|
+
* entity.build(dataset); // add entity with the components to the scene
|
|
56
38
|
*
|
|
57
|
-
* //
|
|
39
|
+
* // ... Once entity is no longer needed, we destroy it
|
|
58
40
|
* entity.destroy();
|
|
59
41
|
*
|
|
60
42
|
* @author Alex Goldring
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityComponentDataset.d.ts","sourceRoot":"","sources":["../../../../src/engine/ecs/EntityComponentDataset.js"],"names":[],"mappings":"AAyHA
|
|
1
|
+
{"version":3,"file":"EntityComponentDataset.d.ts","sourceRoot":"","sources":["../../../../src/engine/ecs/EntityComponentDataset.js"],"names":[],"mappings":"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"}
|
|
@@ -130,13 +130,12 @@ const scratch_args = [];
|
|
|
130
130
|
*
|
|
131
131
|
* @example
|
|
132
132
|
* const ecd = new EntityComponentDataset();
|
|
133
|
-
* // create an entity
|
|
134
|
-
* const entityId = ecd.createEntity();
|
|
135
133
|
*
|
|
136
|
-
*
|
|
137
|
-
* ecd.addComponentToEntity(entityId, myComponentInstance);
|
|
134
|
+
* const entityId = ecd.createEntity(); // create an entity
|
|
138
135
|
*
|
|
139
|
-
* //
|
|
136
|
+
* ecd.addComponentToEntity(entityId, myComponentInstance); // add a component to your entity
|
|
137
|
+
*
|
|
138
|
+
* // ... once no longer needed, destroy the entity
|
|
140
139
|
* ecd.removeEntity(entityId);
|
|
141
140
|
*
|
|
142
141
|
* @see https://en.wikipedia.org/wiki/Entity_component_system
|
|
@@ -255,16 +254,16 @@ export class EntityComponentDataset {
|
|
|
255
254
|
* returns a promise of a component instance based on a given type
|
|
256
255
|
* @template T, R
|
|
257
256
|
* @param {int} entity
|
|
258
|
-
* @param {T}
|
|
257
|
+
* @param {T} component_type
|
|
259
258
|
* @returns {Promise<R>}
|
|
260
259
|
*/
|
|
261
|
-
promiseComponent(entity,
|
|
260
|
+
promiseComponent(entity, component_type) {
|
|
262
261
|
|
|
263
262
|
assert.ok(this.entityExists(entity), `Entity ${entity} doesn't exist`);
|
|
264
263
|
|
|
265
264
|
const self = this;
|
|
266
265
|
return new Promise(function (resolve, reject) {
|
|
267
|
-
const component = self.getComponent(entity,
|
|
266
|
+
const component = self.getComponent(entity, component_type);
|
|
268
267
|
|
|
269
268
|
if (component !== undefined) {
|
|
270
269
|
resolve(component);
|
|
@@ -274,7 +273,7 @@ export class EntityComponentDataset {
|
|
|
274
273
|
function handler(event, entity) {
|
|
275
274
|
const componentClass = event.klass;
|
|
276
275
|
|
|
277
|
-
if (componentClass ===
|
|
276
|
+
if (componentClass === component_type) {
|
|
278
277
|
//found the right one
|
|
279
278
|
|
|
280
279
|
const instance = event.instance;
|
|
@@ -433,18 +432,18 @@ export class EntityComponentDataset {
|
|
|
433
432
|
/**
|
|
434
433
|
* Convenience method for retrieving a collection of components for a given entity
|
|
435
434
|
* @param {number} entity ID of the entity
|
|
436
|
-
* @param {[]}
|
|
435
|
+
* @param {[]} component_classes Classes of components to extract
|
|
437
436
|
* @returns {Array}
|
|
438
437
|
*/
|
|
439
|
-
getComponents(entity,
|
|
438
|
+
getComponents(entity, component_classes) {
|
|
440
439
|
assert.ok(this.entityExists(entity), `Entity ${entity} doesn't exist`);
|
|
441
440
|
|
|
442
|
-
assert.
|
|
443
|
-
assert.
|
|
444
|
-
assert.isArray(
|
|
441
|
+
assert.notNull(component_classes, "component_classes");
|
|
442
|
+
assert.defined(component_classes, "component_classes");
|
|
443
|
+
assert.isArray(component_classes, "component_classes");
|
|
445
444
|
//assert.notOk(componentClasses.some((c, i) => componentClasses.indexOf(c) !== i), 'componentClasses contains duplicates');
|
|
446
445
|
|
|
447
|
-
const resultLength =
|
|
446
|
+
const resultLength = component_classes.length;
|
|
448
447
|
|
|
449
448
|
const result = new Array(resultLength);
|
|
450
449
|
|
|
@@ -457,7 +456,7 @@ export class EntityComponentDataset {
|
|
|
457
456
|
|
|
458
457
|
const componentType = this.componentTypeMap[componentIndex];
|
|
459
458
|
|
|
460
|
-
const resultIndex =
|
|
459
|
+
const resultIndex = component_classes.indexOf(componentType);
|
|
461
460
|
|
|
462
461
|
if (resultIndex === -1) {
|
|
463
462
|
// not requested, skip
|
|
@@ -799,8 +798,11 @@ export class EntityComponentDataset {
|
|
|
799
798
|
/**
|
|
800
799
|
*
|
|
801
800
|
* @param {number} min_size
|
|
801
|
+
* @returns {void}
|
|
802
802
|
*/
|
|
803
803
|
enlargeGenerationTable(min_size) {
|
|
804
|
+
assert.isNonNegativeInteger(min_size, 'min_size');
|
|
805
|
+
|
|
804
806
|
const old_generation_table_size = this.entityGeneration.length;
|
|
805
807
|
|
|
806
808
|
const new_size = max3(
|
|
@@ -832,6 +834,7 @@ export class EntityComponentDataset {
|
|
|
832
834
|
/**
|
|
833
835
|
* @private
|
|
834
836
|
* @param {number} entity_id
|
|
837
|
+
* @returns {void}
|
|
835
838
|
*/
|
|
836
839
|
createEntityUnsafe(entity_id) {
|
|
837
840
|
this.entityOccupancy.set(entity_id, true);
|
|
@@ -868,6 +871,7 @@ export class EntityComponentDataset {
|
|
|
868
871
|
*
|
|
869
872
|
* @param {number} entity_id
|
|
870
873
|
* @throws {Error} if entity index is already in use
|
|
874
|
+
* @returns {void}
|
|
871
875
|
*/
|
|
872
876
|
createEntitySpecific(entity_id) {
|
|
873
877
|
if (this.entityExists(entity_id)) {
|
|
@@ -947,76 +951,80 @@ export class EntityComponentDataset {
|
|
|
947
951
|
/**
|
|
948
952
|
* Convenience method for removal of multiple entities
|
|
949
953
|
* Works the same as {@link removeEntity} but for multiple elements
|
|
950
|
-
* @param {number[]}
|
|
954
|
+
* @param {number[]} entity_ids
|
|
955
|
+
* @returns {void}
|
|
951
956
|
*/
|
|
952
|
-
removeEntities(
|
|
953
|
-
const length =
|
|
957
|
+
removeEntities(entity_ids) {
|
|
958
|
+
const length = entity_ids.length;
|
|
954
959
|
for (let i = 0; i < length; i++) {
|
|
955
|
-
const entityIndex =
|
|
960
|
+
const entityIndex = entity_ids[i];
|
|
956
961
|
this.removeEntity(entityIndex);
|
|
957
962
|
}
|
|
958
963
|
}
|
|
959
964
|
|
|
960
965
|
/**
|
|
961
966
|
*
|
|
962
|
-
* @param {number}
|
|
967
|
+
* @param {number} entity_id
|
|
963
968
|
* @param {Class} klass
|
|
969
|
+
* @returns {void}
|
|
964
970
|
*/
|
|
965
|
-
removeComponentFromEntity(
|
|
966
|
-
const
|
|
971
|
+
removeComponentFromEntity(entity_id, klass) {
|
|
972
|
+
const component_index = this.componentTypeMap.indexOf(klass);
|
|
967
973
|
|
|
968
|
-
if (
|
|
974
|
+
if (component_index === -1) {
|
|
969
975
|
throw new Error(`Component class not found in this dataset`);
|
|
970
976
|
}
|
|
971
977
|
|
|
972
|
-
this.removeComponentFromEntityByIndex(
|
|
978
|
+
this.removeComponentFromEntityByIndex(entity_id, component_index);
|
|
973
979
|
}
|
|
974
980
|
|
|
975
981
|
/**
|
|
976
982
|
*
|
|
977
|
-
* @param {number}
|
|
978
|
-
* @param {number}
|
|
983
|
+
* @param {number} entity_id
|
|
984
|
+
* @param {number} component_index
|
|
985
|
+
* @returns {void}
|
|
979
986
|
*/
|
|
980
|
-
removeComponentFromEntityByIndex(
|
|
981
|
-
assert.ok(this.entityExists(
|
|
982
|
-
assert.ok(this.componentIndexExists(
|
|
987
|
+
removeComponentFromEntityByIndex(entity_id, component_index) {
|
|
988
|
+
assert.ok(this.entityExists(entity_id), `entity ${entity_id} does not exist`);
|
|
989
|
+
assert.ok(this.componentIndexExists(component_index), `componentIndex ${component_index} is out of bounds`);
|
|
983
990
|
|
|
984
991
|
//check if component exists
|
|
985
|
-
const componentOccupancyIndex =
|
|
992
|
+
const componentOccupancyIndex = entity_id * this.componentTypeCount + component_index;
|
|
986
993
|
const exists = this.componentOccupancy.get(componentOccupancyIndex);
|
|
987
994
|
|
|
988
995
|
if (!exists) {
|
|
989
996
|
//nothing to remove
|
|
990
|
-
console.warn(`Entity ${
|
|
997
|
+
console.warn(`Entity ${entity_id} doesn't have a component with index ${component_index}`);
|
|
991
998
|
return;
|
|
992
999
|
}
|
|
993
1000
|
|
|
994
|
-
this.removeComponentFromEntityByIndex_Unchecked(
|
|
1001
|
+
this.removeComponentFromEntityByIndex_Unchecked(entity_id, component_index, componentOccupancyIndex);
|
|
995
1002
|
}
|
|
996
1003
|
|
|
997
1004
|
/**
|
|
998
1005
|
* This method doesn't perform any checks, make sure you understand what you are doing when using it
|
|
999
1006
|
* @private
|
|
1000
|
-
* @param {number}
|
|
1001
|
-
* @param {number}
|
|
1002
|
-
* @param {number}
|
|
1007
|
+
* @param {number} entity_id
|
|
1008
|
+
* @param {number} component_index
|
|
1009
|
+
* @param {number} component_occupancy_index
|
|
1010
|
+
* @returns {void}
|
|
1003
1011
|
*/
|
|
1004
|
-
removeComponentFromEntityByIndex_Unchecked(
|
|
1005
|
-
this.processObservers_ComponentRemoved(
|
|
1012
|
+
removeComponentFromEntityByIndex_Unchecked(entity_id, component_index, component_occupancy_index) {
|
|
1013
|
+
this.processObservers_ComponentRemoved(entity_id, component_index);
|
|
1006
1014
|
|
|
1007
|
-
const componentInstance = this.components[
|
|
1015
|
+
const componentInstance = this.components[component_index][entity_id];
|
|
1008
1016
|
|
|
1009
1017
|
//remove component from record
|
|
1010
|
-
delete this.components[
|
|
1018
|
+
delete this.components[component_index][entity_id];
|
|
1011
1019
|
|
|
1012
1020
|
//clear occupancy bit
|
|
1013
|
-
this.componentOccupancy.clear(
|
|
1021
|
+
this.componentOccupancy.clear(component_occupancy_index);
|
|
1014
1022
|
|
|
1015
1023
|
//dispatch events
|
|
1016
|
-
const componentClass = this.componentTypeMap[
|
|
1024
|
+
const componentClass = this.componentTypeMap[component_index];
|
|
1017
1025
|
|
|
1018
1026
|
//dispatch event to components
|
|
1019
|
-
this.sendEvent(
|
|
1027
|
+
this.sendEvent(entity_id, EventType.ComponentRemoved, { klass: componentClass, instance: componentInstance });
|
|
1020
1028
|
}
|
|
1021
1029
|
|
|
1022
1030
|
/**
|
|
@@ -1054,14 +1062,14 @@ export class EntityComponentDataset {
|
|
|
1054
1062
|
|
|
1055
1063
|
/**
|
|
1056
1064
|
* @template T
|
|
1057
|
-
* @param {Class<T>}
|
|
1065
|
+
* @param {Class<T>} component_type
|
|
1058
1066
|
* @returns {{entity:number, component:T}}
|
|
1059
1067
|
*/
|
|
1060
|
-
getAnyComponent(
|
|
1068
|
+
getAnyComponent(component_type) {
|
|
1061
1069
|
let entity = -1;
|
|
1062
1070
|
let component = null;
|
|
1063
1071
|
|
|
1064
|
-
this.traverseComponents(
|
|
1072
|
+
this.traverseComponents(component_type, (c, i) => {
|
|
1065
1073
|
entity = i;
|
|
1066
1074
|
component = c;
|
|
1067
1075
|
|
|
@@ -1079,89 +1087,89 @@ export class EntityComponentDataset {
|
|
|
1079
1087
|
* Associate a component with a particular entity
|
|
1080
1088
|
* @template C
|
|
1081
1089
|
* @param {number} entity_id
|
|
1082
|
-
* @param {C}
|
|
1090
|
+
* @param {C} component_instance
|
|
1091
|
+
* @returns {void}
|
|
1083
1092
|
*/
|
|
1084
|
-
addComponentToEntity(entity_id,
|
|
1093
|
+
addComponentToEntity(entity_id, component_instance) {
|
|
1085
1094
|
|
|
1086
|
-
assert.notNull(
|
|
1095
|
+
assert.notNull(component_instance, "componentInstance");
|
|
1087
1096
|
|
|
1088
|
-
assert.defined(
|
|
1097
|
+
assert.defined(component_instance, "componentInstance");
|
|
1089
1098
|
|
|
1090
1099
|
/**
|
|
1091
1100
|
*
|
|
1092
1101
|
* @type {Class<C>}
|
|
1093
1102
|
*/
|
|
1094
|
-
const klass =
|
|
1103
|
+
const klass = component_instance.constructor;
|
|
1095
1104
|
|
|
1096
1105
|
const componentTypeIndex = this.__type_to_index_map.get(klass);
|
|
1097
1106
|
|
|
1098
1107
|
if (typeof componentTypeIndex !== "number") {
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
throw new Error(`Component class not found in this dataset for componentInstance ${stringifyComponent(componentInstance)}`);
|
|
1108
|
+
throw new Error(`Component class not found in this dataset for component_instance ${stringifyComponent(component_instance)}`);
|
|
1102
1109
|
}
|
|
1103
1110
|
|
|
1104
|
-
this.addComponentToEntityByIndex(entity_id, componentTypeIndex,
|
|
1111
|
+
this.addComponentToEntityByIndex(entity_id, componentTypeIndex, component_instance);
|
|
1105
1112
|
}
|
|
1106
1113
|
|
|
1107
1114
|
/**
|
|
1108
1115
|
* @template C
|
|
1109
|
-
* @param {number}
|
|
1110
|
-
* @param {number}
|
|
1111
|
-
* @param {C}
|
|
1116
|
+
* @param {number} entity_id
|
|
1117
|
+
* @param {number} component_index
|
|
1118
|
+
* @param {C} component_instance
|
|
1119
|
+
* @returns {void}
|
|
1112
1120
|
*/
|
|
1113
|
-
addComponentToEntityByIndex(
|
|
1121
|
+
addComponentToEntityByIndex(entity_id, component_index, component_instance) {
|
|
1114
1122
|
|
|
1115
|
-
assert.ok(this.entityExists(
|
|
1116
|
-
assert.ok(this.componentIndexExists(
|
|
1123
|
+
assert.ok(this.entityExists(entity_id), `entity ${entity_id} does not exist`);
|
|
1124
|
+
assert.ok(this.componentIndexExists(component_index), `component_index ${component_index} is out of bounds`);
|
|
1117
1125
|
|
|
1118
|
-
assert.
|
|
1126
|
+
assert.defined(component_instance, "component_instance");
|
|
1119
1127
|
|
|
1120
|
-
assert.equal(this.getComponentByIndex(
|
|
1128
|
+
assert.equal(this.getComponentByIndex(entity_id, component_index), undefined, `entity ${entity_id} already has component ${component_index}`);
|
|
1121
1129
|
|
|
1122
1130
|
|
|
1123
|
-
const componentOccupancyIndex =
|
|
1131
|
+
const componentOccupancyIndex = entity_id * this.componentTypeCount + component_index;
|
|
1124
1132
|
|
|
1125
1133
|
//record component occupancy
|
|
1126
1134
|
this.componentOccupancy.set(componentOccupancyIndex, true);
|
|
1127
1135
|
|
|
1128
1136
|
//inset component instance into component dataset
|
|
1129
|
-
this.components[
|
|
1137
|
+
this.components[component_index][entity_id] = component_instance;
|
|
1130
1138
|
|
|
1131
1139
|
//process observers
|
|
1132
|
-
this.processObservers_ComponentAdded(
|
|
1140
|
+
this.processObservers_ComponentAdded(entity_id, component_index);
|
|
1133
1141
|
|
|
1134
1142
|
//dispatch events
|
|
1135
|
-
const componentClass = this.componentTypeMap[
|
|
1143
|
+
const componentClass = this.componentTypeMap[component_index];
|
|
1136
1144
|
|
|
1137
1145
|
//dispatch event to components
|
|
1138
|
-
this.sendEvent(
|
|
1146
|
+
this.sendEvent(entity_id, EventType.ComponentAdded, { klass: componentClass, instance: component_instance });
|
|
1139
1147
|
}
|
|
1140
1148
|
|
|
1141
1149
|
/**
|
|
1142
1150
|
* @template C
|
|
1143
|
-
* @param {number}
|
|
1144
|
-
* @param {number}
|
|
1151
|
+
* @param {number} entity_id
|
|
1152
|
+
* @param {number} component_index
|
|
1145
1153
|
* @returns {C|undefined}
|
|
1146
1154
|
*/
|
|
1147
|
-
getComponentByIndex(
|
|
1155
|
+
getComponentByIndex(entity_id, component_index) {
|
|
1148
1156
|
|
|
1149
|
-
assert.ok(this.entityExists(
|
|
1150
|
-
assert.ok(this.componentIndexExists(
|
|
1157
|
+
assert.ok(this.entityExists(entity_id), `entity ${entity_id} does not exist`);
|
|
1158
|
+
assert.ok(this.componentIndexExists(component_index), `component_index ${component_index} is out of bounds`);
|
|
1151
1159
|
|
|
1152
1160
|
|
|
1153
|
-
return this.components[
|
|
1161
|
+
return this.components[component_index][entity_id];
|
|
1154
1162
|
}
|
|
1155
1163
|
|
|
1156
1164
|
/**
|
|
1157
|
-
* Whether
|
|
1165
|
+
* Whether a given entity has a component of the specified class attached
|
|
1158
1166
|
* @template C
|
|
1159
|
-
* @param {number}
|
|
1167
|
+
* @param {number} entity_id
|
|
1160
1168
|
* @param {Class<C>} klass
|
|
1161
1169
|
* @returns {boolean}
|
|
1162
1170
|
*/
|
|
1163
|
-
hasComponent(
|
|
1164
|
-
return this.getComponent(
|
|
1171
|
+
hasComponent(entity_id, klass) {
|
|
1172
|
+
return this.getComponent(entity_id, klass) !== undefined;
|
|
1165
1173
|
}
|
|
1166
1174
|
|
|
1167
1175
|
/**
|
|
@@ -1188,13 +1196,13 @@ export class EntityComponentDataset {
|
|
|
1188
1196
|
/**
|
|
1189
1197
|
* Always returns non-null value, if the component is not found - an error is thrown instead
|
|
1190
1198
|
* @template C
|
|
1191
|
-
* @param {number}
|
|
1199
|
+
* @param {number} entity_id
|
|
1192
1200
|
* @param {Class<C>} klass
|
|
1193
1201
|
* @returns {C}
|
|
1194
1202
|
* @throws {Error} when component not found
|
|
1195
1203
|
*/
|
|
1196
|
-
getComponentSafe(
|
|
1197
|
-
const component = this.getComponent(
|
|
1204
|
+
getComponentSafe(entity_id, klass) {
|
|
1205
|
+
const component = this.getComponent(entity_id, klass);
|
|
1198
1206
|
|
|
1199
1207
|
if (component === undefined) {
|
|
1200
1208
|
throw new Error("Component not found");
|
|
@@ -1205,23 +1213,24 @@ export class EntityComponentDataset {
|
|
|
1205
1213
|
|
|
1206
1214
|
/**
|
|
1207
1215
|
* same as getComponent when component exists, if component is not associated with the entity, callback will be invoked once when it is added.
|
|
1208
|
-
* @param {Number}
|
|
1209
|
-
* @param {Class}
|
|
1216
|
+
* @param {Number} entity_id
|
|
1217
|
+
* @param {Class} component_class
|
|
1210
1218
|
* @param {function} callback
|
|
1211
1219
|
* @param {*} [thisArg]
|
|
1220
|
+
* @returns {void}
|
|
1212
1221
|
*/
|
|
1213
|
-
getComponentAsync(
|
|
1214
|
-
const component = this.getComponent(
|
|
1222
|
+
getComponentAsync(entity_id, component_class, callback, thisArg) {
|
|
1223
|
+
const component = this.getComponent(entity_id, component_class);
|
|
1215
1224
|
|
|
1216
1225
|
const handler = (options) => {
|
|
1217
|
-
if (options.klass ===
|
|
1218
|
-
this.removeEntityEventListener(
|
|
1226
|
+
if (options.klass === component_class) {
|
|
1227
|
+
this.removeEntityEventListener(entity_id, EventType.ComponentAdded, handler);
|
|
1219
1228
|
callback.call(thisArg, options.instance);
|
|
1220
1229
|
}
|
|
1221
1230
|
}
|
|
1222
1231
|
|
|
1223
1232
|
if (component === undefined) {
|
|
1224
|
-
this.addEntityEventListener(
|
|
1233
|
+
this.addEntityEventListener(entity_id, EventType.ComponentAdded, handler);
|
|
1225
1234
|
} else {
|
|
1226
1235
|
callback.call(thisArg, component);
|
|
1227
1236
|
}
|
|
@@ -1239,6 +1248,7 @@ export class EntityComponentDataset {
|
|
|
1239
1248
|
* @param {Array} classes
|
|
1240
1249
|
* @param {function(...args):boolean} visitor Visitor can return optional "false" to terminate traversal earlier
|
|
1241
1250
|
* @param {object} [thisArg] specifies context object on which callbacks are to be called, optional
|
|
1251
|
+
* @returns {void}
|
|
1242
1252
|
*/
|
|
1243
1253
|
traverseEntities(classes, visitor, thisArg) {
|
|
1244
1254
|
|
|
@@ -1319,6 +1329,7 @@ export class EntityComponentDataset {
|
|
|
1319
1329
|
* @param {Array.<class>} classes
|
|
1320
1330
|
* @param {Function} visitor
|
|
1321
1331
|
* @param {Object} [thisArg] specifies context object on which callbacks are to be called, optional
|
|
1332
|
+
* @returns {void}
|
|
1322
1333
|
*/
|
|
1323
1334
|
traverseEntitiesExact(classes, visitor, thisArg) {
|
|
1324
1335
|
let entityIndex, i;
|
|
@@ -1379,17 +1390,19 @@ export class EntityComponentDataset {
|
|
|
1379
1390
|
}
|
|
1380
1391
|
|
|
1381
1392
|
/**
|
|
1382
|
-
*
|
|
1383
|
-
* @
|
|
1393
|
+
* Iterate over all entities
|
|
1394
|
+
* @return {Generator<number>}
|
|
1384
1395
|
*/
|
|
1385
|
-
*
|
|
1386
|
-
|
|
1396
|
+
* [Symbol.iterator]() {
|
|
1387
1397
|
const eo = this.entityOccupancy;
|
|
1388
1398
|
|
|
1389
|
-
for (
|
|
1399
|
+
for (
|
|
1400
|
+
let i = eo.nextSetBit(0);
|
|
1401
|
+
i !== -1;
|
|
1402
|
+
i = eo.nextSetBit(i + 1)
|
|
1403
|
+
) {
|
|
1390
1404
|
yield i;
|
|
1391
1405
|
}
|
|
1392
|
-
|
|
1393
1406
|
}
|
|
1394
1407
|
|
|
1395
1408
|
/**
|
|
@@ -1397,6 +1410,7 @@ export class EntityComponentDataset {
|
|
|
1397
1410
|
* @param {Class<T>} klass
|
|
1398
1411
|
* @param {function(instance:T, entity:number)} visitor
|
|
1399
1412
|
* @param {*} [thisArg=undefined]
|
|
1413
|
+
* @returns {void}
|
|
1400
1414
|
*/
|
|
1401
1415
|
traverseComponents(klass, visitor, thisArg) {
|
|
1402
1416
|
const componentTypeIndex = this.computeComponentTypeIndex(klass);
|
|
@@ -1413,29 +1427,31 @@ export class EntityComponentDataset {
|
|
|
1413
1427
|
|
|
1414
1428
|
/**
|
|
1415
1429
|
*
|
|
1416
|
-
* @param {number}
|
|
1430
|
+
* @param {number} component_index
|
|
1417
1431
|
* @param {function} visitor
|
|
1418
1432
|
* @param {*} [thisArg]
|
|
1433
|
+
* @returns {void}
|
|
1419
1434
|
*/
|
|
1420
|
-
traverseComponentsByIndex(
|
|
1435
|
+
traverseComponentsByIndex(component_index, visitor, thisArg) {
|
|
1421
1436
|
|
|
1422
|
-
assert.isNumber(
|
|
1423
|
-
assert.isNonNegativeInteger(
|
|
1437
|
+
assert.isNumber(component_index, "component_index");
|
|
1438
|
+
assert.isNonNegativeInteger(component_index, "component_index");
|
|
1424
1439
|
assert.isFunction(visitor, "visitor");
|
|
1425
1440
|
|
|
1426
|
-
this.__traverseComponentsByIndex_via_property(
|
|
1441
|
+
this.__traverseComponentsByIndex_via_property(component_index, visitor, thisArg);
|
|
1427
1442
|
}
|
|
1428
1443
|
|
|
1429
1444
|
/**
|
|
1430
1445
|
* Alternative to {@link __traverseComponentsByIndex_via_property} as of 2020, appears to be significantly slower on Chrome with larger datasets
|
|
1431
1446
|
* @private
|
|
1432
|
-
* @param {number}
|
|
1447
|
+
* @param {number} component_index
|
|
1433
1448
|
* @param {function} visitor
|
|
1434
1449
|
* @param {*} [thisArg]
|
|
1450
|
+
* @returns {void}
|
|
1435
1451
|
*/
|
|
1436
|
-
__traverseComponentsByIndex_via_bitset(
|
|
1452
|
+
__traverseComponentsByIndex_via_bitset(component_index, visitor, thisArg) {
|
|
1437
1453
|
|
|
1438
|
-
const componentDataset = this.components[
|
|
1454
|
+
const componentDataset = this.components[component_index];
|
|
1439
1455
|
const componentTypeCount = this.componentTypeCount;
|
|
1440
1456
|
|
|
1441
1457
|
const entityOccupancy = this.entityOccupancy;
|
|
@@ -1443,7 +1459,7 @@ export class EntityComponentDataset {
|
|
|
1443
1459
|
|
|
1444
1460
|
for (let entityIndex = entityOccupancy.nextSetBit(0); entityIndex !== -1; entityIndex = entityOccupancy.nextSetBit(entityIndex + 1)) {
|
|
1445
1461
|
|
|
1446
|
-
const componentOccupancyIndex = entityIndex * componentTypeCount +
|
|
1462
|
+
const componentOccupancyIndex = entityIndex * componentTypeCount + component_index;
|
|
1447
1463
|
|
|
1448
1464
|
if (componentOccupancy.get(componentOccupancyIndex)) {
|
|
1449
1465
|
|
|
@@ -1462,13 +1478,14 @@ export class EntityComponentDataset {
|
|
|
1462
1478
|
|
|
1463
1479
|
/**
|
|
1464
1480
|
* @private
|
|
1465
|
-
* @param {number}
|
|
1481
|
+
* @param {number} component_index
|
|
1466
1482
|
* @param {function} visitor
|
|
1467
1483
|
* @param {*} [thisArg]
|
|
1484
|
+
* @returns {void}
|
|
1468
1485
|
*/
|
|
1469
|
-
__traverseComponentsByIndex_via_property(
|
|
1486
|
+
__traverseComponentsByIndex_via_property(component_index, visitor, thisArg) {
|
|
1470
1487
|
|
|
1471
|
-
const componentDataset = this.components[
|
|
1488
|
+
const componentDataset = this.components[component_index];
|
|
1472
1489
|
|
|
1473
1490
|
for (const entity_key in componentDataset) {
|
|
1474
1491
|
|
|
@@ -1492,13 +1509,14 @@ export class EntityComponentDataset {
|
|
|
1492
1509
|
|
|
1493
1510
|
/**
|
|
1494
1511
|
* @private
|
|
1495
|
-
* @param {number}
|
|
1496
|
-
* @param {number}
|
|
1512
|
+
* @param {number} entity_id
|
|
1513
|
+
* @param {number} component_index
|
|
1514
|
+
* @returns {void}
|
|
1497
1515
|
*/
|
|
1498
|
-
processObservers_ComponentAdded(
|
|
1516
|
+
processObservers_ComponentAdded(entity_id, component_index) {
|
|
1499
1517
|
const observers = this.observers;
|
|
1500
1518
|
|
|
1501
|
-
const observersStore = observers[
|
|
1519
|
+
const observersStore = observers[component_index];
|
|
1502
1520
|
|
|
1503
1521
|
const numObservers = observersStore.length;
|
|
1504
1522
|
|
|
@@ -1514,14 +1532,14 @@ export class EntityComponentDataset {
|
|
|
1514
1532
|
for (; i < numObservers; i++) {
|
|
1515
1533
|
const observer = observersStore[i];
|
|
1516
1534
|
|
|
1517
|
-
const match = matchComponentMask(this.componentOccupancy,
|
|
1535
|
+
const match = matchComponentMask(this.componentOccupancy, entity_id, this.componentTypeCount, observer.componentMask);
|
|
1518
1536
|
|
|
1519
1537
|
if (match) {
|
|
1520
1538
|
//match completing addition
|
|
1521
|
-
buildObserverCallbackArgs(
|
|
1539
|
+
buildObserverCallbackArgs(entity_id, observer.componentMask, observer.componentIndexMapping, this.components, args);
|
|
1522
1540
|
|
|
1523
1541
|
//write entityId argument
|
|
1524
|
-
args[observer.componentTypeCount] =
|
|
1542
|
+
args[observer.componentTypeCount] = entity_id;
|
|
1525
1543
|
|
|
1526
1544
|
//invoke callback
|
|
1527
1545
|
observer.callbackComplete.apply(observer.thisArg, args);
|
|
@@ -1531,13 +1549,14 @@ export class EntityComponentDataset {
|
|
|
1531
1549
|
|
|
1532
1550
|
/**
|
|
1533
1551
|
* @private
|
|
1534
|
-
* @param {number}
|
|
1535
|
-
* @param {number}
|
|
1552
|
+
* @param {number} entity_id
|
|
1553
|
+
* @param {number} component_index
|
|
1554
|
+
* @returns {void}
|
|
1536
1555
|
*/
|
|
1537
|
-
processObservers_ComponentRemoved(
|
|
1556
|
+
processObservers_ComponentRemoved(entity_id, component_index) {
|
|
1538
1557
|
const observers = this.observers;
|
|
1539
1558
|
|
|
1540
|
-
const observersStore = observers[
|
|
1559
|
+
const observersStore = observers[component_index];
|
|
1541
1560
|
|
|
1542
1561
|
const numObservers = observersStore.length;
|
|
1543
1562
|
|
|
@@ -1548,14 +1567,14 @@ export class EntityComponentDataset {
|
|
|
1548
1567
|
for (i = 0; i < numObservers; i++) {
|
|
1549
1568
|
const observer = observersStore[i];
|
|
1550
1569
|
|
|
1551
|
-
const match = matchComponentMask(this.componentOccupancy,
|
|
1570
|
+
const match = matchComponentMask(this.componentOccupancy, entity_id, this.componentTypeCount, observer.componentMask);
|
|
1552
1571
|
|
|
1553
1572
|
if (match) {
|
|
1554
1573
|
//match breaking removal
|
|
1555
|
-
buildObserverCallbackArgs(
|
|
1574
|
+
buildObserverCallbackArgs(entity_id, observer.componentMask, observer.componentIndexMapping, this.components, args);
|
|
1556
1575
|
|
|
1557
1576
|
//write entityId argument
|
|
1558
|
-
args[observer.componentTypeCount] =
|
|
1577
|
+
args[observer.componentTypeCount] = entity_id;
|
|
1559
1578
|
|
|
1560
1579
|
//invoke callback
|
|
1561
1580
|
observer.callbackBroken.apply(observer.thisArg, args);
|
|
@@ -1568,6 +1587,7 @@ export class EntityComponentDataset {
|
|
|
1568
1587
|
* @param {number} entity
|
|
1569
1588
|
* @param {function} listener
|
|
1570
1589
|
* @param {*} [thisArg]
|
|
1590
|
+
* @returns {void}
|
|
1571
1591
|
*/
|
|
1572
1592
|
addEntityAnyEventListener(entity, listener, thisArg) {
|
|
1573
1593
|
|
|
@@ -1628,15 +1648,16 @@ export class EntityComponentDataset {
|
|
|
1628
1648
|
}
|
|
1629
1649
|
|
|
1630
1650
|
/**
|
|
1631
|
-
* Registers an event listener to a specific entity and event type, specified by
|
|
1651
|
+
* Registers an event listener to a specific entity and event type, specified by event_name string.
|
|
1632
1652
|
* @param {number} entity
|
|
1633
|
-
* @param {string}
|
|
1653
|
+
* @param {string} event_name
|
|
1634
1654
|
* @param {function()} listener
|
|
1635
1655
|
* @param {*} [thisArg]
|
|
1656
|
+
* @returns {void}
|
|
1636
1657
|
*/
|
|
1637
|
-
addEntityEventListener(entity,
|
|
1658
|
+
addEntityEventListener(entity, event_name, listener, thisArg) {
|
|
1638
1659
|
assert.isNonNegativeInteger(entity, "entity");
|
|
1639
|
-
assert.isString(
|
|
1660
|
+
assert.isString(event_name, "event_name");
|
|
1640
1661
|
assert.isFunction(listener, "listener");
|
|
1641
1662
|
|
|
1642
1663
|
if (!this.entityExists(entity)) {
|
|
@@ -1652,11 +1673,11 @@ export class EntityComponentDataset {
|
|
|
1652
1673
|
evl[entity] = hash;
|
|
1653
1674
|
}
|
|
1654
1675
|
|
|
1655
|
-
let listeners = hash[
|
|
1676
|
+
let listeners = hash[event_name];
|
|
1656
1677
|
|
|
1657
1678
|
if (listeners === void 0) {
|
|
1658
1679
|
listeners = [];
|
|
1659
|
-
hash[
|
|
1680
|
+
hash[event_name] = listeners;
|
|
1660
1681
|
}
|
|
1661
1682
|
|
|
1662
1683
|
const handler = new SignalHandler(listener, thisArg);
|
|
@@ -1667,15 +1688,15 @@ export class EntityComponentDataset {
|
|
|
1667
1688
|
/**
|
|
1668
1689
|
* Remove existing event listener associated with a specific entity. Does nothing if listener isn't registered.
|
|
1669
1690
|
* @param {number} entity
|
|
1670
|
-
* @param {string}
|
|
1691
|
+
* @param {string} event_name
|
|
1671
1692
|
* @param {function} listener
|
|
1672
1693
|
* @param {*} [thisArg]
|
|
1673
1694
|
*
|
|
1674
1695
|
* @returns {boolean}
|
|
1675
1696
|
*/
|
|
1676
|
-
removeEntityEventListener(entity,
|
|
1697
|
+
removeEntityEventListener(entity, event_name, listener, thisArg) {
|
|
1677
1698
|
assert.isNonNegativeInteger(entity, "entity");
|
|
1678
|
-
assert.isString(
|
|
1699
|
+
assert.isString(event_name, "event_name");
|
|
1679
1700
|
assert.isFunction(listener, "listener");
|
|
1680
1701
|
|
|
1681
1702
|
const evl = this.__entityEventListeners;
|
|
@@ -1687,7 +1708,7 @@ export class EntityComponentDataset {
|
|
|
1687
1708
|
return false;
|
|
1688
1709
|
}
|
|
1689
1710
|
|
|
1690
|
-
const listeners = hash[
|
|
1711
|
+
const listeners = hash[event_name];
|
|
1691
1712
|
|
|
1692
1713
|
if (listeners === undefined) {
|
|
1693
1714
|
//no event listeners exist for this event
|
|
@@ -1718,6 +1739,7 @@ export class EntityComponentDataset {
|
|
|
1718
1739
|
* @param {Number} entity
|
|
1719
1740
|
* @param {String} name event name
|
|
1720
1741
|
* @param {Object} [event=undefined]
|
|
1742
|
+
* @returns {void}
|
|
1721
1743
|
*/
|
|
1722
1744
|
sendEvent(entity, name, event) {
|
|
1723
1745
|
// console.log("sendEvent", entity, name, event);
|
|
@@ -1738,11 +1760,11 @@ export class EntityComponentDataset {
|
|
|
1738
1760
|
|
|
1739
1761
|
/**
|
|
1740
1762
|
*
|
|
1741
|
-
* @param {number}
|
|
1763
|
+
* @param {number} entity_id
|
|
1742
1764
|
* @returns {boolean}
|
|
1743
1765
|
*/
|
|
1744
|
-
entityHasComponents(
|
|
1745
|
-
const components = this.getAllComponents(
|
|
1766
|
+
entityHasComponents(entity_id) {
|
|
1767
|
+
const components = this.getAllComponents(entity_id);
|
|
1746
1768
|
const n = components.length;
|
|
1747
1769
|
|
|
1748
1770
|
for (let i = 0; i < n; i++) {
|
|
@@ -1758,6 +1780,7 @@ export class EntityComponentDataset {
|
|
|
1758
1780
|
|
|
1759
1781
|
/**
|
|
1760
1782
|
* Remove all entities, triggers all relevant removal events for each entity/component
|
|
1783
|
+
* @returns {void}
|
|
1761
1784
|
*/
|
|
1762
1785
|
clear() {
|
|
1763
1786
|
const entityOccupancy = this.entityOccupancy;
|
|
@@ -1769,7 +1792,8 @@ export class EntityComponentDataset {
|
|
|
1769
1792
|
|
|
1770
1793
|
/**
|
|
1771
1794
|
* Drops all data, bypassing standard workflow, no events are dispatched. Data is simply ejected.
|
|
1772
|
-
* This method is very efficient but is intended to be used only when associated data is
|
|
1795
|
+
* This method is very efficient but is intended to be used only when associated data is not needed as it may produce unintended consequences if the data is re-used
|
|
1796
|
+
* @returns {void}
|
|
1773
1797
|
*/
|
|
1774
1798
|
dropData() {
|
|
1775
1799
|
//drop components
|
|
@@ -1787,37 +1811,43 @@ export class EntityComponentDataset {
|
|
|
1787
1811
|
|
|
1788
1812
|
/**
|
|
1789
1813
|
* @template T
|
|
1790
|
-
* @param {string}
|
|
1814
|
+
* @param {string} class_name
|
|
1791
1815
|
* @returns {null|function|Class<T>}
|
|
1792
1816
|
*/
|
|
1793
|
-
getComponentClassByName(
|
|
1817
|
+
getComponentClassByName(class_name) {
|
|
1794
1818
|
let i = 0;
|
|
1819
|
+
|
|
1795
1820
|
for (; i < this.componentTypeCount; i++) {
|
|
1821
|
+
|
|
1796
1822
|
const componentClass = this.componentTypeMap[i];
|
|
1797
1823
|
const name = componentClass.typeName;
|
|
1798
|
-
|
|
1824
|
+
|
|
1825
|
+
if (name === class_name) {
|
|
1799
1826
|
return componentClass;
|
|
1800
1827
|
}
|
|
1828
|
+
|
|
1801
1829
|
}
|
|
1830
|
+
|
|
1802
1831
|
return null;
|
|
1803
1832
|
}
|
|
1804
1833
|
|
|
1805
1834
|
/**
|
|
1806
1835
|
* Copy entities from a supplied input dataset. Only components present in the mask are copied
|
|
1807
|
-
* @param {Array}
|
|
1836
|
+
* @param {Array} component_classes
|
|
1808
1837
|
* @param {EntityComponentDataset} source
|
|
1838
|
+
* @returns {void}
|
|
1809
1839
|
*/
|
|
1810
|
-
maskedCopy(source,
|
|
1840
|
+
maskedCopy(source, component_classes) {
|
|
1811
1841
|
|
|
1812
1842
|
let i;
|
|
1813
1843
|
|
|
1814
|
-
const componentCount =
|
|
1844
|
+
const componentCount = component_classes.length;
|
|
1815
1845
|
|
|
1816
1846
|
const sourceComponentIndices = [];
|
|
1817
1847
|
const thisComponentIndices = [];
|
|
1818
1848
|
|
|
1819
1849
|
for (i = 0; i < componentCount; i++) {
|
|
1820
|
-
const componentClass =
|
|
1850
|
+
const componentClass = component_classes[i];
|
|
1821
1851
|
|
|
1822
1852
|
const sourceComponentIndex = source.computeComponentTypeIndex(componentClass);
|
|
1823
1853
|
|
|
@@ -1870,12 +1900,13 @@ export class EntityComponentDataset {
|
|
|
1870
1900
|
|
|
1871
1901
|
/**
|
|
1872
1902
|
* Main utility of this method is to facilitate serialization.
|
|
1873
|
-
* @param {Array}
|
|
1903
|
+
* @param {Array} component_classes
|
|
1874
1904
|
* @param {function(componentIndex:number,components:Array, componentCount:number)} visitor
|
|
1905
|
+
* @returns {void}
|
|
1875
1906
|
*/
|
|
1876
|
-
traverseEntitiesCompactedFiltered(
|
|
1907
|
+
traverseEntitiesCompactedFiltered(component_classes, visitor) {
|
|
1877
1908
|
|
|
1878
|
-
const inputClassCount =
|
|
1909
|
+
const inputClassCount = component_classes.length;
|
|
1879
1910
|
|
|
1880
1911
|
const componentIndices = new Array(inputClassCount);
|
|
1881
1912
|
|
|
@@ -1884,9 +1915,8 @@ export class EntityComponentDataset {
|
|
|
1884
1915
|
let i, j;
|
|
1885
1916
|
|
|
1886
1917
|
for (i = 0; i < inputClassCount; i++) {
|
|
1887
|
-
const
|
|
1888
|
-
|
|
1889
|
-
componentIndices[i] = componentIndex;
|
|
1918
|
+
const klass = component_classes[i];
|
|
1919
|
+
componentIndices[i] = this.computeComponentTypeIndex(klass);
|
|
1890
1920
|
}
|
|
1891
1921
|
|
|
1892
1922
|
//sort component indices array for faster traversal
|
|
@@ -1911,9 +1941,7 @@ export class EntityComponentDataset {
|
|
|
1911
1941
|
const componentIndex = componentIndices[j];
|
|
1912
1942
|
if (componentOccupancy.get(entityOccupancyAddress + componentIndex)) {
|
|
1913
1943
|
//component exists
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
components[componentCount] = componentInstance;
|
|
1944
|
+
components[componentCount] = this.components[componentIndex][i];
|
|
1917
1945
|
|
|
1918
1946
|
componentCount++;
|
|
1919
1947
|
}
|
|
@@ -1936,19 +1964,20 @@ export class EntityComponentDataset {
|
|
|
1936
1964
|
*
|
|
1937
1965
|
* @param {function(entityIndex:number)} visitor
|
|
1938
1966
|
* @param {*} [thisArg]
|
|
1967
|
+
* @returns {void}
|
|
1939
1968
|
*/
|
|
1940
1969
|
traverseEntityIndices(visitor, thisArg) {
|
|
1941
|
-
let
|
|
1970
|
+
let entity_id;
|
|
1942
1971
|
|
|
1943
1972
|
const occupancy = this.entityOccupancy;
|
|
1944
1973
|
|
|
1945
1974
|
for (
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1975
|
+
entity_id = occupancy.nextSetBit(0);
|
|
1976
|
+
entity_id !== -1;
|
|
1977
|
+
entity_id = occupancy.nextSetBit(entity_id + 1)
|
|
1949
1978
|
) {
|
|
1950
1979
|
|
|
1951
|
-
visitor.call(thisArg,
|
|
1980
|
+
visitor.call(thisArg, entity_id);
|
|
1952
1981
|
|
|
1953
1982
|
}
|
|
1954
1983
|
}
|
|
@@ -1960,6 +1989,9 @@ export class EntityComponentDataset {
|
|
|
1960
1989
|
*/
|
|
1961
1990
|
EntityComponentDataset.prototype.isEntityComponentDataset = true;
|
|
1962
1991
|
|
|
1992
|
+
// aliases
|
|
1993
|
+
EntityComponentDataset.prototype.createEntityIterator = EntityComponentDataset.prototype[Symbol.iterator];
|
|
1994
|
+
|
|
1963
1995
|
|
|
1964
1996
|
function stringifyComponent(c) {
|
|
1965
1997
|
if (typeof c === "object") {
|