@woosh/meep-engine 2.84.4 → 2.84.5

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.
@@ -72502,6 +72502,7 @@ class Entity {
72502
72502
  * @returns {*|null}
72503
72503
  */
72504
72504
  removeComponent(klass) {
72505
+
72505
72506
  const elements = this.components;
72506
72507
  const n = elements.length;
72507
72508
 
@@ -72627,6 +72628,7 @@ class Entity {
72627
72628
  dataset.removeEntity(entity);
72628
72629
 
72629
72630
  this.id = -1;
72631
+ this.generation = -1;
72630
72632
 
72631
72633
  this.clearFlag(EntityFlags.Built);
72632
72634
 
@@ -72652,6 +72654,7 @@ class Entity {
72652
72654
  }
72653
72655
 
72654
72656
  const entity = this.id = dataset.createEntity();
72657
+ this.generation = dataset.getEntityGeneration(entity);
72655
72658
  this.dataset = dataset;
72656
72659
 
72657
72660
  let i;
@@ -72709,6 +72712,7 @@ class Entity {
72709
72712
  r.setFlag(EntityFlags.Built);
72710
72713
  r.id = entity;
72711
72714
  r.dataset = dataset;
72715
+ r.generation = dataset.getEntityGeneration(entity);
72712
72716
 
72713
72717
  return r;
72714
72718
  }
@@ -84050,7 +84054,13 @@ class AssetDescription {
84050
84054
  toString() {
84051
84055
  return `{ type: '${this.type}', path: '${this.path}' }`;
84052
84056
  }
84053
- }
84057
+ }
84058
+
84059
+ /**
84060
+ * @readonly
84061
+ * @type {boolean}
84062
+ */
84063
+ AssetDescription.prototype.isAssetDescription = true;
84054
84064
 
84055
84065
  /**
84056
84066
  * @enum {number}
@@ -92360,6 +92370,15 @@ class EntityComponentDataset {
92360
92370
  * @type {BitSet}
92361
92371
  */
92362
92372
  entityOccupancy = new BitSet();
92373
+
92374
+ /**
92375
+ * For each entity ID records generation when entity was created
92376
+ * Values are invalid for unused entity IDs
92377
+ * @private
92378
+ * @type {Uint32Array}
92379
+ */
92380
+ entityGeneration = new Uint32Array(0);
92381
+
92363
92382
  /**
92364
92383
  * @private
92365
92384
  * @type {BitSet}
@@ -92411,7 +92430,7 @@ class EntityComponentDataset {
92411
92430
 
92412
92431
  /**
92413
92432
  * @readonly
92414
- * @type {Signal}
92433
+ * @type {Signal<number>}
92415
92434
  */
92416
92435
  onEntityCreated = new Signal();
92417
92436
 
@@ -92961,38 +92980,79 @@ class EntityComponentDataset {
92961
92980
 
92962
92981
  /**
92963
92982
  *
92964
- * @returns {number} entityIndex
92983
+ * @param {number} min_size
92965
92984
  */
92966
- createEntity() {
92967
- const entityIndex = this.entityOccupancy.nextClearBit(0);
92968
- this.entityOccupancy.set(entityIndex, true);
92985
+ enlargeGenerationTable(min_size) {
92986
+ const old_generation_table_size = this.entityGeneration.length;
92969
92987
 
92970
- this.entityCount++;
92988
+ const new_size = max3(
92989
+ min_size,
92990
+ Math.ceil(old_generation_table_size * 1.2),
92991
+ old_generation_table_size + 16
92992
+ );
92971
92993
 
92972
- this.onEntityCreated.send1(entityIndex);
92994
+ const new_generation_table = new Uint32Array(new_size);
92973
92995
 
92974
- this.generation++;
92996
+ new_generation_table.set(this.entityGeneration);
92975
92997
 
92976
- return entityIndex;
92998
+ this.entityGeneration = new_generation_table;
92977
92999
  }
92978
93000
 
92979
93001
  /**
92980
- *
92981
- * @param {number} entityIndex
92982
- * @throws {Error} if entity index is already in use
93002
+ * Produces generation ID for a given entity
93003
+ * @param {number} entity_id
93004
+ * @returns {number}
92983
93005
  */
92984
- createEntitySpecific(entityIndex) {
92985
- if (this.entityExists(entityIndex)) {
92986
- throw new Error(`EntityId ${entityIndex} is already in use`);
93006
+ getEntityGeneration(entity_id) {
93007
+ return this.entityGeneration[entity_id];
93008
+ }
93009
+
93010
+ /**
93011
+ * @private
93012
+ * @param {number} entity_id
93013
+ */
93014
+ createEntityUnsafe(entity_id) {
93015
+ this.entityOccupancy.set(entity_id, true);
93016
+
93017
+ // record entity generation
93018
+ if (this.entityGeneration.length <= entity_id) {
93019
+ // needs to be resized
93020
+ this.enlargeGenerationTable(entity_id + 1);
92987
93021
  }
92988
93022
 
92989
- this.entityOccupancy.set(entityIndex, true);
93023
+ const current_generation = this.generation;
93024
+ this.generation = current_generation + 1;
93025
+
93026
+ this.entityGeneration[entity_id] = current_generation;
92990
93027
 
92991
93028
  this.entityCount++;
92992
93029
 
92993
- this.onEntityCreated.send1(entityIndex);
93030
+ this.onEntityCreated.send1(entity_id);
93031
+ }
93032
+
93033
+ /**
93034
+ *
93035
+ * @returns {number} entityIndex
93036
+ */
93037
+ createEntity() {
93038
+ const entity_id = this.entityOccupancy.nextClearBit(0);
93039
+
93040
+ this.createEntityUnsafe(entity_id);
93041
+
93042
+ return entity_id;
93043
+ }
93044
+
93045
+ /**
93046
+ *
93047
+ * @param {number} entity_id
93048
+ * @throws {Error} if entity index is already in use
93049
+ */
93050
+ createEntitySpecific(entity_id) {
93051
+ if (this.entityExists(entity_id)) {
93052
+ throw new Error(`EntityId ${entity_id} is already in use`);
93053
+ }
92994
93054
 
92995
- this.generation++;
93055
+ this.createEntityUnsafe(entity_id);
92996
93056
  }
92997
93057
 
92998
93058
  /**
@@ -93117,7 +93177,7 @@ class EntityComponentDataset {
93117
93177
  const componentClass = this.componentTypeMap[componentIndex];
93118
93178
 
93119
93179
  //dispatch event to components
93120
- this.sendEvent(entityIndex, EventType.ComponentRemoved, {klass: componentClass, instance: componentInstance});
93180
+ this.sendEvent(entityIndex, EventType.ComponentRemoved, { klass: componentClass, instance: componentInstance });
93121
93181
  }
93122
93182
 
93123
93183
  /**
@@ -93218,7 +93278,7 @@ class EntityComponentDataset {
93218
93278
  const componentClass = this.componentTypeMap[componentIndex];
93219
93279
 
93220
93280
  //dispatch event to components
93221
- this.sendEvent(entityIndex, EventType.ComponentAdded, {klass: componentClass, instance: componentInstance});
93281
+ this.sendEvent(entityIndex, EventType.ComponentAdded, { klass: componentClass, instance: componentInstance });
93222
93282
  }
93223
93283
 
93224
93284
  /**
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.84.4",
8
+ "version": "2.84.5",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -49,3 +49,9 @@ export class AssetDescription {
49
49
  return `{ type: '${this.type}', path: '${this.path}' }`;
50
50
  }
51
51
  }
52
+
53
+ /**
54
+ * @readonly
55
+ * @type {boolean}
56
+ */
57
+ AssetDescription.prototype.isAssetDescription = true;
@@ -205,6 +205,8 @@ class Entity {
205
205
  * @returns {*|null}
206
206
  */
207
207
  removeComponent(klass) {
208
+ assert.defined(klass, 'klass');
209
+
208
210
  const elements = this.components;
209
211
  const n = elements.length;
210
212
 
@@ -332,6 +334,7 @@ class Entity {
332
334
  dataset.removeEntity(entity);
333
335
 
334
336
  this.id = -1;
337
+ this.generation = -1;
335
338
 
336
339
  this.clearFlag(EntityFlags.Built);
337
340
 
@@ -359,6 +362,7 @@ class Entity {
359
362
  }
360
363
 
361
364
  const entity = this.id = dataset.createEntity();
365
+ this.generation = dataset.getEntityGeneration(entity);
362
366
  this.dataset = dataset;
363
367
 
364
368
  let i;
@@ -416,6 +420,7 @@ class Entity {
416
420
  r.setFlag(EntityFlags.Built);
417
421
  r.id = entity;
418
422
  r.dataset = dataset;
423
+ r.generation = dataset.getEntityGeneration(entity);
419
424
 
420
425
  return r;
421
426
  }
@@ -1,13 +1,14 @@
1
- import {BitSet} from "../../core/binary/BitSet.js";
2
- import {assert} from "../../core/assert.js";
1
+ import { assert } from "../../core/assert.js";
2
+ import { BitSet } from "../../core/binary/BitSet.js";
3
+ import { array_shrink_to_size } from "../../core/collection/array/array_shrink_to_size.js";
4
+ import { arraySetDiff } from "../../core/collection/array/arraySetDiff.js";
3
5
  import Signal, {
4
6
  findSignalHandlerIndexByHandle,
5
7
  findSignalHandlerIndexByHandleAndContext
6
8
  } from "../../core/events/signal/Signal.js";
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";
9
+ import { SignalHandler } from "../../core/events/signal/SignalHandler.js";
10
+ import { max3 } from "../../core/math/max3.js";
11
+ import { EventType } from "./EntityManager.js";
11
12
 
12
13
  /**
13
14
  *
@@ -116,6 +117,15 @@ export class EntityComponentDataset {
116
117
  * @type {BitSet}
117
118
  */
118
119
  entityOccupancy = new BitSet();
120
+
121
+ /**
122
+ * For each entity ID records generation when entity was created
123
+ * Values are invalid for unused entity IDs
124
+ * @private
125
+ * @type {Uint32Array}
126
+ */
127
+ entityGeneration = new Uint32Array(0);
128
+
119
129
  /**
120
130
  * @private
121
131
  * @type {BitSet}
@@ -167,7 +177,7 @@ export class EntityComponentDataset {
167
177
 
168
178
  /**
169
179
  * @readonly
170
- * @type {Signal}
180
+ * @type {Signal<number>}
171
181
  */
172
182
  onEntityCreated = new Signal();
173
183
 
@@ -448,6 +458,7 @@ export class EntityComponentDataset {
448
458
  */
449
459
  setComponentTypeMap(map) {
450
460
  assert.defined(map, "map");
461
+ assert.isArray(map, 'map');
451
462
 
452
463
  const newComponentTypeCount = map.length;
453
464
 
@@ -726,38 +737,79 @@ export class EntityComponentDataset {
726
737
 
727
738
  /**
728
739
  *
729
- * @returns {number} entityIndex
740
+ * @param {number} min_size
730
741
  */
731
- createEntity() {
732
- const entityIndex = this.entityOccupancy.nextClearBit(0);
733
- this.entityOccupancy.set(entityIndex, true);
742
+ enlargeGenerationTable(min_size) {
743
+ const old_generation_table_size = this.entityGeneration.length;
734
744
 
735
- this.entityCount++;
745
+ const new_size = max3(
746
+ min_size,
747
+ Math.ceil(old_generation_table_size * 1.2),
748
+ old_generation_table_size + 16
749
+ );
736
750
 
737
- this.onEntityCreated.send1(entityIndex);
751
+ const new_generation_table = new Uint32Array(new_size);
738
752
 
739
- this.generation++;
753
+ new_generation_table.set(this.entityGeneration);
740
754
 
741
- return entityIndex;
755
+ this.entityGeneration = new_generation_table
742
756
  }
743
757
 
744
758
  /**
745
- *
746
- * @param {number} entityIndex
747
- * @throws {Error} if entity index is already in use
759
+ * Produces generation ID for a given entity
760
+ * @param {number} entity_id
761
+ * @returns {number}
762
+ */
763
+ getEntityGeneration(entity_id) {
764
+ return this.entityGeneration[entity_id];
765
+ }
766
+
767
+ /**
768
+ * @private
769
+ * @param {number} entity_id
748
770
  */
749
- createEntitySpecific(entityIndex) {
750
- if (this.entityExists(entityIndex)) {
751
- throw new Error(`EntityId ${entityIndex} is already in use`);
771
+ createEntityUnsafe(entity_id) {
772
+ this.entityOccupancy.set(entity_id, true);
773
+
774
+ // record entity generation
775
+ if (this.entityGeneration.length <= entity_id) {
776
+ // needs to be resized
777
+ this.enlargeGenerationTable(entity_id + 1);
752
778
  }
753
779
 
754
- this.entityOccupancy.set(entityIndex, true);
780
+ const current_generation = this.generation;
781
+ this.generation = current_generation + 1;
782
+
783
+ this.entityGeneration[entity_id] = current_generation;
755
784
 
756
785
  this.entityCount++;
757
786
 
758
- this.onEntityCreated.send1(entityIndex);
787
+ this.onEntityCreated.send1(entity_id);
788
+ }
789
+
790
+ /**
791
+ *
792
+ * @returns {number} entityIndex
793
+ */
794
+ createEntity() {
795
+ const entity_id = this.entityOccupancy.nextClearBit(0);
796
+
797
+ this.createEntityUnsafe(entity_id);
798
+
799
+ return entity_id;
800
+ }
801
+
802
+ /**
803
+ *
804
+ * @param {number} entity_id
805
+ * @throws {Error} if entity index is already in use
806
+ */
807
+ createEntitySpecific(entity_id) {
808
+ if (this.entityExists(entity_id)) {
809
+ throw new Error(`EntityId ${entity_id} is already in use`);
810
+ }
759
811
 
760
- this.generation++;
812
+ this.createEntityUnsafe(entity_id);
761
813
  }
762
814
 
763
815
  /**
@@ -887,7 +939,7 @@ export class EntityComponentDataset {
887
939
  const componentClass = this.componentTypeMap[componentIndex];
888
940
 
889
941
  //dispatch event to components
890
- this.sendEvent(entityIndex, EventType.ComponentRemoved, {klass: componentClass, instance: componentInstance});
942
+ this.sendEvent(entityIndex, EventType.ComponentRemoved, { klass: componentClass, instance: componentInstance });
891
943
  }
892
944
 
893
945
  /**
@@ -999,7 +1051,7 @@ export class EntityComponentDataset {
999
1051
  const componentClass = this.componentTypeMap[componentIndex];
1000
1052
 
1001
1053
  //dispatch event to components
1002
- this.sendEvent(entityIndex, EventType.ComponentAdded, {klass: componentClass, instance: componentInstance});
1054
+ this.sendEvent(entityIndex, EventType.ComponentAdded, { klass: componentClass, instance: componentInstance });
1003
1055
  }
1004
1056
 
1005
1057
  /**