@woosh/meep-engine 2.84.4 → 2.84.6
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 +111 -51
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +111 -51
- package/package.json +1 -1
- package/src/core/collection/list/List.js +1 -1
- package/src/core/primitives/numbers/number_count_decimals.js +30 -0
- package/src/core/primitives/numbers/number_pretty_print.js +7 -29
- package/src/core/primitives/strings/string_format_camel_to_kebab.js +2 -0
- package/src/core/primitives/strings/string_strip_trailing.js +22 -0
- package/src/core/primitives/strings/string_strip_trailing.spec.js +27 -0
- package/src/engine/asset/AssetDescription.js +6 -0
- package/src/engine/ecs/Entity.js +5 -0
- package/src/engine/ecs/EntityComponentDataset.js +78 -26
- package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +8 -1
package/build/meep.module.js
CHANGED
|
@@ -61269,7 +61269,7 @@ class List {
|
|
|
61269
61269
|
this.data.push(el);
|
|
61270
61270
|
const oldLength = this.length;
|
|
61271
61271
|
|
|
61272
|
-
this.length
|
|
61272
|
+
this.length = oldLength + 1;
|
|
61273
61273
|
|
|
61274
61274
|
this.on.added.send2(el, oldLength);
|
|
61275
61275
|
return this;
|
|
@@ -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
|
-
* @
|
|
92983
|
+
* @param {number} min_size
|
|
92965
92984
|
*/
|
|
92966
|
-
|
|
92967
|
-
const
|
|
92968
|
-
this.entityOccupancy.set(entityIndex, true);
|
|
92985
|
+
enlargeGenerationTable(min_size) {
|
|
92986
|
+
const old_generation_table_size = this.entityGeneration.length;
|
|
92969
92987
|
|
|
92970
|
-
|
|
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
|
-
|
|
92994
|
+
const new_generation_table = new Uint32Array(new_size);
|
|
92973
92995
|
|
|
92974
|
-
this.
|
|
92996
|
+
new_generation_table.set(this.entityGeneration);
|
|
92975
92997
|
|
|
92976
|
-
|
|
92998
|
+
this.entityGeneration = new_generation_table;
|
|
92977
92999
|
}
|
|
92978
93000
|
|
|
92979
93001
|
/**
|
|
92980
|
-
*
|
|
92981
|
-
* @param {number}
|
|
92982
|
-
* @
|
|
93002
|
+
* Produces generation ID for a given entity
|
|
93003
|
+
* @param {number} entity_id
|
|
93004
|
+
* @returns {number}
|
|
93005
|
+
*/
|
|
93006
|
+
getEntityGeneration(entity_id) {
|
|
93007
|
+
return this.entityGeneration[entity_id];
|
|
93008
|
+
}
|
|
93009
|
+
|
|
93010
|
+
/**
|
|
93011
|
+
* @private
|
|
93012
|
+
* @param {number} entity_id
|
|
92983
93013
|
*/
|
|
92984
|
-
|
|
92985
|
-
|
|
92986
|
-
|
|
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.
|
|
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(
|
|
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);
|
|
92994
93039
|
|
|
92995
|
-
this.
|
|
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
|
+
}
|
|
93054
|
+
|
|
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
|
/**
|
|
@@ -96024,40 +96084,38 @@ LinearValue.prototype.fromJSON = function (json) {
|
|
|
96024
96084
|
|
|
96025
96085
|
/**
|
|
96026
96086
|
*
|
|
96027
|
-
* @param {
|
|
96028
|
-
* @param {string}
|
|
96087
|
+
* @param {string} string
|
|
96088
|
+
* @param {string} trailing_sequence
|
|
96029
96089
|
* @returns {string}
|
|
96030
96090
|
*/
|
|
96031
|
-
function
|
|
96091
|
+
function string_strip_trailing(string, trailing_sequence) {
|
|
96092
|
+
const trailing_sequence_length = trailing_sequence.length;
|
|
96032
96093
|
|
|
96033
|
-
|
|
96094
|
+
if (trailing_sequence_length <= 0) {
|
|
96095
|
+
// special case to avoid infinite looping
|
|
96096
|
+
return string;
|
|
96097
|
+
}
|
|
96098
|
+
|
|
96099
|
+
let end_index = string.length;
|
|
96100
|
+
|
|
96101
|
+
while (string.substring(end_index - trailing_sequence_length, end_index) === trailing_sequence) {
|
|
96102
|
+
end_index -= trailing_sequence_length;
|
|
96103
|
+
}
|
|
96104
|
+
|
|
96105
|
+
return string.substring(0, end_index);
|
|
96034
96106
|
}
|
|
96035
96107
|
|
|
96036
96108
|
/**
|
|
96037
96109
|
*
|
|
96038
|
-
* @param {
|
|
96039
|
-
* @
|
|
96110
|
+
* @param {number} x
|
|
96111
|
+
* @param {string} [separator=',']
|
|
96112
|
+
* @returns {string}
|
|
96040
96113
|
*/
|
|
96041
|
-
function
|
|
96042
|
-
if (value % 1 === 0) {
|
|
96043
|
-
//whole number
|
|
96044
|
-
return 0;
|
|
96045
|
-
}
|
|
96046
|
-
const s = value.toString();
|
|
96047
|
-
const index = s.indexOf('.');
|
|
96048
|
-
|
|
96049
|
-
if (index === -1) {
|
|
96050
|
-
return 0;
|
|
96051
|
-
}
|
|
96052
|
-
|
|
96053
|
-
//find last 0
|
|
96054
|
-
let endIndex = s.length - 1;
|
|
96055
|
-
for (; endIndex > index && s.charAt(endIndex) === "0"; endIndex--) {
|
|
96056
|
-
|
|
96057
|
-
}
|
|
96058
|
-
return endIndex - index;
|
|
96059
|
-
}
|
|
96114
|
+
function number_format_by_thousands(x, separator = ',') {
|
|
96060
96115
|
|
|
96116
|
+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
|
96117
|
+
}
|
|
96118
|
+
|
|
96061
96119
|
/**
|
|
96062
96120
|
*
|
|
96063
96121
|
* @param {number} value
|
|
@@ -96068,10 +96126,12 @@ function number_pretty_print(value) {
|
|
|
96068
96126
|
const MAX_DECIMALS = 2;
|
|
96069
96127
|
|
|
96070
96128
|
const fraction = value % 1;
|
|
96071
|
-
|
|
96072
|
-
|
|
96073
|
-
|
|
96074
|
-
|
|
96129
|
+
|
|
96130
|
+
const would_produce_decimals = fraction * Math.pow(10, MAX_DECIMALS) > 0;
|
|
96131
|
+
|
|
96132
|
+
if (would_produce_decimals && Math.abs(value) < 100) {
|
|
96133
|
+
const truncated = value.toFixed(MAX_DECIMALS);
|
|
96134
|
+
return string_strip_trailing(truncated, "0");
|
|
96075
96135
|
} else {
|
|
96076
96136
|
//no fraction
|
|
96077
96137
|
return number_format_by_thousands(value - fraction, ",");
|
package/package.json
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number} value
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export function number_count_decimals(value) {
|
|
9
|
+
assert.isNumber(value, 'value');
|
|
10
|
+
|
|
11
|
+
if (value % 1 === 0) {
|
|
12
|
+
//whole number
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const s = value.toString();
|
|
17
|
+
const index = s.indexOf('.');
|
|
18
|
+
|
|
19
|
+
if (index === -1) {
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//find last 0
|
|
24
|
+
let endIndex = s.length - 1;
|
|
25
|
+
for (; endIndex > index && s.charAt(endIndex) === "0"; endIndex--) {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return endIndex - index;
|
|
30
|
+
}
|
|
@@ -1,31 +1,7 @@
|
|
|
1
1
|
import { assert } from "../../assert.js";
|
|
2
|
+
import { string_strip_trailing } from "../strings/string_strip_trailing.js";
|
|
2
3
|
import { number_format_by_thousands } from "./number_format_by_thousands.js";
|
|
3
4
|
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* @param {string} value
|
|
7
|
-
* @returns {number}
|
|
8
|
-
*/
|
|
9
|
-
function countDecimals(value) {
|
|
10
|
-
if (value % 1 === 0) {
|
|
11
|
-
//whole number
|
|
12
|
-
return 0;
|
|
13
|
-
}
|
|
14
|
-
const s = value.toString();
|
|
15
|
-
const index = s.indexOf('.');
|
|
16
|
-
|
|
17
|
-
if (index === -1) {
|
|
18
|
-
return 0;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
//find last 0
|
|
22
|
-
let endIndex = s.length - 1;
|
|
23
|
-
for (; endIndex > index && s.charAt(endIndex) === "0"; endIndex--) {
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
return endIndex - index;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
5
|
/**
|
|
30
6
|
*
|
|
31
7
|
* @param {number} value
|
|
@@ -37,10 +13,12 @@ export function number_pretty_print(value) {
|
|
|
37
13
|
const MAX_DECIMALS = 2;
|
|
38
14
|
|
|
39
15
|
const fraction = value % 1;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
16
|
+
|
|
17
|
+
const would_produce_decimals = fraction * Math.pow(10, MAX_DECIMALS) > 0;
|
|
18
|
+
|
|
19
|
+
if (would_produce_decimals && Math.abs(value) < 100) {
|
|
20
|
+
const truncated = value.toFixed(MAX_DECIMALS);
|
|
21
|
+
return string_strip_trailing(truncated, "0");
|
|
44
22
|
} else {
|
|
45
23
|
//no fraction
|
|
46
24
|
return number_format_by_thousands(value - fraction, ",");
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {string} string
|
|
4
|
+
* @param {string} trailing_sequence
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
7
|
+
export function string_strip_trailing(string, trailing_sequence) {
|
|
8
|
+
const trailing_sequence_length = trailing_sequence.length;
|
|
9
|
+
|
|
10
|
+
if (trailing_sequence_length <= 0) {
|
|
11
|
+
// special case to avoid infinite looping
|
|
12
|
+
return string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let end_index = string.length;
|
|
16
|
+
|
|
17
|
+
while (string.substring(end_index - trailing_sequence_length, end_index) === trailing_sequence) {
|
|
18
|
+
end_index -= trailing_sequence_length;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return string.substring(0, end_index);
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { string_strip_trailing } from "./string_strip_trailing.js";
|
|
2
|
+
|
|
3
|
+
test("strip empty from empty", () => {
|
|
4
|
+
expect(
|
|
5
|
+
string_strip_trailing("", "")
|
|
6
|
+
).toBe("");
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("strip repeating 2 character sequence", () => {
|
|
10
|
+
|
|
11
|
+
expect(
|
|
12
|
+
string_strip_trailing("Cabab", "ab")
|
|
13
|
+
).toBe("C");
|
|
14
|
+
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("mistakes", () => {
|
|
18
|
+
|
|
19
|
+
expect(
|
|
20
|
+
string_strip_trailing("food", "o")
|
|
21
|
+
).toBe("food");
|
|
22
|
+
|
|
23
|
+
expect(
|
|
24
|
+
string_strip_trailing("food", "f")
|
|
25
|
+
).toBe("food");
|
|
26
|
+
|
|
27
|
+
});
|
package/src/engine/ecs/Entity.js
CHANGED
|
@@ -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 {
|
|
2
|
-
import {
|
|
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 {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
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
|
-
* @
|
|
740
|
+
* @param {number} min_size
|
|
730
741
|
*/
|
|
731
|
-
|
|
732
|
-
const
|
|
733
|
-
this.entityOccupancy.set(entityIndex, true);
|
|
742
|
+
enlargeGenerationTable(min_size) {
|
|
743
|
+
const old_generation_table_size = this.entityGeneration.length;
|
|
734
744
|
|
|
735
|
-
|
|
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
|
-
|
|
751
|
+
const new_generation_table = new Uint32Array(new_size);
|
|
738
752
|
|
|
739
|
-
this.
|
|
753
|
+
new_generation_table.set(this.entityGeneration);
|
|
740
754
|
|
|
741
|
-
|
|
755
|
+
this.entityGeneration = new_generation_table
|
|
742
756
|
}
|
|
743
757
|
|
|
744
758
|
/**
|
|
745
|
-
*
|
|
746
|
-
* @param {number}
|
|
747
|
-
* @
|
|
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
|
-
|
|
750
|
-
|
|
751
|
-
|
|
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.
|
|
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(
|
|
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.
|
|
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
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import { number_pretty_print } from "../../../core/primitives/numbers/number_pretty_print.js";
|
|
2
3
|
import Task from "../../../core/process/task/Task.js";
|
|
3
4
|
import { TaskSignal } from "../../../core/process/task/TaskSignal.js";
|
|
4
5
|
import { emptyTask } from "../../../core/process/task/util/emptyTask.js";
|
|
@@ -24,6 +25,7 @@ class BinaryBufferDeSerializer {
|
|
|
24
25
|
assert.notEqual(engine, undefined, 'engine is undefined');
|
|
25
26
|
assert.notEqual(dataset, undefined, 'dataset is undefined');
|
|
26
27
|
|
|
28
|
+
const entity_count_before = dataset.entityCount;
|
|
27
29
|
|
|
28
30
|
const version = buffer.readUint16();
|
|
29
31
|
const numSerializedTypes = buffer.readUint16();
|
|
@@ -37,7 +39,12 @@ class BinaryBufferDeSerializer {
|
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
task.on.completed.add(function () {
|
|
40
|
-
|
|
42
|
+
const entity_count_after = dataset.entityCount;
|
|
43
|
+
|
|
44
|
+
const execution_time = task.getExecutedCpuTime();
|
|
45
|
+
const entity_count = entity_count_after - entity_count_before;
|
|
46
|
+
|
|
47
|
+
console.log(`Binary Buffer De-Serialization took ${number_pretty_print(execution_time)}ms. ${entity_count} Entities`);
|
|
41
48
|
});
|
|
42
49
|
|
|
43
50
|
return task;
|