@woosh/meep-engine 2.84.3 → 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.
- package/build/meep.cjs +163 -109
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +163 -109
- package/editor/view/ecs/EntityEditor.js +7 -8
- package/package.json +1 -1
- package/src/core/math/random/roundFair.js +5 -2
- package/src/core/math/random/roundFair.spec.js +12 -0
- package/src/core/math/random/seededRandom_Mulberry32.spec.js +19 -0
- package/src/core/model/node-graph/node/NodeInstancePortReference.spec.js +25 -2
- package/src/core/model/node-graph/node/Port.js +8 -6
- package/src/core/model/node-graph/node/Port.spec.js +49 -0
- package/src/core/process/matcher/and.js +16 -0
- package/src/core/process/matcher/isDefined.js +8 -0
- package/src/core/process/matcher/isEqualTo.js +10 -0
- package/src/core/process/matcher/isGreaterThan.js +10 -0
- package/src/core/process/matcher/isGreaterThanOrEqualTo.js +10 -0
- package/src/core/process/matcher/isInstanceOf.js +10 -0
- package/src/core/process/matcher/isLessThan.js +10 -0
- package/src/core/process/matcher/isLessThanOrEqualTo.js +10 -0
- package/src/core/process/matcher/isNull.js +8 -0
- package/src/core/process/matcher/isTypeOf.js +16 -0
- package/src/core/process/matcher/not.js +10 -0
- package/src/core/process/matcher/or.js +16 -0
- package/src/core/process/task/util/actionTask.spec.js +14 -0
- package/src/core/process/task/util/countTask.js +1 -1
- package/src/core/process/task/util/countTask.spec.js +18 -0
- package/src/engine/asset/AssetDescription.js +6 -0
- package/src/engine/ecs/Entity.js +9 -4
- package/src/engine/ecs/EntityComponentDataset.js +78 -26
- package/src/view/common/LabelView.js +3 -1
- package/src/view/elements/windrose/WindRoseDiagram.js +3 -3
- package/src/core/math/spline/spline_catmullrom_1d.js +0 -120
- package/src/core/process/IntervalExecutor.js +0 -78
- package/src/core/process/matcher/Matchers.js +0 -145
package/build/meep.module.js
CHANGED
|
@@ -63964,7 +63964,7 @@ Task.prototype.isTask = true;
|
|
|
63964
63964
|
/**
|
|
63965
63965
|
*
|
|
63966
63966
|
* @param {number|function(*):number} initial
|
|
63967
|
-
* @param {number|function(*):number} limit
|
|
63967
|
+
* @param {number|function(*):number} limit limit is excluded from the count, same as `for(;i < limit;)`
|
|
63968
63968
|
* @param {function(index:int)} callback
|
|
63969
63969
|
* @returns {Task}
|
|
63970
63970
|
*/
|
|
@@ -69662,6 +69662,36 @@ function array_remove_first(array, element, start_index = 0, length = array.leng
|
|
|
69662
69662
|
return false;
|
|
69663
69663
|
}
|
|
69664
69664
|
|
|
69665
|
+
/**
|
|
69666
|
+
*
|
|
69667
|
+
* @param {*} value
|
|
69668
|
+
* @return {boolean}
|
|
69669
|
+
*/
|
|
69670
|
+
function isDefined(value) {
|
|
69671
|
+
return value !== undefined;
|
|
69672
|
+
}
|
|
69673
|
+
|
|
69674
|
+
/**
|
|
69675
|
+
*
|
|
69676
|
+
* @enum
|
|
69677
|
+
*/
|
|
69678
|
+
const EntityFlags = {
|
|
69679
|
+
/**
|
|
69680
|
+
* Whether the entity is built, set internally
|
|
69681
|
+
*/
|
|
69682
|
+
Built: 1,
|
|
69683
|
+
/**
|
|
69684
|
+
* If component type is not registered on the {@link EntityComponentDataset} when calling {@link Entity#build} - will register the component first
|
|
69685
|
+
*/
|
|
69686
|
+
RegisterComponents: 2,
|
|
69687
|
+
/**
|
|
69688
|
+
* Entity builder will watch destruction of the entity (subscribe to event), this will make the {@link Entity} automatically
|
|
69689
|
+
* recognize when the corresponding entity is destroyed outside the {@link Entity} API
|
|
69690
|
+
* 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}
|
|
69691
|
+
*/
|
|
69692
|
+
WatchDestruction: 4
|
|
69693
|
+
};
|
|
69694
|
+
|
|
69665
69695
|
/**
|
|
69666
69696
|
* de Bruijn sequence
|
|
69667
69697
|
* @see https://graphics.stanford.edu/~seander/bithacks.html
|
|
@@ -72274,78 +72304,6 @@ class EntityManager {
|
|
|
72274
72304
|
}
|
|
72275
72305
|
}
|
|
72276
72306
|
|
|
72277
|
-
/**
|
|
72278
|
-
* @author Alex Goldring
|
|
72279
|
-
* @copyright Alex Goldring 2017
|
|
72280
|
-
*/
|
|
72281
|
-
|
|
72282
|
-
|
|
72283
|
-
/**
|
|
72284
|
-
*
|
|
72285
|
-
* @param {*} value
|
|
72286
|
-
* @return {boolean}
|
|
72287
|
-
*/
|
|
72288
|
-
function isDefined(value) {
|
|
72289
|
-
return value !== undefined;
|
|
72290
|
-
}
|
|
72291
|
-
|
|
72292
|
-
/**
|
|
72293
|
-
* performs instanceof match
|
|
72294
|
-
* @param {function} type
|
|
72295
|
-
* @returns {function(*): boolean}
|
|
72296
|
-
*/
|
|
72297
|
-
function isInstanceOf$1(type) {
|
|
72298
|
-
return function (m) {
|
|
72299
|
-
return m instanceof type;
|
|
72300
|
-
}
|
|
72301
|
-
}
|
|
72302
|
-
|
|
72303
|
-
/**
|
|
72304
|
-
* performs typeof match
|
|
72305
|
-
* @param {string} type
|
|
72306
|
-
* @returns {function(*): boolean}
|
|
72307
|
-
*/
|
|
72308
|
-
function isTypeOf(type) {
|
|
72309
|
-
|
|
72310
|
-
return function (m) {
|
|
72311
|
-
return typeof m === type;
|
|
72312
|
-
}
|
|
72313
|
-
}
|
|
72314
|
-
|
|
72315
|
-
/**
|
|
72316
|
-
* Joins two matchers via OR
|
|
72317
|
-
* @param {function(*):boolean} a
|
|
72318
|
-
* @param {function(*):boolean} b
|
|
72319
|
-
* @returns {function(*):boolean}
|
|
72320
|
-
*/
|
|
72321
|
-
function or(a, b) {
|
|
72322
|
-
|
|
72323
|
-
return function (m) {
|
|
72324
|
-
return a(m) || b(m);
|
|
72325
|
-
}
|
|
72326
|
-
}
|
|
72327
|
-
|
|
72328
|
-
/**
|
|
72329
|
-
*
|
|
72330
|
-
* @enum
|
|
72331
|
-
*/
|
|
72332
|
-
const EntityFlags = {
|
|
72333
|
-
/**
|
|
72334
|
-
* Whether the entity is built, set internally
|
|
72335
|
-
*/
|
|
72336
|
-
Built: 1,
|
|
72337
|
-
/**
|
|
72338
|
-
* If component type is not registered on the {@link EntityComponentDataset} when calling {@link Entity#build} - will register the component first
|
|
72339
|
-
*/
|
|
72340
|
-
RegisterComponents: 2,
|
|
72341
|
-
/**
|
|
72342
|
-
* Entity builder will watch destruction of the entity (subscribe to event), this will make the {@link Entity} automatically
|
|
72343
|
-
* recognize when the corresponding entity is destroyed outside the {@link Entity} API
|
|
72344
|
-
* 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}
|
|
72345
|
-
*/
|
|
72346
|
-
WatchDestruction: 4
|
|
72347
|
-
};
|
|
72348
|
-
|
|
72349
72307
|
/**
|
|
72350
72308
|
* Set of default flags
|
|
72351
72309
|
* @type {number}
|
|
@@ -72544,6 +72502,7 @@ class Entity {
|
|
|
72544
72502
|
* @returns {*|null}
|
|
72545
72503
|
*/
|
|
72546
72504
|
removeComponent(klass) {
|
|
72505
|
+
|
|
72547
72506
|
const elements = this.components;
|
|
72548
72507
|
const n = elements.length;
|
|
72549
72508
|
|
|
@@ -72669,6 +72628,7 @@ class Entity {
|
|
|
72669
72628
|
dataset.removeEntity(entity);
|
|
72670
72629
|
|
|
72671
72630
|
this.id = -1;
|
|
72631
|
+
this.generation = -1;
|
|
72672
72632
|
|
|
72673
72633
|
this.clearFlag(EntityFlags.Built);
|
|
72674
72634
|
|
|
@@ -72694,6 +72654,7 @@ class Entity {
|
|
|
72694
72654
|
}
|
|
72695
72655
|
|
|
72696
72656
|
const entity = this.id = dataset.createEntity();
|
|
72657
|
+
this.generation = dataset.getEntityGeneration(entity);
|
|
72697
72658
|
this.dataset = dataset;
|
|
72698
72659
|
|
|
72699
72660
|
let i;
|
|
@@ -72751,6 +72712,7 @@ class Entity {
|
|
|
72751
72712
|
r.setFlag(EntityFlags.Built);
|
|
72752
72713
|
r.id = entity;
|
|
72753
72714
|
r.dataset = dataset;
|
|
72715
|
+
r.generation = dataset.getEntityGeneration(entity);
|
|
72754
72716
|
|
|
72755
72717
|
return r;
|
|
72756
72718
|
}
|
|
@@ -84092,7 +84054,13 @@ class AssetDescription {
|
|
|
84092
84054
|
toString() {
|
|
84093
84055
|
return `{ type: '${this.type}', path: '${this.path}' }`;
|
|
84094
84056
|
}
|
|
84095
|
-
}
|
|
84057
|
+
}
|
|
84058
|
+
|
|
84059
|
+
/**
|
|
84060
|
+
* @readonly
|
|
84061
|
+
* @type {boolean}
|
|
84062
|
+
*/
|
|
84063
|
+
AssetDescription.prototype.isAssetDescription = true;
|
|
84096
84064
|
|
|
84097
84065
|
/**
|
|
84098
84066
|
* @enum {number}
|
|
@@ -89823,7 +89791,7 @@ class InputDeviceSwitch {
|
|
|
89823
89791
|
* @param klass
|
|
89824
89792
|
* @returns {boolean}
|
|
89825
89793
|
*/
|
|
89826
|
-
function isInstanceOf(thing, klass) {
|
|
89794
|
+
function isInstanceOf$1(thing, klass) {
|
|
89827
89795
|
if (klass === undefined) {
|
|
89828
89796
|
return false;
|
|
89829
89797
|
}
|
|
@@ -89844,12 +89812,12 @@ function isInstanceOf(thing, klass) {
|
|
|
89844
89812
|
* @param {Element} el
|
|
89845
89813
|
*/
|
|
89846
89814
|
function isFocusable(el) {
|
|
89847
|
-
return isInstanceOf(el, HTMLInputElement)
|
|
89848
|
-
|| isInstanceOf(el, HTMLSelectElement)
|
|
89849
|
-
|| isInstanceOf(el, HTMLTextAreaElement)
|
|
89850
|
-
|| isInstanceOf(el, HTMLAnchorElement)
|
|
89851
|
-
|| isInstanceOf(el, HTMLButtonElement)
|
|
89852
|
-
|| isInstanceOf(el, HTMLAreaElement)
|
|
89815
|
+
return isInstanceOf$1(el, HTMLInputElement)
|
|
89816
|
+
|| isInstanceOf$1(el, HTMLSelectElement)
|
|
89817
|
+
|| isInstanceOf$1(el, HTMLTextAreaElement)
|
|
89818
|
+
|| isInstanceOf$1(el, HTMLAnchorElement)
|
|
89819
|
+
|| isInstanceOf$1(el, HTMLButtonElement)
|
|
89820
|
+
|| isInstanceOf$1(el, HTMLAreaElement)
|
|
89853
89821
|
}
|
|
89854
89822
|
|
|
89855
89823
|
/**
|
|
@@ -92402,6 +92370,15 @@ class EntityComponentDataset {
|
|
|
92402
92370
|
* @type {BitSet}
|
|
92403
92371
|
*/
|
|
92404
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
|
+
|
|
92405
92382
|
/**
|
|
92406
92383
|
* @private
|
|
92407
92384
|
* @type {BitSet}
|
|
@@ -92453,7 +92430,7 @@ class EntityComponentDataset {
|
|
|
92453
92430
|
|
|
92454
92431
|
/**
|
|
92455
92432
|
* @readonly
|
|
92456
|
-
* @type {Signal}
|
|
92433
|
+
* @type {Signal<number>}
|
|
92457
92434
|
*/
|
|
92458
92435
|
onEntityCreated = new Signal();
|
|
92459
92436
|
|
|
@@ -93003,38 +92980,79 @@ class EntityComponentDataset {
|
|
|
93003
92980
|
|
|
93004
92981
|
/**
|
|
93005
92982
|
*
|
|
93006
|
-
* @
|
|
92983
|
+
* @param {number} min_size
|
|
93007
92984
|
*/
|
|
93008
|
-
|
|
93009
|
-
const
|
|
93010
|
-
this.entityOccupancy.set(entityIndex, true);
|
|
92985
|
+
enlargeGenerationTable(min_size) {
|
|
92986
|
+
const old_generation_table_size = this.entityGeneration.length;
|
|
93011
92987
|
|
|
93012
|
-
|
|
92988
|
+
const new_size = max3(
|
|
92989
|
+
min_size,
|
|
92990
|
+
Math.ceil(old_generation_table_size * 1.2),
|
|
92991
|
+
old_generation_table_size + 16
|
|
92992
|
+
);
|
|
93013
92993
|
|
|
93014
|
-
|
|
92994
|
+
const new_generation_table = new Uint32Array(new_size);
|
|
93015
92995
|
|
|
93016
|
-
this.
|
|
92996
|
+
new_generation_table.set(this.entityGeneration);
|
|
93017
92997
|
|
|
93018
|
-
|
|
92998
|
+
this.entityGeneration = new_generation_table;
|
|
93019
92999
|
}
|
|
93020
93000
|
|
|
93021
93001
|
/**
|
|
93022
|
-
*
|
|
93023
|
-
* @param {number}
|
|
93024
|
-
* @
|
|
93002
|
+
* Produces generation ID for a given entity
|
|
93003
|
+
* @param {number} entity_id
|
|
93004
|
+
* @returns {number}
|
|
93025
93005
|
*/
|
|
93026
|
-
|
|
93027
|
-
|
|
93028
|
-
|
|
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);
|
|
93029
93021
|
}
|
|
93030
93022
|
|
|
93031
|
-
this.
|
|
93023
|
+
const current_generation = this.generation;
|
|
93024
|
+
this.generation = current_generation + 1;
|
|
93025
|
+
|
|
93026
|
+
this.entityGeneration[entity_id] = current_generation;
|
|
93032
93027
|
|
|
93033
93028
|
this.entityCount++;
|
|
93034
93029
|
|
|
93035
|
-
this.onEntityCreated.send1(
|
|
93030
|
+
this.onEntityCreated.send1(entity_id);
|
|
93031
|
+
}
|
|
93036
93032
|
|
|
93037
|
-
|
|
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
|
+
}
|
|
93054
|
+
|
|
93055
|
+
this.createEntityUnsafe(entity_id);
|
|
93038
93056
|
}
|
|
93039
93057
|
|
|
93040
93058
|
/**
|
|
@@ -93159,7 +93177,7 @@ class EntityComponentDataset {
|
|
|
93159
93177
|
const componentClass = this.componentTypeMap[componentIndex];
|
|
93160
93178
|
|
|
93161
93179
|
//dispatch event to components
|
|
93162
|
-
this.sendEvent(entityIndex, EventType.ComponentRemoved, {klass: componentClass, instance: componentInstance});
|
|
93180
|
+
this.sendEvent(entityIndex, EventType.ComponentRemoved, { klass: componentClass, instance: componentInstance });
|
|
93163
93181
|
}
|
|
93164
93182
|
|
|
93165
93183
|
/**
|
|
@@ -93260,7 +93278,7 @@ class EntityComponentDataset {
|
|
|
93260
93278
|
const componentClass = this.componentTypeMap[componentIndex];
|
|
93261
93279
|
|
|
93262
93280
|
//dispatch event to components
|
|
93263
|
-
this.sendEvent(entityIndex, EventType.ComponentAdded, {klass: componentClass, instance: componentInstance});
|
|
93281
|
+
this.sendEvent(entityIndex, EventType.ComponentAdded, { klass: componentClass, instance: componentInstance });
|
|
93264
93282
|
}
|
|
93265
93283
|
|
|
93266
93284
|
/**
|
|
@@ -96121,6 +96139,42 @@ function number_pretty_print(value) {
|
|
|
96121
96139
|
|
|
96122
96140
|
}
|
|
96123
96141
|
|
|
96142
|
+
/**
|
|
96143
|
+
* performs instanceof match
|
|
96144
|
+
* @param {function} type
|
|
96145
|
+
* @returns {function(*): boolean}
|
|
96146
|
+
*/
|
|
96147
|
+
function isInstanceOf(type) {
|
|
96148
|
+
return function (m) {
|
|
96149
|
+
return m instanceof type;
|
|
96150
|
+
}
|
|
96151
|
+
}
|
|
96152
|
+
|
|
96153
|
+
/**
|
|
96154
|
+
* performs typeof match
|
|
96155
|
+
* @param {string} type
|
|
96156
|
+
* @returns {function(*): boolean}
|
|
96157
|
+
*/
|
|
96158
|
+
function isTypeOf(type) {
|
|
96159
|
+
|
|
96160
|
+
return function (m) {
|
|
96161
|
+
return typeof m === type;
|
|
96162
|
+
}
|
|
96163
|
+
}
|
|
96164
|
+
|
|
96165
|
+
/**
|
|
96166
|
+
* Joins two matchers via OR
|
|
96167
|
+
* @param {function(*):boolean} a
|
|
96168
|
+
* @param {function(*):boolean} b
|
|
96169
|
+
* @returns {function(*):boolean}
|
|
96170
|
+
*/
|
|
96171
|
+
function or(a, b) {
|
|
96172
|
+
|
|
96173
|
+
return function (m) {
|
|
96174
|
+
return a(m) || b(m);
|
|
96175
|
+
}
|
|
96176
|
+
}
|
|
96177
|
+
|
|
96124
96178
|
/**
|
|
96125
96179
|
* Created by Alex on 01/11/2014.
|
|
96126
96180
|
* @copyright Alex Goldring 2014
|
|
@@ -96269,14 +96323,14 @@ function p(m, e, f) {
|
|
|
96269
96323
|
* @type {Array.<ValueProcessor>}
|
|
96270
96324
|
*/
|
|
96271
96325
|
const processors = [
|
|
96272
|
-
p(isInstanceOf
|
|
96273
|
-
p(isInstanceOf
|
|
96274
|
-
p(isInstanceOf
|
|
96275
|
-
p(isInstanceOf
|
|
96276
|
-
p(isInstanceOf
|
|
96277
|
-
p(isInstanceOf
|
|
96278
|
-
p(isInstanceOf
|
|
96279
|
-
p(isInstanceOf
|
|
96326
|
+
p(isInstanceOf(ObservedBoolean), extractorGetValue, format),
|
|
96327
|
+
p(isInstanceOf(ObservedValue), extractorGetValue, format),
|
|
96328
|
+
p(isInstanceOf(ObservedString), extractorGetValue, format),
|
|
96329
|
+
p(isInstanceOf(LinearValue), extractorGetValue, formatNumber),
|
|
96330
|
+
p(isInstanceOf(BoundedValue), extractBoundedValue, formatArray),
|
|
96331
|
+
p(isInstanceOf(Stat), extractorGetValue, formatNumber),
|
|
96332
|
+
p(isInstanceOf(Vector1), extractorGetValue, formatNumber),
|
|
96333
|
+
p(isInstanceOf(ObservedInteger), extractorGetValue, formatNumber),
|
|
96280
96334
|
p(or(isTypedArray, Array.isArray), arrayUnwrap, formatArray),
|
|
96281
96335
|
p(isTypeOf("number"), passThrough, formatNumber),
|
|
96282
96336
|
p(isTypeOf("string"), passThrough, passThrough),
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Created by Alex on 15/01/2017.
|
|
3
3
|
*/
|
|
4
|
-
import View from "../../../src/view/View.js";
|
|
5
|
-
import dom from "../../../src/view/DOM.js";
|
|
6
|
-
|
|
7
4
|
import List from '../../../src/core/collection/list/List.js';
|
|
8
5
|
import ObservedValue from '../../../src/core/model/ObservedValue.js';
|
|
6
|
+
import { isDefined } from "../../../src/core/process/matcher/isDefined.js";
|
|
7
|
+
import { EntityManager, EventType } from "../../../src/engine/ecs/EntityManager.js";
|
|
9
8
|
import LabelView from '../../../src/view/common/LabelView.js';
|
|
9
|
+
import dom from "../../../src/view/DOM.js";
|
|
10
10
|
import ButtonView from '../../../src/view/elements/button/ButtonView.js';
|
|
11
11
|
import DropDownSelectionView from '../../../src/view/elements/DropDownSelectionView.js';
|
|
12
12
|
import EmptyView from "../../../src/view/elements/EmptyView.js";
|
|
13
|
-
import
|
|
14
|
-
import ComponentRemoveAction from "../../actions/concrete/ComponentRemoveAction.js";
|
|
13
|
+
import View from "../../../src/view/View.js";
|
|
15
14
|
import ComponentAddAction from "../../actions/concrete/ComponentAddAction.js";
|
|
16
|
-
import
|
|
17
|
-
import { ComponentControlView } from "./ComponentControlView.js";
|
|
15
|
+
import ComponentRemoveAction from "../../actions/concrete/ComponentRemoveAction.js";
|
|
18
16
|
import { buildObjectEditorFromRegistry } from "../../ecs/component/createObjectEditor.js";
|
|
19
|
-
import {
|
|
17
|
+
import { ComponentControlView } from "./ComponentControlView.js";
|
|
18
|
+
import { LineView } from "./components/common/LineView.js";
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class EntityEditor extends View {
|
package/package.json
CHANGED
|
@@ -5,11 +5,14 @@
|
|
|
5
5
|
* @returns {int}
|
|
6
6
|
*/
|
|
7
7
|
export function roundFair(number, random) {
|
|
8
|
+
|
|
8
9
|
const mantissa = number % 1;
|
|
9
10
|
const roll = random();
|
|
11
|
+
|
|
10
12
|
if (roll < mantissa) {
|
|
11
|
-
return Math.ceil(number);
|
|
12
|
-
} else {
|
|
13
13
|
return Math.floor(number);
|
|
14
|
+
} else {
|
|
15
|
+
return Math.ceil(number);
|
|
14
16
|
}
|
|
17
|
+
|
|
15
18
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { roundFair } from "./roundFair.js";
|
|
2
|
+
|
|
3
|
+
test("basics", () => {
|
|
4
|
+
|
|
5
|
+
expect(roundFair(0.3, () => 0)).toEqual(0);
|
|
6
|
+
expect(roundFair(0.3, () => 0.1)).toEqual(0);
|
|
7
|
+
expect(roundFair(0.3, () => 0.299)).toEqual(0);
|
|
8
|
+
expect(roundFair(0.3, () => 0.31)).toEqual(1);
|
|
9
|
+
expect(roundFair(0.3, () => 0.9)).toEqual(1);
|
|
10
|
+
expect(roundFair(0.3, () => 1)).toEqual(1);
|
|
11
|
+
|
|
12
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { seededRandom_Mulberry32 } from "./seededRandom_Mulberry32.js";
|
|
2
|
+
|
|
3
|
+
test("predictable sequence", () => {
|
|
4
|
+
|
|
5
|
+
const random = seededRandom_Mulberry32(1337);
|
|
6
|
+
|
|
7
|
+
const seq_a = new Array(29).map(random);
|
|
8
|
+
|
|
9
|
+
const seed_a = random.getCurrentSeed();
|
|
10
|
+
|
|
11
|
+
random.setCurrentSeed(1337);
|
|
12
|
+
|
|
13
|
+
const seq_b = new Array(29).map(random);
|
|
14
|
+
|
|
15
|
+
const seed_b = random.getCurrentSeed();
|
|
16
|
+
|
|
17
|
+
expect(seq_b).toEqual(seq_a);
|
|
18
|
+
expect(seed_a).toEqual(seed_b);
|
|
19
|
+
});
|
|
@@ -49,8 +49,12 @@ test("incoming connections", () => {
|
|
|
49
49
|
expect(port_b_ref.inConnections).toEqual([connection]);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
test("hash", () => {
|
|
53
52
|
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @returns {NodeInstancePortReference}
|
|
56
|
+
*/
|
|
57
|
+
function sample_a() {
|
|
54
58
|
const nd = new NodeDescription();
|
|
55
59
|
const port_a_id = nd.createPort(DUMMY_TYPE, "a", PortDirection.Out);
|
|
56
60
|
|
|
@@ -58,9 +62,28 @@ test("hash", () => {
|
|
|
58
62
|
const graph = new NodeGraph();
|
|
59
63
|
const node_instance_id = graph.createNode(nd);
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
return graph.getConnectionEndpoint(node_instance_id, port_a_id);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
test("hash", () => {
|
|
69
|
+
const port_a_ref = sample_a();
|
|
62
70
|
|
|
63
71
|
expect(port_a_ref.hash()).toEqual(port_a_ref.hash());
|
|
64
72
|
expect(typeof port_a_ref.hash()).toBe("number");
|
|
65
73
|
expect(Number.isInteger(port_a_ref.hash())).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("toString", () => {
|
|
77
|
+
|
|
78
|
+
const s = sample_a().toString();
|
|
79
|
+
|
|
80
|
+
expect(typeof s).toEqual("string");
|
|
81
|
+
expect(s.length).toBeGreaterThan(0);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("self equality", () => {
|
|
85
|
+
|
|
86
|
+
const ref = sample_a();
|
|
87
|
+
|
|
88
|
+
expect(ref.equals(ref)).toBe(true);
|
|
66
89
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {assert} from "../../../assert.js";
|
|
2
|
-
import {computeHashIntegerArray} from "../../../collection/array/computeHashIntegerArray.js";
|
|
3
|
-
import {computeStringHash} from "../../../primitives/strings/computeStringHash.js";
|
|
4
|
-
import {objectKeyByValue} from "../../object/objectKeyByValue.js";
|
|
5
|
-
import {DataType} from "../DataType.js";
|
|
6
|
-
import {PortDirection} from "./PortDirection.js";
|
|
1
|
+
import { assert } from "../../../assert.js";
|
|
2
|
+
import { computeHashIntegerArray } from "../../../collection/array/computeHashIntegerArray.js";
|
|
3
|
+
import { computeStringHash } from "../../../primitives/strings/computeStringHash.js";
|
|
4
|
+
import { objectKeyByValue } from "../../object/objectKeyByValue.js";
|
|
5
|
+
import { DataType } from "../DataType.js";
|
|
6
|
+
import { PortDirection } from "./PortDirection.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @type {number}
|
|
@@ -94,6 +94,8 @@ export class Port {
|
|
|
94
94
|
id, name, direction, dataType
|
|
95
95
|
}, registry) {
|
|
96
96
|
|
|
97
|
+
assert.isNonNegativeInteger(id, 'id');
|
|
98
|
+
|
|
97
99
|
this.id = id;
|
|
98
100
|
this.name = name;
|
|
99
101
|
this.direction = PortDirection[direction];
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { DataType } from "../DataType.js";
|
|
2
|
+
import { NodeRegistry } from "./NodeRegistry.js";
|
|
1
3
|
import { Port } from "./Port.js";
|
|
4
|
+
import { PortDirection } from "./PortDirection.js";
|
|
2
5
|
|
|
3
6
|
test("constructor does not throw", () => {
|
|
4
7
|
expect(() => new Port()).not.toThrow();
|
|
@@ -51,3 +54,49 @@ test("toString on newly crated instance produces a valid string", () => {
|
|
|
51
54
|
expect(typeof s).toBe('string');
|
|
52
55
|
expect(s.trim().length).toBeGreaterThan(0); // non-empty
|
|
53
56
|
});
|
|
57
|
+
|
|
58
|
+
test("fromJSON", () => {
|
|
59
|
+
|
|
60
|
+
const registry = new NodeRegistry();
|
|
61
|
+
|
|
62
|
+
registry.addType(DataType.from(7, "t"));
|
|
63
|
+
|
|
64
|
+
const port = new Port();
|
|
65
|
+
|
|
66
|
+
port.fromJSON({
|
|
67
|
+
id: 3,
|
|
68
|
+
name: "x",
|
|
69
|
+
direction: "In",
|
|
70
|
+
dataType: {
|
|
71
|
+
id: 7,
|
|
72
|
+
name: "t"
|
|
73
|
+
}
|
|
74
|
+
}, registry);
|
|
75
|
+
|
|
76
|
+
expect(port.id).toEqual(3);
|
|
77
|
+
expect(port.name).toEqual("x");
|
|
78
|
+
expect(port.direction).toEqual(PortDirection.In);
|
|
79
|
+
expect(port.dataType.id).toEqual(7);
|
|
80
|
+
expect(port.dataType.name).toEqual("t");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("toJSON", () => {
|
|
84
|
+
|
|
85
|
+
const port = new Port();
|
|
86
|
+
|
|
87
|
+
port.id = 3;
|
|
88
|
+
port.name = "x";
|
|
89
|
+
port.direction = PortDirection.Out;
|
|
90
|
+
port.dataType = DataType.from(7, "t");
|
|
91
|
+
|
|
92
|
+
expect(port.toJSON()).toEqual({
|
|
93
|
+
id: 3,
|
|
94
|
+
name: "x",
|
|
95
|
+
direction: "Out",
|
|
96
|
+
dataType: {
|
|
97
|
+
id: 7,
|
|
98
|
+
name: "t"
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { assert } from "../../assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Joins two matchers via AND
|
|
5
|
+
* @param {function(*):boolean} a
|
|
6
|
+
* @param {function(*):boolean} b
|
|
7
|
+
* @returns {function(*):boolean}
|
|
8
|
+
*/
|
|
9
|
+
export function and(a, b) {
|
|
10
|
+
assert.isFunction(a, 'a');
|
|
11
|
+
assert.isFunction(b, 'b');
|
|
12
|
+
|
|
13
|
+
return function (m) {
|
|
14
|
+
return a(m) && b(m);
|
|
15
|
+
}
|
|
16
|
+
}
|