@woosh/meep-engine 2.59.0 → 2.59.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/build/meep.cjs +538 -518
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +538 -518
- package/editor/process/symbolic/SymbolicDisplayInternalAPI.js +3 -3
- package/editor/process/symbolic/makeParticleEmitterSymbolicDisplay.js +1 -1
- package/editor/process/symbolic/makePathSymbolicDisplay.js +1 -1
- package/editor/process/symbolic/makeSoundEmitterSymbolicDisplay.js +1 -1
- package/editor/tools/TopDownCameraControlTool.js +2 -2
- package/editor/tools/v2/TransformControls.js +1 -1
- package/editor/tools/v2/prototypeTransformControls.js +1 -1
- package/package.json +1 -1
- package/samples/generation/main.js +1 -1
- package/samples/terrain/editor.js +1 -1
- package/src/core/collection/array/arraySetDiff.js +11 -7
- package/src/core/geom/3d/aabb/aabb3_array_intersects_point.spec.js +48 -0
- package/src/core/geom/3d/aabb/aabb3_array_intersects_ray.js +5 -1
- package/src/core/geom/3d/aabb/aabb3_expand_array.spec.js +16 -0
- package/src/core/geom/3d/aabb/aabb3_raycast.spec.js +37 -0
- package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.js +11 -12
- package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.spec.js +14 -0
- package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +6 -4
- package/src/core/geom/3d/aabb/compute_aabb_from_points.js +6 -3
- package/src/core/geom/3d/matrix/m4_multiply.spec.js +24 -0
- package/src/core/geom/3d/matrix/m4_multiply_alphatensor.js +56 -40
- package/src/core/geom/3d/matrix/m4_multiply_alphatensor.spec.js +24 -0
- package/src/core/geom/3d/shape/util/shape_to_visual_entity.js +2 -2
- package/src/core/geom/Vector3.spec.js +24 -14
- package/src/engine/EngineHarness.js +1 -1
- package/src/engine/control/ControlContext.js +1 -1
- package/src/engine/ecs/Entity.d.ts +2 -0
- package/src/engine/ecs/Entity.js +40 -37
- package/src/engine/ecs/Entity.spec.js +2 -2
- package/src/engine/ecs/EntityBuilderUtils.js +2 -2
- package/src/engine/ecs/EntityComponentDataset.js +91 -89
- package/src/engine/ecs/EntityFlags.js +4 -4
- package/src/engine/ecs/attachment/Attachment.js +5 -2
- package/src/engine/ecs/binding/ComponentPropertyBinding.js +13 -13
- package/src/engine/ecs/dynamic_actions/RuleExecution.js +1 -1
- package/src/engine/ecs/parent/EntityNode.js +2 -2
- package/src/engine/ecs/parent/EntityNode.spec.js +2 -2
- package/src/engine/ecs/tooltip/testTooltipComponentSystem.js +1 -1
- package/src/engine/ecs/util/hideEntityGracefully.js +6 -6
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +1 -0
- package/src/engine/graphics/ecs/mesh-v2/render/SGThreeObjectCache.js +30 -7
- package/src/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +1 -1
- package/src/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +71 -34
- package/src/engine/graphics/ecs/mesh-v2/sample/prototype_sg_raycast.js +1 -1
- package/src/engine/graphics/ecs/path/PathDisplaySystem.js +4 -4
- package/src/engine/graphics/ecs/path/entity/EntityPathMarker.js +1 -1
- package/src/engine/graphics/ecs/path/highlight/PathDisplayHighlightSystem.js +3 -3
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +5 -5
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +2 -2
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +2 -2
- package/src/engine/intelligence/behavior/ecs/EntityBehavior.js +14 -17
- package/src/engine/intelligence/behavior/util/DelayBehavior.js +6 -6
- package/src/engine/ui/GUIEngine.js +368 -371
- package/src/engine/ui/notification/NotificationManager.js +1 -1
- package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.js +1 -1
- package/src/view/tooltip/gml/TooltipParser.js +21 -28
- package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.js +3 -2
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_branchless.js +0 -52
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_fast.js +0 -176
- package/src/core/geom/3d/aabb/aabb3_intersects_ray_slab.js +0 -91
|
@@ -1,34 +1,34 @@
|
|
|
1
|
+
import {MATRIX_4_IDENTITY} from "./3d/matrix/MATRIX_4_IDENTITY.js";
|
|
2
|
+
import {v3_slerp} from "./vec3/v3_slerp.js";
|
|
1
3
|
import Vector3 from "./Vector3.js";
|
|
2
|
-
import { v3_slerp } from "./vec3/v3_slerp.js";
|
|
3
|
-
import { MATRIX_4_IDENTITY } from "./3d/matrix/MATRIX_4_IDENTITY.js";
|
|
4
4
|
|
|
5
5
|
test('slerp', () => {
|
|
6
6
|
|
|
7
7
|
const v = new Vector3();
|
|
8
8
|
|
|
9
9
|
v3_slerp(v, 0, 0, 0, 0, 0, 0, 0);
|
|
10
|
-
expect(v.toJSON()).toEqual({
|
|
10
|
+
expect(v.toJSON()).toEqual({x: 0, y: 0, z: 0});
|
|
11
11
|
|
|
12
12
|
v3_slerp(v, 0, 0, 0, 0, 0, 0, 1);
|
|
13
|
-
expect(v.toJSON()).toEqual({
|
|
13
|
+
expect(v.toJSON()).toEqual({x: 0, y: 0, z: 0});
|
|
14
14
|
|
|
15
15
|
v3_slerp(v, 1, 1, 1, 1, 1, 1, 0);
|
|
16
|
-
expect(v.toJSON()).toEqual({
|
|
16
|
+
expect(v.toJSON()).toEqual({x: 1, y: 1, z: 1});
|
|
17
17
|
|
|
18
18
|
v3_slerp(v, 1, 1, 1, 1, 1, 1, 1);
|
|
19
|
-
expect(v.toJSON()).toEqual({
|
|
19
|
+
expect(v.toJSON()).toEqual({x: 1, y: 1, z: 1});
|
|
20
20
|
|
|
21
21
|
v3_slerp(v, -1, -1, -1, -1, -1, -1, 0);
|
|
22
|
-
expect(v.toJSON()).toEqual({
|
|
22
|
+
expect(v.toJSON()).toEqual({x: -1, y: -1, z: -1});
|
|
23
23
|
|
|
24
24
|
v3_slerp(v, -1, -1, -1, -1, -1, -1, 1);
|
|
25
|
-
expect(v.toJSON()).toEqual({
|
|
25
|
+
expect(v.toJSON()).toEqual({x: -1, y: -1, z: -1});
|
|
26
26
|
|
|
27
27
|
v3_slerp(v, 1, 1, 1, -1, -1, -1, 0);
|
|
28
|
-
expect(v.toJSON()).toEqual({
|
|
28
|
+
expect(v.toJSON()).toEqual({x: 1, y: 1, z: 1});
|
|
29
29
|
|
|
30
30
|
v3_slerp(v, 1, 1, 1, -1, -1, -1, 1);
|
|
31
|
-
expect(v.toJSON()).toEqual({
|
|
31
|
+
expect(v.toJSON()).toEqual({x: -1, y: -1, z: -1});
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
v3_slerp(v, 1, 0, 0, 0, 1, 0, 0.5);
|
|
@@ -123,10 +123,10 @@ test("iterator symbol", () => {
|
|
|
123
123
|
|
|
124
124
|
const iterator = v[Symbol.iterator]();
|
|
125
125
|
|
|
126
|
-
expect(iterator.next()).toEqual({
|
|
127
|
-
expect(iterator.next()).toEqual({
|
|
128
|
-
expect(iterator.next()).toEqual({
|
|
129
|
-
expect(iterator.next()).toEqual({
|
|
126
|
+
expect(iterator.next()).toEqual({value: 5, done: false})
|
|
127
|
+
expect(iterator.next()).toEqual({value: 7, done: false})
|
|
128
|
+
expect(iterator.next()).toEqual({value: 11, done: false})
|
|
129
|
+
expect(iterator.next()).toEqual({done: true})
|
|
130
130
|
|
|
131
131
|
});
|
|
132
132
|
|
|
@@ -172,3 +172,13 @@ test("applyMatrix with identity", () => {
|
|
|
172
172
|
expect(v.z).toEqual(11);
|
|
173
173
|
|
|
174
174
|
});
|
|
175
|
+
|
|
176
|
+
test("setFromSphericalCoords", () => {
|
|
177
|
+
const v3 = new Vector3();
|
|
178
|
+
|
|
179
|
+
v3.setFromSphericalCoords(0, 0, 0);
|
|
180
|
+
|
|
181
|
+
expect(v3.x).not.toBeNaN();
|
|
182
|
+
expect(v3.y).not.toBeNaN();
|
|
183
|
+
expect(v3.z).not.toBeNaN();
|
|
184
|
+
});
|
|
@@ -125,7 +125,7 @@ export class ControlContext {
|
|
|
125
125
|
|
|
126
126
|
for (const e of this.entities) {
|
|
127
127
|
if (e.getFlag(EntityFlags.Built)) {
|
|
128
|
-
throw new IllegalStateException(`Entity ${e.
|
|
128
|
+
throw new IllegalStateException(`Entity ${e.id} is already built, this violates pre-condition of control context`);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
e.build(this.ecd)
|
package/src/engine/ecs/Entity.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Signal from "../../core/events/signal/Signal.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import {assert} from "../../core/assert.js";
|
|
3
|
+
import {EventType} from "./EntityManager.js";
|
|
4
|
+
import {isDefined} from "../../core/process/matcher/Matchers.js";
|
|
5
|
+
import {EntityFlags} from "./EntityFlags.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Set of default flags
|
|
@@ -20,9 +20,10 @@ const DEFAULT_FLAGS =
|
|
|
20
20
|
class Entity {
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
+
* When entity is live - this is the entity ID inside associated `EntityComponentDataset`, when the entity is not live - it's set to -1
|
|
23
24
|
* @type {number}
|
|
24
25
|
*/
|
|
25
|
-
|
|
26
|
+
id = -1;
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Generation is a unique identifier coming from the dataset
|
|
@@ -32,16 +33,17 @@ class Entity {
|
|
|
32
33
|
generation = -1;
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
|
-
*
|
|
36
|
+
* Components associated with the entity
|
|
37
|
+
* @readonly
|
|
36
38
|
* @type {Array}
|
|
37
39
|
*/
|
|
38
|
-
|
|
40
|
+
components = [];
|
|
39
41
|
|
|
40
42
|
/**
|
|
41
43
|
*
|
|
42
44
|
* @type {{name:string,listener:(function|Function), context:*}[]}
|
|
43
45
|
*/
|
|
44
|
-
deferredListeners = [];
|
|
46
|
+
#deferredListeners = [];
|
|
45
47
|
|
|
46
48
|
/**
|
|
47
49
|
*
|
|
@@ -56,7 +58,7 @@ class Entity {
|
|
|
56
58
|
flags = DEFAULT_FLAGS;
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
|
-
*
|
|
61
|
+
* Arbitrary metadata, add anything you want here
|
|
60
62
|
* @type {Object}
|
|
61
63
|
*/
|
|
62
64
|
properties = {};
|
|
@@ -72,7 +74,7 @@ class Entity {
|
|
|
72
74
|
* Handles event when entity is removed without invoking {@link #destroy} method
|
|
73
75
|
* @private
|
|
74
76
|
*/
|
|
75
|
-
|
|
77
|
+
#handleEntityDestroyed() {
|
|
76
78
|
this.clearFlag(EntityFlags.Built);
|
|
77
79
|
}
|
|
78
80
|
|
|
@@ -115,7 +117,7 @@ class Entity {
|
|
|
115
117
|
* Remove all components from the entity
|
|
116
118
|
*/
|
|
117
119
|
removeAllComponents() {
|
|
118
|
-
const elements = this.
|
|
120
|
+
const elements = this.components;
|
|
119
121
|
const n = elements.length;
|
|
120
122
|
for (let i = n - 1; i >= 0; i--) {
|
|
121
123
|
const component = elements[i];
|
|
@@ -129,7 +131,7 @@ class Entity {
|
|
|
129
131
|
* @return {number}
|
|
130
132
|
*/
|
|
131
133
|
get count() {
|
|
132
|
-
return this.
|
|
134
|
+
return this.components.length;
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
/**
|
|
@@ -139,16 +141,16 @@ class Entity {
|
|
|
139
141
|
*/
|
|
140
142
|
add(componentInstance) {
|
|
141
143
|
if (componentInstance === undefined) {
|
|
142
|
-
throw new Error(`Can not add ${componentInstance} to
|
|
144
|
+
throw new Error(`Can not add ${componentInstance} to Entity`);
|
|
143
145
|
}
|
|
144
146
|
|
|
145
147
|
assert.notOk(this.hasComponent(Object.getPrototypeOf(componentInstance).constructor), 'Component of this type already exists');
|
|
146
148
|
|
|
147
|
-
this.
|
|
149
|
+
this.components.push(componentInstance);
|
|
148
150
|
|
|
149
151
|
if (this.getFlag(EntityFlags.Built)) {
|
|
150
152
|
//already built, add component to entity
|
|
151
|
-
this.dataset.addComponentToEntity(this.
|
|
153
|
+
this.dataset.addComponentToEntity(this.id, componentInstance);
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
return this;
|
|
@@ -169,7 +171,7 @@ class Entity {
|
|
|
169
171
|
* @returns {T|null} component of specified class
|
|
170
172
|
*/
|
|
171
173
|
getComponent(klass) {
|
|
172
|
-
const elements = this.
|
|
174
|
+
const elements = this.components;
|
|
173
175
|
const element_count = elements.length;
|
|
174
176
|
|
|
175
177
|
for (let i = 0; i < element_count; i++) {
|
|
@@ -203,7 +205,7 @@ class Entity {
|
|
|
203
205
|
* @returns {*|null}
|
|
204
206
|
*/
|
|
205
207
|
removeComponent(klass) {
|
|
206
|
-
const elements = this.
|
|
208
|
+
const elements = this.components;
|
|
207
209
|
const n = elements.length;
|
|
208
210
|
|
|
209
211
|
for (let i = 0; i < n; i++) {
|
|
@@ -215,7 +217,7 @@ class Entity {
|
|
|
215
217
|
//see if entity is built
|
|
216
218
|
if (this.getFlag(EntityFlags.Built)) {
|
|
217
219
|
|
|
218
|
-
this.dataset.removeComponentFromEntity(this.
|
|
220
|
+
this.dataset.removeComponentFromEntity(this.id, klass);
|
|
219
221
|
|
|
220
222
|
}
|
|
221
223
|
|
|
@@ -233,7 +235,7 @@ class Entity {
|
|
|
233
235
|
*/
|
|
234
236
|
sendEvent(eventName, event) {
|
|
235
237
|
if (this.getFlag(EntityFlags.Built)) {
|
|
236
|
-
this.dataset.sendEvent(this.
|
|
238
|
+
this.dataset.sendEvent(this.id, eventName, event);
|
|
237
239
|
} else {
|
|
238
240
|
console.warn("Entity doesn't exist. Event " + eventName + ":" + event + " was not sent.")
|
|
239
241
|
}
|
|
@@ -269,9 +271,9 @@ class Entity {
|
|
|
269
271
|
*/
|
|
270
272
|
addEventListener(eventName, listener, context) {
|
|
271
273
|
if (this.getFlag(EntityFlags.Built)) {
|
|
272
|
-
this.dataset.addEntityEventListener(this.
|
|
274
|
+
this.dataset.addEntityEventListener(this.id, eventName, listener, context);
|
|
273
275
|
} else {
|
|
274
|
-
this
|
|
276
|
+
this.#deferredListeners.push({
|
|
275
277
|
name: eventName,
|
|
276
278
|
listener: listener,
|
|
277
279
|
context
|
|
@@ -289,9 +291,9 @@ class Entity {
|
|
|
289
291
|
*/
|
|
290
292
|
removeEventListener(eventName, listener, context) {
|
|
291
293
|
if (this.getFlag(EntityFlags.Built)) {
|
|
292
|
-
this.dataset.removeEntityEventListener(this.
|
|
294
|
+
this.dataset.removeEntityEventListener(this.id, eventName, listener, context);
|
|
293
295
|
} else {
|
|
294
|
-
const listeners = this
|
|
296
|
+
const listeners = this.#deferredListeners;
|
|
295
297
|
|
|
296
298
|
for (let i = 0, numListeners = listeners.length; i < numListeners; i++) {
|
|
297
299
|
const deferredDescriptor = listeners[i];
|
|
@@ -320,16 +322,16 @@ class Entity {
|
|
|
320
322
|
if (this.getFlag(EntityFlags.Built)) {
|
|
321
323
|
|
|
322
324
|
const dataset = this.dataset;
|
|
323
|
-
const entity = this.
|
|
325
|
+
const entity = this.id;
|
|
324
326
|
|
|
325
327
|
//check that the entity is the same as what we have built
|
|
326
|
-
//assert.ok(checkExistingComponents(entity, this.element, dataset), `Signature of
|
|
328
|
+
//assert.ok(checkExistingComponents(entity, this.element, dataset), `Signature of Entity does not match existing entity(id=${entity})`);
|
|
327
329
|
|
|
328
|
-
dataset.removeEntityEventListener(entity, EventType.EntityRemoved, this
|
|
330
|
+
dataset.removeEntityEventListener(entity, EventType.EntityRemoved, this.#handleEntityDestroyed, this);
|
|
329
331
|
|
|
330
332
|
dataset.removeEntity(entity);
|
|
331
333
|
|
|
332
|
-
this.
|
|
334
|
+
this.id = -1;
|
|
333
335
|
|
|
334
336
|
this.clearFlag(EntityFlags.Built);
|
|
335
337
|
|
|
@@ -350,18 +352,18 @@ class Entity {
|
|
|
350
352
|
|
|
351
353
|
if (
|
|
352
354
|
this.getFlag(EntityFlags.Built)
|
|
353
|
-
&& checkExistingComponents(this.
|
|
355
|
+
&& checkExistingComponents(this.id, this.components, dataset)
|
|
354
356
|
) {
|
|
355
357
|
//already built
|
|
356
|
-
return this.
|
|
358
|
+
return this.id;
|
|
357
359
|
}
|
|
358
360
|
|
|
359
|
-
const entity = this.
|
|
361
|
+
const entity = this.id = dataset.createEntity();
|
|
360
362
|
this.dataset = dataset;
|
|
361
363
|
|
|
362
364
|
let i;
|
|
363
365
|
|
|
364
|
-
const listeners = this
|
|
366
|
+
const listeners = this.#deferredListeners;
|
|
365
367
|
const listeners_count = listeners.length;
|
|
366
368
|
|
|
367
369
|
for (i = 0; i < listeners_count; i++) {
|
|
@@ -369,9 +371,9 @@ class Entity {
|
|
|
369
371
|
dataset.addEntityEventListener(entity, subscription.name, subscription.listener, subscription.context);
|
|
370
372
|
}
|
|
371
373
|
// reset listeners
|
|
372
|
-
this
|
|
374
|
+
this.#deferredListeners.splice(0, listeners_count);
|
|
373
375
|
|
|
374
|
-
const element = this.
|
|
376
|
+
const element = this.components;
|
|
375
377
|
const element_count = element.length;
|
|
376
378
|
|
|
377
379
|
if (this.getFlag(EntityFlags.RegisterComponents)) {
|
|
@@ -391,7 +393,7 @@ class Entity {
|
|
|
391
393
|
this.setFlag(EntityFlags.Built);
|
|
392
394
|
|
|
393
395
|
if (this.getFlag(EntityFlags.WatchDestruction)) {
|
|
394
|
-
dataset.addEntityEventListener(entity, EventType.EntityRemoved, this
|
|
396
|
+
dataset.addEntityEventListener(entity, EventType.EntityRemoved, this.#handleEntityDestroyed, this);
|
|
395
397
|
}
|
|
396
398
|
|
|
397
399
|
this.on.built.send2(entity, dataset);
|
|
@@ -399,7 +401,7 @@ class Entity {
|
|
|
399
401
|
}
|
|
400
402
|
|
|
401
403
|
/**
|
|
402
|
-
*
|
|
404
|
+
* Extract data about an entity and its components from a dataset
|
|
403
405
|
* @param {number} entity
|
|
404
406
|
* @param {EntityComponentDataset} dataset
|
|
405
407
|
* @returns {Entity}
|
|
@@ -412,7 +414,7 @@ class Entity {
|
|
|
412
414
|
.forEach(r.add, r);
|
|
413
415
|
|
|
414
416
|
r.setFlag(EntityFlags.Built);
|
|
415
|
-
r.
|
|
417
|
+
r.id = entity;
|
|
416
418
|
r.dataset = dataset;
|
|
417
419
|
|
|
418
420
|
return r;
|
|
@@ -420,10 +422,11 @@ class Entity {
|
|
|
420
422
|
}
|
|
421
423
|
|
|
422
424
|
/**
|
|
425
|
+
* Useful for faster alternative to `instanceof` checks
|
|
423
426
|
* @readonly
|
|
424
427
|
* @type {boolean}
|
|
425
428
|
*/
|
|
426
|
-
Entity.prototype.
|
|
429
|
+
Entity.prototype.isEntity = true;
|
|
427
430
|
|
|
428
431
|
|
|
429
432
|
/**
|
|
@@ -63,7 +63,7 @@ test("'Built' flag is reset when entity is removed without invoking 'destroy' me
|
|
|
63
63
|
expect(b.getFlag(EntityFlags.Built)).toBe(true);
|
|
64
64
|
expect(b.isBuilt).toBe(true);
|
|
65
65
|
|
|
66
|
-
dataset.removeEntity(b.
|
|
66
|
+
dataset.removeEntity(b.id);
|
|
67
67
|
|
|
68
68
|
expect(b.getFlag(EntityFlags.Built)).toBe(false);
|
|
69
69
|
expect(b.isBuilt).toBe(false);
|
|
@@ -135,7 +135,7 @@ test("adding component to live entity results in component being added to the da
|
|
|
135
135
|
const component = new DummyComponent();
|
|
136
136
|
entity.add(component);
|
|
137
137
|
|
|
138
|
-
expect(ecd.getComponent(entity.
|
|
138
|
+
expect(ecd.getComponent(entity.id, DummyComponent)).toBe(component);
|
|
139
139
|
|
|
140
140
|
});
|
|
141
141
|
|
|
@@ -2,7 +2,7 @@ import { EventType } from "./EntityManager.js";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
5
|
-
* @param {
|
|
5
|
+
* @param {Entity[]} builders
|
|
6
6
|
* @returns {Promise}
|
|
7
7
|
*/
|
|
8
8
|
export function whenAllEntitiesDestroyed(builders) {
|
|
@@ -11,7 +11,7 @@ export function whenAllEntitiesDestroyed(builders) {
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
*
|
|
14
|
-
* @param {
|
|
14
|
+
* @param {Entity} builder
|
|
15
15
|
* @returns {Promise}
|
|
16
16
|
*/
|
|
17
17
|
export function whenEntityDestroyed(builder) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {BitSet} from "../../core/binary/BitSet.js";
|
|
2
|
+
import {assert} from "../../core/assert.js";
|
|
3
3
|
import Signal, {
|
|
4
4
|
findSignalHandlerIndexByHandle,
|
|
5
5
|
findSignalHandlerIndexByHandleAndContext
|
|
6
6
|
} from "../../core/events/signal/Signal.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import {EventType} from "./EntityManager.js";
|
|
8
|
+
import {SignalHandler} from "../../core/events/signal/SignalHandler.js";
|
|
9
|
+
import {arraySetDiff} from "../../core/collection/array/arraySetDiff.js";
|
|
10
|
+
import {array_shrink_to_size} from "../../core/collection/array/array_shrink_to_size.js";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
*
|
|
14
|
-
* @param {
|
|
14
|
+
* @param {number} entityIndex
|
|
15
15
|
* @returns {boolean}
|
|
16
16
|
*/
|
|
17
17
|
function validateEntityIndex(entityIndex) {
|
|
@@ -20,7 +20,7 @@ function validateEntityIndex(entityIndex) {
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
*
|
|
23
|
-
* @param {
|
|
23
|
+
* @param {number} componentIndex
|
|
24
24
|
* @returns {boolean}
|
|
25
25
|
*/
|
|
26
26
|
function validateComponentIndex(componentIndex) {
|
|
@@ -29,7 +29,7 @@ function validateComponentIndex(componentIndex) {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
*
|
|
32
|
-
* @param index
|
|
32
|
+
* @param {number} index
|
|
33
33
|
* @param {string} name
|
|
34
34
|
* @returns {boolean}
|
|
35
35
|
*/
|
|
@@ -103,99 +103,101 @@ function buildObserverCallbackArgs(entityIndex, mask, componentIndexMap, compone
|
|
|
103
103
|
const scratch_array_0 = [];
|
|
104
104
|
const scratch_array_1 = [];
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Represents a storage for entities and their associated components
|
|
108
|
+
* Entities are just integer IDs and components are stored in a virtual table, where each component type has a separate column and each entity is a row in that table
|
|
109
|
+
* It is valid for entities to have no components or to have every possible component
|
|
110
|
+
* Generally the entity IDs are compacted, meaning that when an entity is removed - it's ID will be later reused
|
|
111
|
+
*/
|
|
106
112
|
export class EntityComponentDataset {
|
|
113
|
+
|
|
107
114
|
/**
|
|
108
|
-
* @
|
|
109
|
-
* @
|
|
115
|
+
* @private
|
|
116
|
+
* @type {BitSet}
|
|
110
117
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* @private
|
|
119
|
-
* @type {BitSet}
|
|
120
|
-
*/
|
|
121
|
-
this.componentOccupancy = new BitSet();
|
|
118
|
+
entityOccupancy = new BitSet();
|
|
119
|
+
/**
|
|
120
|
+
* @private
|
|
121
|
+
* @type {BitSet}
|
|
122
|
+
*/
|
|
123
|
+
componentOccupancy = new BitSet();
|
|
122
124
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
/**
|
|
126
|
+
* @private
|
|
127
|
+
* @type {Class[]}
|
|
128
|
+
*/
|
|
129
|
+
componentTypeMap = [];
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Fast index lookup from a component class
|
|
133
|
+
* @type {Map<Class, number>}
|
|
134
|
+
* @private
|
|
135
|
+
*/
|
|
136
|
+
__type_to_index_map = new Map();
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
/**
|
|
139
|
+
* How many component types exist for this collection. This is the same as componentMap.length
|
|
140
|
+
* @private
|
|
141
|
+
* @type {number}
|
|
142
|
+
*/
|
|
143
|
+
componentTypeCount = 0;
|
|
142
144
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
/**
|
|
146
|
+
* @private
|
|
147
|
+
* @type {Object[][]}
|
|
148
|
+
*/
|
|
149
|
+
components = [];
|
|
148
150
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
/**
|
|
152
|
+
* Current number of entities
|
|
153
|
+
* @private
|
|
154
|
+
* @type {number}
|
|
155
|
+
*/
|
|
156
|
+
entityCount = 0;
|
|
155
157
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
158
|
+
/**
|
|
159
|
+
* A counter that is incremented every time an entity is created
|
|
160
|
+
* Generation is used to provide an entity with a unique identity
|
|
161
|
+
* Entity IDs are re-used, but generation is always increasing
|
|
162
|
+
* Two entities with the same ID but different generation represent two distinct entities, one with "younger" generation (larger number) is the more recently created one
|
|
163
|
+
* @private
|
|
164
|
+
* @type {number}
|
|
165
|
+
*/
|
|
166
|
+
generation = 0;
|
|
165
167
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
/**
|
|
169
|
+
* @readonly
|
|
170
|
+
* @type {Signal}
|
|
171
|
+
*/
|
|
172
|
+
onEntityCreated = new Signal();
|
|
171
173
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
/**
|
|
175
|
+
* @readonly
|
|
176
|
+
* @type {Signal}
|
|
177
|
+
*/
|
|
178
|
+
onEntityRemoved = new Signal();
|
|
177
179
|
|
|
178
180
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
/**
|
|
182
|
+
*
|
|
183
|
+
* @type {Array<Object<SignalHandler[]>>}
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
__entityEventListeners = [];
|
|
185
187
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
/**
|
|
189
|
+
*
|
|
190
|
+
* @type {SignalHandler[][]}
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
193
|
+
__entityAnyEventListeners = [];
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* @private
|
|
197
|
+
* @type {Array<Array<EntityObserver>>}
|
|
198
|
+
*/
|
|
199
|
+
observers = [];
|
|
192
200
|
|
|
193
|
-
/**
|
|
194
|
-
* @private
|
|
195
|
-
* @type {Array<Array<EntityObserver>>}
|
|
196
|
-
*/
|
|
197
|
-
this.observers = [];
|
|
198
|
-
}
|
|
199
201
|
|
|
200
202
|
/**
|
|
201
203
|
* returns a promise of a component instance based on a given type
|
|
@@ -885,7 +887,7 @@ export class EntityComponentDataset {
|
|
|
885
887
|
const componentClass = this.componentTypeMap[componentIndex];
|
|
886
888
|
|
|
887
889
|
//dispatch event to components
|
|
888
|
-
this.sendEvent(entityIndex, EventType.ComponentRemoved, {
|
|
890
|
+
this.sendEvent(entityIndex, EventType.ComponentRemoved, {klass: componentClass, instance: componentInstance});
|
|
889
891
|
}
|
|
890
892
|
|
|
891
893
|
/**
|
|
@@ -997,7 +999,7 @@ export class EntityComponentDataset {
|
|
|
997
999
|
const componentClass = this.componentTypeMap[componentIndex];
|
|
998
1000
|
|
|
999
1001
|
//dispatch event to components
|
|
1000
|
-
this.sendEvent(entityIndex, EventType.ComponentAdded, {
|
|
1002
|
+
this.sendEvent(entityIndex, EventType.ComponentAdded, {klass: componentClass, instance: componentInstance});
|
|
1001
1003
|
}
|
|
1002
1004
|
|
|
1003
1005
|
/**
|
|
@@ -8,13 +8,13 @@ export const EntityFlags = {
|
|
|
8
8
|
*/
|
|
9
9
|
Built: 1,
|
|
10
10
|
/**
|
|
11
|
-
* If component type is not registered on the {@link EntityComponentDataset} when calling {@link
|
|
11
|
+
* If component type is not registered on the {@link EntityComponentDataset} when calling {@link Entity#build} - will register the component first
|
|
12
12
|
*/
|
|
13
13
|
RegisterComponents: 2,
|
|
14
14
|
/**
|
|
15
|
-
* Entity builder will watch destruction of the entity (subscribe to event), this will make the {@link
|
|
16
|
-
* recognize when the corresponding entity is destroyed outside the
|
|
17
|
-
* NOTE: useful to turn off to save a bit of memory, as those event listeners take up a bit of space. Feel free to turn this flag off when you don't care to keep the reference to the
|
|
15
|
+
* Entity builder will watch destruction of the entity (subscribe to event), this will make the {@link Entity} automatically
|
|
16
|
+
* recognize when the corresponding entity is destroyed outside the {@link Entity} API
|
|
17
|
+
* NOTE: useful to turn off to save a bit of memory, as those event listeners take up a bit of space. Feel free to turn this flag off when you don't care to keep the reference to the {@link Entity}
|
|
18
18
|
*/
|
|
19
19
|
WatchDestruction: 4
|
|
20
20
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Transform} from "../transform/Transform.js";
|
|
2
|
+
import {assert} from "../../../core/assert.js";
|
|
2
3
|
|
|
3
4
|
export class Attachment {
|
|
4
5
|
|
|
@@ -26,7 +27,9 @@ export class Attachment {
|
|
|
26
27
|
*/
|
|
27
28
|
immediate = false;
|
|
28
29
|
|
|
29
|
-
fromJSON({
|
|
30
|
+
fromJSON({parent, socket, transform, immediate = false}) {
|
|
31
|
+
assert.isNonNegativeInteger(parent, 'parent');
|
|
32
|
+
|
|
30
33
|
this.parent = parent;
|
|
31
34
|
this.socket = socket;
|
|
32
35
|
|