@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.
Files changed (64) hide show
  1. package/build/meep.cjs +538 -518
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +538 -518
  4. package/editor/process/symbolic/SymbolicDisplayInternalAPI.js +3 -3
  5. package/editor/process/symbolic/makeParticleEmitterSymbolicDisplay.js +1 -1
  6. package/editor/process/symbolic/makePathSymbolicDisplay.js +1 -1
  7. package/editor/process/symbolic/makeSoundEmitterSymbolicDisplay.js +1 -1
  8. package/editor/tools/TopDownCameraControlTool.js +2 -2
  9. package/editor/tools/v2/TransformControls.js +1 -1
  10. package/editor/tools/v2/prototypeTransformControls.js +1 -1
  11. package/package.json +1 -1
  12. package/samples/generation/main.js +1 -1
  13. package/samples/terrain/editor.js +1 -1
  14. package/src/core/collection/array/arraySetDiff.js +11 -7
  15. package/src/core/geom/3d/aabb/aabb3_array_intersects_point.spec.js +48 -0
  16. package/src/core/geom/3d/aabb/aabb3_array_intersects_ray.js +5 -1
  17. package/src/core/geom/3d/aabb/aabb3_expand_array.spec.js +16 -0
  18. package/src/core/geom/3d/aabb/aabb3_raycast.spec.js +37 -0
  19. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.js +11 -12
  20. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.spec.js +14 -0
  21. package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +6 -4
  22. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +6 -3
  23. package/src/core/geom/3d/matrix/m4_multiply.spec.js +24 -0
  24. package/src/core/geom/3d/matrix/m4_multiply_alphatensor.js +56 -40
  25. package/src/core/geom/3d/matrix/m4_multiply_alphatensor.spec.js +24 -0
  26. package/src/core/geom/3d/shape/util/shape_to_visual_entity.js +2 -2
  27. package/src/core/geom/Vector3.spec.js +24 -14
  28. package/src/engine/EngineHarness.js +1 -1
  29. package/src/engine/control/ControlContext.js +1 -1
  30. package/src/engine/ecs/Entity.d.ts +2 -0
  31. package/src/engine/ecs/Entity.js +40 -37
  32. package/src/engine/ecs/Entity.spec.js +2 -2
  33. package/src/engine/ecs/EntityBuilderUtils.js +2 -2
  34. package/src/engine/ecs/EntityComponentDataset.js +91 -89
  35. package/src/engine/ecs/EntityFlags.js +4 -4
  36. package/src/engine/ecs/attachment/Attachment.js +5 -2
  37. package/src/engine/ecs/binding/ComponentPropertyBinding.js +13 -13
  38. package/src/engine/ecs/dynamic_actions/RuleExecution.js +1 -1
  39. package/src/engine/ecs/parent/EntityNode.js +2 -2
  40. package/src/engine/ecs/parent/EntityNode.spec.js +2 -2
  41. package/src/engine/ecs/tooltip/testTooltipComponentSystem.js +1 -1
  42. package/src/engine/ecs/util/hideEntityGracefully.js +6 -6
  43. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +1 -0
  44. package/src/engine/graphics/ecs/mesh-v2/render/SGThreeObjectCache.js +30 -7
  45. package/src/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +1 -1
  46. package/src/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +71 -34
  47. package/src/engine/graphics/ecs/mesh-v2/sample/prototype_sg_raycast.js +1 -1
  48. package/src/engine/graphics/ecs/path/PathDisplaySystem.js +4 -4
  49. package/src/engine/graphics/ecs/path/entity/EntityPathMarker.js +1 -1
  50. package/src/engine/graphics/ecs/path/highlight/PathDisplayHighlightSystem.js +3 -3
  51. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +5 -5
  52. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +2 -2
  53. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
  54. package/src/engine/graphics/sh3/prototypeSH3Probe.js +2 -2
  55. package/src/engine/intelligence/behavior/ecs/EntityBehavior.js +14 -17
  56. package/src/engine/intelligence/behavior/util/DelayBehavior.js +6 -6
  57. package/src/engine/ui/GUIEngine.js +368 -371
  58. package/src/engine/ui/notification/NotificationManager.js +1 -1
  59. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.js +1 -1
  60. package/src/view/tooltip/gml/TooltipParser.js +21 -28
  61. package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.js +3 -2
  62. package/src/core/geom/3d/aabb/aabb3_intersects_ray_branchless.js +0 -52
  63. package/src/core/geom/3d/aabb/aabb3_intersects_ray_fast.js +0 -176
  64. package/src/core/geom/3d/aabb/aabb3_intersects_ray_slab.js +0 -91
package/build/meep.cjs CHANGED
@@ -61968,34 +61968,38 @@ function arrayIndexByEquality(array, element, equals) {
61968
61968
  }
61969
61969
 
61970
61970
  /**
61971
+ * Compute a diff between two arrays, result is a 3 way split between common items, unique items in `a` array and unique items in `b` array
61971
61972
  * @template T
61972
61973
  * @param {T[]} a
61973
61974
  * @param {T[]} b
61974
- * @param {function(a:T,b:T):boolean} [equals]
61975
+ * @param {function(a:T,b:T):boolean} [equals] method to determine equality between two elements
61975
61976
  * @returns {{uniqueA:T[], uniqueB:T[], common:T[]}}
61976
61977
  */
61977
61978
  function arraySetDiff(a, b, equals = strictEquals) {
61979
+ // TODO we can do this faster if we use a comparator instead of equality and pre-sort the data
61978
61980
  const uniqueA = a.slice();
61979
61981
  const uniqueB = b.slice();
61980
61982
 
61981
61983
  const common = [];
61982
61984
 
61983
- let lA = uniqueA.length;
61985
+ let a_length = uniqueA.length;
61984
61986
 
61985
- let i;
61986
- for (i = 0; i < lA; i++) {
61987
+ for (let i = 0; i < a_length; i++) {
61987
61988
  const elA = uniqueA[i];
61988
61989
 
61989
61990
  const j = arrayIndexByEquality(uniqueB, elA, equals);
61990
61991
 
61991
61992
  if (j !== -1) {
61993
+ // common element found
61994
+
61992
61995
  common.push(elA);
61993
61996
 
61997
+ // remove from respective unique sets
61994
61998
  uniqueA.splice(i, 1);
61995
61999
  uniqueB.splice(j, 1);
61996
62000
 
61997
62001
  i--;
61998
- lA--;
62002
+ a_length--;
61999
62003
  }
62000
62004
  }
62001
62005
 
@@ -68730,6 +68734,7 @@ const scratch_ray_0$1 = new Float32Array(6);
68730
68734
 
68731
68735
  /**
68732
68736
  * Represents a primitive 3d object, a combination of a material and geometry
68737
+ * This is roughly equivalent to single draw call, note that his is not a hierarchical data structure, if you want that - you will need to combine multiple entities, each with a `ShadedGeometry` component
68733
68738
  */
68734
68739
  class ShadedGeometry {
68735
68740
  constructor() {
@@ -74618,13 +74623,13 @@ const EntityFlags = {
74618
74623
  */
74619
74624
  Built: 1,
74620
74625
  /**
74621
- * If component type is not registered on the {@link EntityComponentDataset} when calling {@link EntityBuilder#build} - will register the component first
74626
+ * If component type is not registered on the {@link EntityComponentDataset} when calling {@link Entity#build} - will register the component first
74622
74627
  */
74623
74628
  RegisterComponents: 2,
74624
74629
  /**
74625
- * Entity builder will watch destruction of the entity (subscribe to event), this will make the {@link EntityBuilder} automatically
74626
- * recognize when the corresponding entity is destroyed outside the EntityBuilder API
74627
- * 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 EntityBuilder
74630
+ * Entity builder will watch destruction of the entity (subscribe to event), this will make the {@link Entity} automatically
74631
+ * recognize when the corresponding entity is destroyed outside the {@link Entity} API
74632
+ * 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}
74628
74633
  */
74629
74634
  WatchDestruction: 4
74630
74635
  };
@@ -74645,9 +74650,10 @@ const DEFAULT_FLAGS$3 =
74645
74650
  class Entity {
74646
74651
 
74647
74652
  /**
74653
+ * When entity is live - this is the entity ID inside associated `EntityComponentDataset`, when the entity is not live - it's set to -1
74648
74654
  * @type {number}
74649
74655
  */
74650
- entity = void 0;
74656
+ id = -1;
74651
74657
 
74652
74658
  /**
74653
74659
  * Generation is a unique identifier coming from the dataset
@@ -74657,16 +74663,17 @@ class Entity {
74657
74663
  generation = -1;
74658
74664
 
74659
74665
  /**
74660
- *
74666
+ * Components associated with the entity
74667
+ * @readonly
74661
74668
  * @type {Array}
74662
74669
  */
74663
- element = [];
74670
+ components = [];
74664
74671
 
74665
74672
  /**
74666
74673
  *
74667
74674
  * @type {{name:string,listener:(function|Function), context:*}[]}
74668
74675
  */
74669
- deferredListeners = [];
74676
+ #deferredListeners = [];
74670
74677
 
74671
74678
  /**
74672
74679
  *
@@ -74681,7 +74688,7 @@ class Entity {
74681
74688
  flags = DEFAULT_FLAGS$3;
74682
74689
 
74683
74690
  /**
74684
- *
74691
+ * Arbitrary metadata, add anything you want here
74685
74692
  * @type {Object}
74686
74693
  */
74687
74694
  properties = {};
@@ -74697,7 +74704,7 @@ class Entity {
74697
74704
  * Handles event when entity is removed without invoking {@link #destroy} method
74698
74705
  * @private
74699
74706
  */
74700
- __handleEntityDestroyed() {
74707
+ #handleEntityDestroyed() {
74701
74708
  this.clearFlag(EntityFlags.Built);
74702
74709
  }
74703
74710
 
@@ -74740,7 +74747,7 @@ class Entity {
74740
74747
  * Remove all components from the entity
74741
74748
  */
74742
74749
  removeAllComponents() {
74743
- const elements = this.element;
74750
+ const elements = this.components;
74744
74751
  const n = elements.length;
74745
74752
  for (let i = n - 1; i >= 0; i--) {
74746
74753
  const component = elements[i];
@@ -74754,7 +74761,7 @@ class Entity {
74754
74761
  * @return {number}
74755
74762
  */
74756
74763
  get count() {
74757
- return this.element.length;
74764
+ return this.components.length;
74758
74765
  }
74759
74766
 
74760
74767
  /**
@@ -74764,16 +74771,16 @@ class Entity {
74764
74771
  */
74765
74772
  add(componentInstance) {
74766
74773
  if (componentInstance === undefined) {
74767
- throw new Error(`Can not add ${componentInstance} to EntityBuilder`);
74774
+ throw new Error(`Can not add ${componentInstance} to Entity`);
74768
74775
  }
74769
74776
 
74770
74777
  assert.notOk(this.hasComponent(Object.getPrototypeOf(componentInstance).constructor), 'Component of this type already exists');
74771
74778
 
74772
- this.element.push(componentInstance);
74779
+ this.components.push(componentInstance);
74773
74780
 
74774
74781
  if (this.getFlag(EntityFlags.Built)) {
74775
74782
  //already built, add component to entity
74776
- this.dataset.addComponentToEntity(this.entity, componentInstance);
74783
+ this.dataset.addComponentToEntity(this.id, componentInstance);
74777
74784
  }
74778
74785
 
74779
74786
  return this;
@@ -74794,7 +74801,7 @@ class Entity {
74794
74801
  * @returns {T|null} component of specified class
74795
74802
  */
74796
74803
  getComponent(klass) {
74797
- const elements = this.element;
74804
+ const elements = this.components;
74798
74805
  const element_count = elements.length;
74799
74806
 
74800
74807
  for (let i = 0; i < element_count; i++) {
@@ -74828,7 +74835,7 @@ class Entity {
74828
74835
  * @returns {*|null}
74829
74836
  */
74830
74837
  removeComponent(klass) {
74831
- const elements = this.element;
74838
+ const elements = this.components;
74832
74839
  const n = elements.length;
74833
74840
 
74834
74841
  for (let i = 0; i < n; i++) {
@@ -74840,7 +74847,7 @@ class Entity {
74840
74847
  //see if entity is built
74841
74848
  if (this.getFlag(EntityFlags.Built)) {
74842
74849
 
74843
- this.dataset.removeComponentFromEntity(this.entity, klass);
74850
+ this.dataset.removeComponentFromEntity(this.id, klass);
74844
74851
 
74845
74852
  }
74846
74853
 
@@ -74858,7 +74865,7 @@ class Entity {
74858
74865
  */
74859
74866
  sendEvent(eventName, event) {
74860
74867
  if (this.getFlag(EntityFlags.Built)) {
74861
- this.dataset.sendEvent(this.entity, eventName, event);
74868
+ this.dataset.sendEvent(this.id, eventName, event);
74862
74869
  } else {
74863
74870
  console.warn("Entity doesn't exist. Event " + eventName + ":" + event + " was not sent.");
74864
74871
  }
@@ -74894,9 +74901,9 @@ class Entity {
74894
74901
  */
74895
74902
  addEventListener(eventName, listener, context) {
74896
74903
  if (this.getFlag(EntityFlags.Built)) {
74897
- this.dataset.addEntityEventListener(this.entity, eventName, listener, context);
74904
+ this.dataset.addEntityEventListener(this.id, eventName, listener, context);
74898
74905
  } else {
74899
- this.deferredListeners.push({
74906
+ this.#deferredListeners.push({
74900
74907
  name: eventName,
74901
74908
  listener: listener,
74902
74909
  context
@@ -74914,9 +74921,9 @@ class Entity {
74914
74921
  */
74915
74922
  removeEventListener(eventName, listener, context) {
74916
74923
  if (this.getFlag(EntityFlags.Built)) {
74917
- this.dataset.removeEntityEventListener(this.entity, eventName, listener, context);
74924
+ this.dataset.removeEntityEventListener(this.id, eventName, listener, context);
74918
74925
  } else {
74919
- const listeners = this.deferredListeners;
74926
+ const listeners = this.#deferredListeners;
74920
74927
 
74921
74928
  for (let i = 0, numListeners = listeners.length; i < numListeners; i++) {
74922
74929
  const deferredDescriptor = listeners[i];
@@ -74945,16 +74952,16 @@ class Entity {
74945
74952
  if (this.getFlag(EntityFlags.Built)) {
74946
74953
 
74947
74954
  const dataset = this.dataset;
74948
- const entity = this.entity;
74955
+ const entity = this.id;
74949
74956
 
74950
74957
  //check that the entity is the same as what we have built
74951
- //assert.ok(checkExistingComponents(entity, this.element, dataset), `Signature of EntityBuilder does not match existing entity(id=${entity})`);
74958
+ //assert.ok(checkExistingComponents(entity, this.element, dataset), `Signature of Entity does not match existing entity(id=${entity})`);
74952
74959
 
74953
- dataset.removeEntityEventListener(entity, EventType.EntityRemoved, this.__handleEntityDestroyed, this);
74960
+ dataset.removeEntityEventListener(entity, EventType.EntityRemoved, this.#handleEntityDestroyed, this);
74954
74961
 
74955
74962
  dataset.removeEntity(entity);
74956
74963
 
74957
- this.entity = void 0;
74964
+ this.id = -1;
74958
74965
 
74959
74966
  this.clearFlag(EntityFlags.Built);
74960
74967
 
@@ -74975,18 +74982,18 @@ class Entity {
74975
74982
 
74976
74983
  if (
74977
74984
  this.getFlag(EntityFlags.Built)
74978
- && checkExistingComponents(this.entity, this.element, dataset)
74985
+ && checkExistingComponents(this.id, this.components, dataset)
74979
74986
  ) {
74980
74987
  //already built
74981
- return this.entity;
74988
+ return this.id;
74982
74989
  }
74983
74990
 
74984
- const entity = this.entity = dataset.createEntity();
74991
+ const entity = this.id = dataset.createEntity();
74985
74992
  this.dataset = dataset;
74986
74993
 
74987
74994
  let i;
74988
74995
 
74989
- const listeners = this.deferredListeners;
74996
+ const listeners = this.#deferredListeners;
74990
74997
  const listeners_count = listeners.length;
74991
74998
 
74992
74999
  for (i = 0; i < listeners_count; i++) {
@@ -74994,9 +75001,9 @@ class Entity {
74994
75001
  dataset.addEntityEventListener(entity, subscription.name, subscription.listener, subscription.context);
74995
75002
  }
74996
75003
  // reset listeners
74997
- this.deferredListeners.splice(0, listeners_count);
75004
+ this.#deferredListeners.splice(0, listeners_count);
74998
75005
 
74999
- const element = this.element;
75006
+ const element = this.components;
75000
75007
  const element_count = element.length;
75001
75008
 
75002
75009
  if (this.getFlag(EntityFlags.RegisterComponents)) {
@@ -75016,7 +75023,7 @@ class Entity {
75016
75023
  this.setFlag(EntityFlags.Built);
75017
75024
 
75018
75025
  if (this.getFlag(EntityFlags.WatchDestruction)) {
75019
- dataset.addEntityEventListener(entity, EventType.EntityRemoved, this.__handleEntityDestroyed, this);
75026
+ dataset.addEntityEventListener(entity, EventType.EntityRemoved, this.#handleEntityDestroyed, this);
75020
75027
  }
75021
75028
 
75022
75029
  this.on.built.send2(entity, dataset);
@@ -75024,7 +75031,7 @@ class Entity {
75024
75031
  }
75025
75032
 
75026
75033
  /**
75027
- *
75034
+ * Extract data about an entity and its components from a dataset
75028
75035
  * @param {number} entity
75029
75036
  * @param {EntityComponentDataset} dataset
75030
75037
  * @returns {Entity}
@@ -75037,7 +75044,7 @@ class Entity {
75037
75044
  .forEach(r.add, r);
75038
75045
 
75039
75046
  r.setFlag(EntityFlags.Built);
75040
- r.entity = entity;
75047
+ r.id = entity;
75041
75048
  r.dataset = dataset;
75042
75049
 
75043
75050
  return r;
@@ -75045,10 +75052,11 @@ class Entity {
75045
75052
  }
75046
75053
 
75047
75054
  /**
75055
+ * Useful for faster alternative to `instanceof` checks
75048
75056
  * @readonly
75049
75057
  * @type {boolean}
75050
75058
  */
75051
- Entity.prototype.isEntityBuilder = true;
75059
+ Entity.prototype.isEntity = true;
75052
75060
 
75053
75061
 
75054
75062
  /**
@@ -75446,7 +75454,7 @@ class EntityNode {
75446
75454
  throw new Error('Parent entity is not built');
75447
75455
  }
75448
75456
 
75449
- const parent_entity_id = parent_entity_builder.entity;
75457
+ const parent_entity_id = parent_entity_builder.id;
75450
75458
  parent_entity.entity = parent_entity_id;
75451
75459
 
75452
75460
  // add component back
@@ -75571,7 +75579,7 @@ class EntityNode {
75571
75579
  throw new Error('Parent entity is not built');
75572
75580
  }
75573
75581
 
75574
- const parent_entity_id = parent_entity_builder.entity;
75582
+ const parent_entity_id = parent_entity_builder.id;
75575
75583
  parent_entity.entity = parent_entity_id;
75576
75584
 
75577
75585
  assert.ok(parent.entity.hasComponent(Transform), "parent node must have a transform but doesn't. Transform is required for attachment transform hierarchy to work correctly");
@@ -78436,11 +78444,17 @@ function build_three_object(sg) {
78436
78444
  return object;
78437
78445
  }
78438
78446
 
78447
+ class CacheValue {
78448
+ object = null
78449
+ key = null
78450
+ }
78451
+
78452
+
78439
78453
  class SGThreeObjectCache {
78440
78454
  constructor() {
78441
78455
  /**
78442
78456
  *
78443
- * @type {WeakMap<ShadedGeometry, THREE.Object3D>}
78457
+ * @type {Map<ShadedGeometry, CacheValue>}
78444
78458
  * @private
78445
78459
  */
78446
78460
  this.__object_cache = new WeakMap();
@@ -78453,15 +78467,28 @@ class SGThreeObjectCache {
78453
78467
  */
78454
78468
  get(sg) {
78455
78469
 
78456
- const existing_object = this.__object_cache.get(sg);
78470
+ const existing_value = this.__object_cache.get(sg);
78457
78471
 
78458
- if (existing_object !== undefined) {
78459
- return existing_object;
78472
+ if (existing_value !== undefined) {
78473
+ const object = existing_value.object;
78474
+
78475
+ // validate that the object is still the same
78476
+ if (existing_value.key.equals(sg)) {
78477
+ return object;
78478
+ }
78460
78479
  }
78461
78480
 
78462
- const new_object = build_three_object(sg);
78481
+ // replace scratch key as it's being used inside the cache now
78482
+ const key = sg.clone();
78483
+
78484
+ const new_object = build_three_object(key);
78485
+
78486
+ const cacheValue = new CacheValue();
78487
+
78488
+ cacheValue.key = key;
78489
+ cacheValue.object = new_object;
78463
78490
 
78464
- this.__object_cache.set(sg, new_object);
78491
+ this.__object_cache.set(sg, cacheValue);
78465
78492
 
78466
78493
  return new_object;
78467
78494
  }
@@ -92564,7 +92591,7 @@ Preloader.prototype.load = function (assetManager) {
92564
92591
 
92565
92592
  /**
92566
92593
  *
92567
- * @param {*} entityIndex
92594
+ * @param {number} entityIndex
92568
92595
  * @returns {boolean}
92569
92596
  */
92570
92597
  function validateEntityIndex(entityIndex) {
@@ -92573,7 +92600,7 @@ function validateEntityIndex(entityIndex) {
92573
92600
 
92574
92601
  /**
92575
92602
  *
92576
- * @param {*} componentIndex
92603
+ * @param {number} componentIndex
92577
92604
  * @returns {boolean}
92578
92605
  */
92579
92606
  function validateComponentIndex(componentIndex) {
@@ -92582,7 +92609,7 @@ function validateComponentIndex(componentIndex) {
92582
92609
 
92583
92610
  /**
92584
92611
  *
92585
- * @param index
92612
+ * @param {number} index
92586
92613
  * @param {string} name
92587
92614
  * @returns {boolean}
92588
92615
  */
@@ -92656,99 +92683,101 @@ function buildObserverCallbackArgs(entityIndex, mask, componentIndexMap, compone
92656
92683
  const scratch_array_0 = [];
92657
92684
  const scratch_array_1 = [];
92658
92685
 
92686
+ /**
92687
+ * Represents a storage for entities and their associated components
92688
+ * 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
92689
+ * It is valid for entities to have no components or to have every possible component
92690
+ * Generally the entity IDs are compacted, meaning that when an entity is removed - it's ID will be later reused
92691
+ */
92659
92692
  class EntityComponentDataset {
92693
+
92660
92694
  /**
92661
- * @class
92662
- * @constructor
92695
+ * @private
92696
+ * @type {BitSet}
92663
92697
  */
92664
- constructor() {
92665
- /**
92666
- * @private
92667
- * @type {BitSet}
92668
- */
92669
- this.entityOccupancy = new BitSet();
92670
- /**
92671
- * @private
92672
- * @type {BitSet}
92673
- */
92674
- this.componentOccupancy = new BitSet();
92698
+ entityOccupancy = new BitSet();
92699
+ /**
92700
+ * @private
92701
+ * @type {BitSet}
92702
+ */
92703
+ componentOccupancy = new BitSet();
92675
92704
 
92676
- /**
92677
- * @private
92678
- * @type {Class[]}
92679
- */
92680
- this.componentTypeMap = [];
92705
+ /**
92706
+ * @private
92707
+ * @type {Class[]}
92708
+ */
92709
+ componentTypeMap = [];
92681
92710
 
92682
- /**
92683
- * Fast index lookup from a component class
92684
- * @type {Map<Class, number>}
92685
- * @private
92686
- */
92687
- this.__type_to_index_map = new Map();
92711
+ /**
92712
+ * Fast index lookup from a component class
92713
+ * @type {Map<Class, number>}
92714
+ * @private
92715
+ */
92716
+ __type_to_index_map = new Map();
92688
92717
 
92689
- /**
92690
- * How many component types exist for this collection. This is the same as componentMap.length
92691
- * @private
92692
- * @type {number}
92693
- */
92694
- this.componentTypeCount = 0;
92718
+ /**
92719
+ * How many component types exist for this collection. This is the same as componentMap.length
92720
+ * @private
92721
+ * @type {number}
92722
+ */
92723
+ componentTypeCount = 0;
92695
92724
 
92696
- /**
92697
- * @private
92698
- * @type {Object[][]}
92699
- */
92700
- this.components = [];
92725
+ /**
92726
+ * @private
92727
+ * @type {Object[][]}
92728
+ */
92729
+ components = [];
92701
92730
 
92702
- /**
92703
- * Current number of entities
92704
- * @private
92705
- * @type {number}
92706
- */
92707
- this.entityCount = 0;
92731
+ /**
92732
+ * Current number of entities
92733
+ * @private
92734
+ * @type {number}
92735
+ */
92736
+ entityCount = 0;
92708
92737
 
92709
- /**
92710
- * A counter that is incremented every time an entity is created
92711
- * Generation is used to provide an entity with a unique identity
92712
- * Entity IDs are re-used, but generation is always increasing
92713
- * 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
92714
- * @private
92715
- * @type {number}
92716
- */
92717
- this.generation = 0;
92738
+ /**
92739
+ * A counter that is incremented every time an entity is created
92740
+ * Generation is used to provide an entity with a unique identity
92741
+ * Entity IDs are re-used, but generation is always increasing
92742
+ * 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
92743
+ * @private
92744
+ * @type {number}
92745
+ */
92746
+ generation = 0;
92718
92747
 
92719
- /**
92720
- * @readonly
92721
- * @type {Signal}
92722
- */
92723
- this.onEntityCreated = new Signal();
92748
+ /**
92749
+ * @readonly
92750
+ * @type {Signal}
92751
+ */
92752
+ onEntityCreated = new Signal();
92724
92753
 
92725
- /**
92726
- * @readonly
92727
- * @type {Signal}
92728
- */
92729
- this.onEntityRemoved = new Signal();
92754
+ /**
92755
+ * @readonly
92756
+ * @type {Signal}
92757
+ */
92758
+ onEntityRemoved = new Signal();
92730
92759
 
92731
92760
 
92732
- /**
92733
- *
92734
- * @type {Array<Object<SignalHandler[]>>}
92735
- * @private
92736
- */
92737
- this.__entityEventListeners = [];
92761
+ /**
92762
+ *
92763
+ * @type {Array<Object<SignalHandler[]>>}
92764
+ * @private
92765
+ */
92766
+ __entityEventListeners = [];
92738
92767
 
92739
- /**
92740
- *
92741
- * @type {SignalHandler[][]}
92742
- * @private
92743
- */
92744
- this.__entityAnyEventListeners = [];
92768
+ /**
92769
+ *
92770
+ * @type {SignalHandler[][]}
92771
+ * @private
92772
+ */
92773
+ __entityAnyEventListeners = [];
92774
+
92775
+ /**
92776
+ * @private
92777
+ * @type {Array<Array<EntityObserver>>}
92778
+ */
92779
+ observers = [];
92745
92780
 
92746
- /**
92747
- * @private
92748
- * @type {Array<Array<EntityObserver>>}
92749
- */
92750
- this.observers = [];
92751
- }
92752
92781
 
92753
92782
  /**
92754
92783
  * returns a promise of a component instance based on a given type
@@ -93438,7 +93467,7 @@ class EntityComponentDataset {
93438
93467
  const componentClass = this.componentTypeMap[componentIndex];
93439
93468
 
93440
93469
  //dispatch event to components
93441
- this.sendEvent(entityIndex, EventType.ComponentRemoved, { klass: componentClass, instance: componentInstance });
93470
+ this.sendEvent(entityIndex, EventType.ComponentRemoved, {klass: componentClass, instance: componentInstance});
93442
93471
  }
93443
93472
 
93444
93473
  /**
@@ -93550,7 +93579,7 @@ class EntityComponentDataset {
93550
93579
  const componentClass = this.componentTypeMap[componentIndex];
93551
93580
 
93552
93581
  //dispatch event to components
93553
- this.sendEvent(entityIndex, EventType.ComponentAdded, { klass: componentClass, instance: componentInstance });
93582
+ this.sendEvent(entityIndex, EventType.ComponentAdded, {klass: componentClass, instance: componentInstance});
93554
93583
  }
93555
93584
 
93556
93585
  /**
@@ -100360,28 +100389,21 @@ function parseTooltipString(text) {
100360
100389
 
100361
100390
  class TooltipParser {
100362
100391
 
100363
- constructor() {
100364
100392
 
100365
- /**
100366
- *
100367
- * @type {Cache<String,Token[]>}
100368
- * @private
100369
- */
100370
- this.__cache = new Cache({
100371
- maxWeight: 1048576,
100372
- keyWeigher: string_compute_byte_size,
100373
- valueWeigher(tokens) {
100374
- return tokens.length * 256;
100375
- },
100376
- keyHashFunction: computeStringHash,
100377
- keyEqualityFunction: strictEquals
100378
- });
100379
-
100380
- }
100381
-
100382
- resetCache() {
100383
- this.__cache.clear();
100384
- }
100393
+ /**
100394
+ *
100395
+ * @type {Cache<String,Token[]>}
100396
+ * @private
100397
+ */
100398
+ #cache = new Cache({
100399
+ maxWeight: 1048576,
100400
+ keyWeigher: string_compute_byte_size,
100401
+ valueWeigher(tokens) {
100402
+ return tokens.length * 256;
100403
+ },
100404
+ keyHashFunction: computeStringHash,
100405
+ keyEqualityFunction: strictEquals
100406
+ });
100385
100407
 
100386
100408
  /**
100387
100409
  *
@@ -100390,7 +100412,7 @@ class TooltipParser {
100390
100412
  */
100391
100413
  parse(code) {
100392
100414
 
100393
- const existing = this.__cache.get(code);
100415
+ const existing = this.#cache.get(code);
100394
100416
 
100395
100417
  if (existing !== null) {
100396
100418
  // result is cached, reuse
@@ -100401,7 +100423,7 @@ class TooltipParser {
100401
100423
  const tokens = parseTooltipString(code);
100402
100424
 
100403
100425
  // cache result
100404
- this.__cache.put(code, tokens);
100426
+ this.#cache.put(code, tokens);
100405
100427
 
100406
100428
  return tokens;
100407
100429
  }
@@ -103151,7 +103173,7 @@ class NotificationManager {
103151
103173
  //find existing entry
103152
103174
  for (const [view, builder] of views) {
103153
103175
 
103154
- if (builder.entity === entity) {
103176
+ if (builder.id === entity) {
103155
103177
  //clear from the map
103156
103178
  views.delete(view);
103157
103179
  break;
@@ -103900,68 +103922,47 @@ class SceneGUIContext {
103900
103922
  */
103901
103923
 
103902
103924
 
103903
- function GUIEngine() {
103904
- this.windows = new List();
103905
-
103906
- /**
103907
- * When set to 'true' - indicated that GUI engine should be the only one receiving the inputs, this is useful for Modal dialogs and other overlays
103908
- * @readonly
103909
- * @type {ObservedBoolean}
103910
- */
103911
- this.captureInputs = new ObservedBoolean(false);
103925
+ class GUIEngine {
103926
+ windows = new List();
103912
103927
 
103913
103928
  /**
103914
103929
  *
103915
103930
  * @type {EntityManager|null}
103916
103931
  */
103917
- this.entityManager = null;
103932
+ entityManager = null;
103918
103933
 
103919
103934
  /**
103920
103935
  *
103921
103936
  * @type {Engine}
103922
103937
  */
103923
- this.engine = null;
103938
+ engine = null;
103924
103939
 
103925
103940
  /**
103926
103941
  *
103927
103942
  * @type {WeakMap<Scene, SceneGUIContext>}
103928
103943
  */
103929
- this.sceneContexts = new WeakMap();
103944
+ sceneContexts = new WeakMap();
103930
103945
 
103931
103946
  /**
103932
103947
  *
103933
103948
  * @type {TooltipManager}
103934
103949
  */
103935
- this.tooltips = new TooltipManager();
103950
+ tooltips = new TooltipManager();
103936
103951
 
103937
103952
  /**
103938
103953
  *
103939
103954
  * @type {DomTooltipManager}
103940
103955
  */
103941
- this.viewTooltips = new DomTooltipManager(this.tooltips);
103956
+ viewTooltips = new DomTooltipManager(this.tooltips);
103942
103957
 
103943
103958
 
103944
103959
  /**
103945
103960
  *
103946
103961
  * @type {Ticker}
103947
103962
  */
103948
- this.ticker = new Ticker();
103949
- this.ticker.subscribe(d => {
103950
-
103951
-
103952
- let ctx = null;
103953
- try {
103954
- ctx = this.getActiveSceneContext();
103955
- } catch (e) {
103956
- //skip
103957
- }
103963
+ ticker = new Ticker();
103958
103964
 
103959
- if (ctx !== null) {
103960
- ctx.tick(d);
103961
- }
103962
- });
103963
-
103964
- this.view = new EmptyView({
103965
+ view = new EmptyView({
103965
103966
  classList: ['gui-engine-root'],
103966
103967
  css: {
103967
103968
  position: "absolute",
@@ -103974,459 +103975,478 @@ function GUIEngine() {
103974
103975
  *
103975
103976
  * @type {GMLEngine}
103976
103977
  */
103977
- this.gml = new GMLEngine();
103978
+ gml = new GMLEngine();
103978
103979
 
103979
103980
  /**
103980
103981
  *
103981
103982
  * @type {ObservedString}
103982
103983
  */
103983
- this.cursor = new ObservedString(CursorType.Normal);
103984
+ cursor = new ObservedString(CursorType.Normal);
103984
103985
 
103985
103986
 
103986
103987
  /**
103987
103988
  *
103988
103989
  * @type {Localization|null}
103989
103990
  */
103990
- this.localization = null;
103991
- }
103991
+ localization = null;
103992
103992
 
103993
- /**
103994
- * @param {boolean} closeable
103995
- * @param {View} content
103996
- * @param {string} title
103997
- * @param {View} [wrapper]
103998
- * @returns {Entity}
103999
- */
104000
- GUIEngine.prototype.openWindow = function ({ closeable, content, title, wrapper }) {
104001
- const entityBuilder = new Entity();
103993
+ constructor() {
103994
+
103995
+ this.ticker.subscribe(d => {
103996
+
103997
+
103998
+ let ctx = null;
103999
+ try {
104000
+ ctx = this.getActiveSceneContext();
104001
+ } catch (e) {
104002
+ //skip
104003
+ }
104004
+
104005
+ if (ctx !== null) {
104006
+ ctx.tick(d);
104007
+ }
104008
+ });
104002
104009
 
104003
- function closeAction() {
104004
- entityBuilder.destroy();
104005
104010
  }
104006
104011
 
104007
- const windowView = new SimpleWindowView(content, {
104008
- closeAction,
104009
- title,
104010
- closeable
104011
- });
104012
+ /**
104013
+ * @param {boolean} closeable
104014
+ * @param {View} content
104015
+ * @param {string} title
104016
+ * @param {View} [wrapper]
104017
+ * @returns {Entity}
104018
+ */
104019
+ openWindow({closeable, content, title, wrapper}) {
104020
+ const entityBuilder = new Entity();
104021
+
104022
+ function closeAction() {
104023
+ entityBuilder.destroy();
104024
+ }
104025
+
104026
+ const windowView = new SimpleWindowView(content, {
104027
+ closeAction,
104028
+ title,
104029
+ closeable
104030
+ });
104012
104031
 
104013
- entityBuilder.add(new ViewportPosition());
104032
+ entityBuilder.add(new ViewportPosition());
104014
104033
 
104015
- let vElement;
104016
- if (wrapper !== undefined) {
104017
- vElement = wrapper;
104018
- wrapper.addChild(windowView);
104019
- } else {
104020
- vElement = windowView;
104034
+ let vElement;
104035
+ if (wrapper !== undefined) {
104036
+ vElement = wrapper;
104037
+ wrapper.addChild(windowView);
104038
+ } else {
104039
+ vElement = windowView;
104040
+ }
104041
+
104042
+ const guiElement = GUIElement.fromView(vElement);
104043
+ entityBuilder.add(guiElement)
104044
+ .add(SerializationMetadata.Transient);
104045
+
104046
+ const dataset = this.entityManager.dataset;
104047
+
104048
+ animateView(windowView, dataset);
104049
+
104050
+ entityBuilder.build(dataset);
104051
+
104052
+ return entityBuilder;
104021
104053
  }
104022
104054
 
104023
- const guiElement = GUIElement.fromView(vElement);
104024
- entityBuilder.add(guiElement)
104025
- .add(SerializationMetadata.Transient);
104055
+ /**
104056
+ *
104057
+ * @param {View} content
104058
+ * @param {string} title
104059
+ * @param {number} priority
104060
+ * @returns {SimpleLifecycle}
104061
+ */
104062
+ createModal({content, title, priority = 0}) {
104063
+ const entityManager = this.entityManager;
104026
104064
 
104027
- const dataset = this.entityManager.dataset;
104065
+ const self = this;
104066
+ let window = null;
104067
+ let overlay = null;
104028
104068
 
104029
- animateView(windowView, dataset);
104030
104069
 
104031
- entityBuilder.build(dataset);
104070
+ function destroy() {
104071
+ window.destroy();
104072
+ overlay.destroy();
104073
+ }
104032
104074
 
104033
- return entityBuilder;
104034
- };
104075
+ function makeOverlay() {
104076
+ const overlay = new View();
104077
+ overlay.el = document.createElement('div');
104078
+ overlay.el.classList.add('ui-modal-overlay');
104079
+ //make overlay dismiss modal
104080
+ overlay.el.addEventListener('click', function (event) {
104081
+ event.stopPropagation();
104082
+ lifecycle.makeDestroyed();
104083
+ });
104035
104084
 
104036
- /**
104037
- *
104038
- * @param {View} view
104039
- * @param {EntityComponentDataset} ecd
104040
- */
104041
- function animateView(view, ecd) {
104085
+ const builder = new Entity();
104042
104086
 
104043
- const animationTrack = new AnimationTrack(["alpha", "scale"]);
104044
- animationTrack.addKey(0, [0, 0.95]);
104045
- animationTrack.addKey(0.2, [1, 1]);
104087
+ builder.add(SerializationMetadata.Transient);
104088
+ builder.add(GUIElement.fromView(overlay));
104089
+ return builder;
104090
+ }
104046
104091
 
104047
- animationTrack.addTransition(0, TransitionFunctions.Linear);
104092
+ function build() {
104093
+ overlay = makeOverlay();
104048
104094
 
104049
- const playback = new AnimationTrackPlayback(animationTrack, function (alpha, scale) {
104050
- this.el.style.opacity = alpha;
104051
- this.scale.set(scale, scale);
104052
- }, view);
104095
+ overlay.build(entityManager.dataset);
104053
104096
 
104054
- //force view status to initial key of animation
104055
- playback.update();
104097
+ const view = content;
104056
104098
 
104057
- playTrackRealTime(playback, ecd);
104058
- }
104099
+ const vModalContainer = new EmptyView({classList: ['ui-modal-window-container']});
104059
104100
 
104060
- /**
104061
- *
104062
- * @param {View} content
104063
- * @param {string} title
104064
- * @param {number} priority
104065
- * @returns {SimpleLifecycle}
104066
- */
104067
- GUIEngine.prototype.createModal = function ({ content, title, priority = 0 }) {
104068
- const entityManager = this.entityManager;
104101
+ window = self.openWindow({
104102
+ title: title,
104103
+ content: view,
104104
+ closeable: false,
104105
+ wrapper: vModalContainer
104106
+ });
104069
104107
 
104070
- const self = this;
104071
- let window = null;
104072
- let overlay = null;
104108
+ const windowGuiElement = window.getComponent(GUIElement);
104109
+ windowGuiElement.anchor.set(0.5, 0.5);
104073
104110
 
104111
+ window.removeComponent(ViewportPosition);
104074
104112
 
104075
- function destroy() {
104076
- window.destroy();
104077
- overlay.destroy();
104078
- }
104113
+ }
104079
104114
 
104080
- function makeOverlay() {
104081
- const overlay = new View();
104082
- overlay.el = document.createElement('div');
104083
- overlay.el.classList.add('ui-modal-overlay');
104084
- //make overlay dismiss modal
104085
- overlay.el.addEventListener('click', function (event) {
104086
- event.stopPropagation();
104087
- lifecycle.makeDestroyed();
104088
- });
104115
+ const lifecycle = new SimpleLifecycle({priority});
104089
104116
 
104090
- const builder = new Entity();
104117
+ lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Active, build);
104118
+ lifecycle.sm.addEventHandlerStateExit(SimpleLifecycleStateType.Active, destroy);
104119
+
104120
+ this.getActiveSceneContext().modals.add(lifecycle);
104091
104121
 
104092
- builder.add(SerializationMetadata.Transient);
104093
- builder.add(GUIElement.fromView(overlay));
104094
- return builder;
104122
+ return lifecycle;
104095
104123
  }
104096
104124
 
104097
- function build() {
104098
- overlay = makeOverlay();
104125
+ /**
104126
+ *
104127
+ * @param {string} title
104128
+ * @param {View} content
104129
+ * @param {ObservedBoolean|ReactiveExpression} [confirmationEnabled]
104130
+ * @returns {Promise<any>}
104131
+ */
104132
+ createModalConfirmation({title, content, confirmationEnabled}) {
104099
104133
 
104100
- overlay.build(entityManager.dataset);
104134
+ const self = this;
104101
104135
 
104102
- const view = content;
104136
+ let lifecycle = null;
104103
104137
 
104104
- const vModalContainer = new EmptyView({ classList: ['ui-modal-window-container'] });
104105
104138
 
104106
- window = self.openWindow({
104107
- title: title,
104108
- content: view,
104109
- closeable: false,
104110
- wrapper: vModalContainer
104111
- });
104139
+ const result = new Promise(function (resolve, reject) {
104140
+ //make view
104112
104141
 
104113
- const windowGuiElement = window.getComponent(GUIElement);
104114
- windowGuiElement.anchor.set(0.5, 0.5);
104142
+ let resolved = false;
104115
104143
 
104116
- window.removeComponent(ViewportPosition);
104144
+ function clear() {
104145
+ lifecycle.makeDestroyed();
104146
+ }
104117
104147
 
104118
- }
104148
+ function callbackYes() {
104149
+ resolved = true;
104150
+ clear();
104151
+ resolve();
104152
+ }
104119
104153
 
104120
- const lifecycle = new SimpleLifecycle({ priority });
104154
+ function callbackNo() {
104155
+ resolved = true;
104156
+ clear();
104157
+ reject();
104158
+ }
104121
104159
 
104122
- lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Active, build);
104123
- lifecycle.sm.addEventHandlerStateExit(SimpleLifecycleStateType.Active, destroy);
104160
+ const view = new ConfirmationDialogView(content,
104161
+ [{
104162
+ name: "yes",
104163
+ displayName: self.localization.getString("system_confirmation_confirm"),
104164
+ callback: callbackYes,
104165
+ enabled: confirmationEnabled
104166
+ }, {
104167
+ name: "no",
104168
+ displayName: self.localization.getString("system_confirmation_cancel"),
104169
+ callback: callbackNo
104170
+ }]
104171
+ );
104124
104172
 
104125
- this.getActiveSceneContext().modals.add(lifecycle);
104173
+ lifecycle = self.createModal({
104174
+ content: view,
104175
+ title: title
104176
+ });
104126
104177
 
104127
- return lifecycle;
104128
- };
104178
+ lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, function () {
104179
+ if (!resolved) {
104180
+ //if destroyed without resolution, reject the promise
104181
+ reject();
104182
+ }
104183
+ });
104184
+ });
104129
104185
 
104130
- /**
104131
- *
104132
- * @param {string} title
104133
- * @param {View} content
104134
- * @param {ObservedBoolean|ReactiveExpression} [confirmationEnabled]
104135
- * @returns {Promise<any>}
104136
- */
104137
- GUIEngine.prototype.createModalConfirmation = function ({ title, content, confirmationEnabled }) {
104138
104186
 
104139
- const self = this;
104187
+ return result;
104188
+ }
104140
104189
 
104141
- let lifecycle = null;
104190
+ /**
104191
+ * @param {string} text
104192
+ * @param {string} title
104193
+ * @returns {Promise} will be resolved or rejected based on user choice
104194
+ */
104195
+ confirmTextDialog({text, title}) {
104196
+ const content = createTextView(text);
104142
104197
 
104198
+ return this.createModalConfirmation({
104199
+ title,
104200
+ content: content
104201
+ });
104202
+ }
104143
104203
 
104144
- const result = new Promise(function (resolve, reject) {
104145
- //make view
104204
+ /**
104205
+ *
104206
+ * @param {string} text
104207
+ * @param {string} title
104208
+ * @returns {Promise}
104209
+ */
104210
+ createTextAlert({text, title}) {
104211
+ const content = createTextView(text);
104212
+ return this.createAlert({
104213
+ content,
104214
+ title
104215
+ });
104216
+ }
104146
104217
 
104147
- let resolved = false;
104218
+ /**
104219
+ *
104220
+ * @param {View} content
104221
+ * @param {string} title
104222
+ * @param {View[]} [marks]
104223
+ * @param {number} priority
104224
+ * @param {function(SimpleLifecycle)} [lifecycleHook]
104225
+ * @returns {Promise}
104226
+ */
104227
+ createAlert(
104228
+ {
104229
+ content,
104230
+ title,
104231
+ marks = [],
104232
+ priority = 0,
104233
+ lifecycleHook = noop
104234
+ }
104235
+ ) {
104236
+ /**
104237
+ *
104238
+ * @type {SimpleLifecycle|null}
104239
+ */
104240
+ let lifecycle = null;
104148
104241
 
104149
104242
  function clear() {
104150
104243
  lifecycle.makeDestroyed();
104151
104244
  }
104152
104245
 
104153
- function callbackYes() {
104154
- resolved = true;
104155
- clear();
104156
- resolve();
104157
- }
104158
-
104159
- function callbackNo() {
104160
- resolved = true;
104161
- clear();
104162
- reject();
104163
- }
104246
+ const localization = this.localization;
104164
104247
 
104165
104248
  const view = new ConfirmationDialogView(content,
104166
104249
  [{
104167
- name: "yes",
104168
- displayName: self.localization.getString("system_confirmation_confirm"),
104169
- callback: callbackYes,
104170
- enabled: confirmationEnabled
104171
- }, {
104172
- name: "no",
104173
- displayName: self.localization.getString("system_confirmation_cancel"),
104174
- callback: callbackNo
104250
+ name: "ok",
104251
+ displayName: localization.getString("system_confirmation_continue"),
104252
+ callback: clear
104175
104253
  }]
104176
104254
  );
104177
104255
 
104178
- lifecycle = self.createModal({
104179
- content: view,
104180
- title: title
104181
- });
104182
-
104183
- lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, function () {
104184
- if (!resolved) {
104185
- //if destroyed without resolution, reject the promise
104186
- reject();
104187
- }
104188
- });
104189
- });
104256
+ if (marks.length > 0) {
104257
+ const vMarks = new EmptyView({classList: ['marks']});
104190
104258
 
104259
+ marks.forEach(vMarks.addChild, vMarks);
104191
104260
 
104192
- return result;
104193
- };
104194
-
104195
- /**
104196
- *
104197
- * @param {string} text
104198
- * @return {View}
104199
- */
104200
- function createTextView(text) {
104201
- const content = new View();
104202
- content.el = document.createElement('div');
104203
- content.el.classList.add('text');
104204
- content.el.innerText = text;
104261
+ view.addChild(vMarks);
104262
+ }
104205
104263
 
104206
- content.size.set(300, 100);
104207
- return content;
104208
- }
104209
104264
 
104210
- /**
104211
- * @param {string} text
104212
- * @param {string} title
104213
- * @returns {Promise} will be resolved or rejected based on user choice
104214
- */
104215
- GUIEngine.prototype.confirmTextDialog = function ({ text, title }) {
104216
- const content = createTextView(text);
104265
+ lifecycle = this.createModal({
104266
+ content: view,
104267
+ title,
104268
+ priority
104269
+ });
104217
104270
 
104218
- return this.createModalConfirmation({
104219
- title,
104220
- content: content
104221
- });
104222
- };
104271
+ const result = new Promise(function (resolve, reject) {
104272
+ lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, resolve);
104273
+ });
104223
104274
 
104224
- /**
104225
- *
104226
- * @param {string} text
104227
- * @param {string} title
104228
- * @returns {Promise}
104229
- */
104230
- GUIEngine.prototype.createTextAlert = function ({ text, title }) {
104231
- const content = createTextView(text);
104232
- return this.createAlert({
104233
- content,
104234
- title
104235
- });
104236
- };
104275
+ lifecycleHook(lifecycle);
104237
104276
 
104238
- /**
104239
- *
104240
- * @param {View} content
104241
- * @param {string} title
104242
- * @param {View[]} [marks]
104243
- * @param {number} priority
104244
- * @param {function(SimpleLifecycle)} [lifecycleHook]
104245
- * @returns {Promise}
104246
- */
104247
- GUIEngine.prototype.createAlert = function (
104248
- {
104249
- content,
104250
- title,
104251
- marks = [],
104252
- priority = 0,
104253
- lifecycleHook = noop
104277
+ return result;
104254
104278
  }
104255
- ) {
104279
+
104256
104280
  /**
104257
104281
  *
104258
- * @type {SimpleLifecycle|null}
104282
+ * @param {Scene} scene
104283
+ * @return {SceneGUIContext}
104259
104284
  */
104260
- let lifecycle = null;
104261
-
104262
- function clear() {
104263
- lifecycle.makeDestroyed();
104264
- }
104285
+ obtainSceneContext(scene) {
104265
104286
 
104266
- const localization = this.localization;
104287
+ let context = this.sceneContexts.get(scene);
104267
104288
 
104268
- const view = new ConfirmationDialogView(content,
104269
- [{
104270
- name: "ok",
104271
- displayName: localization.getString("system_confirmation_continue"),
104272
- callback: clear
104273
- }]
104274
- );
104289
+ if (context === undefined) {
104290
+ context = new SceneGUIContext();
104275
104291
 
104276
- if (marks.length > 0) {
104277
- const vMarks = new EmptyView({ classList: ['marks'] });
104292
+ context.initialize(scene);
104293
+ context.startup();
104278
104294
 
104279
- marks.forEach(vMarks.addChild, vMarks);
104295
+ this.sceneContexts.set(scene, context);
104296
+ }
104280
104297
 
104281
- view.addChild(vMarks);
104298
+ return context;
104282
104299
  }
104283
104300
 
104301
+ /**
104302
+ * @returns {SceneGUIContext|null}
104303
+ */
104304
+ getActiveSceneContext() {
104305
+ const engine = this.engine;
104284
104306
 
104285
- lifecycle = this.createModal({
104286
- content: view,
104287
- title,
104288
- priority
104289
- });
104307
+ if (engine === null) {
104308
+ throw new Error(`Engine is not set`);
104309
+ }
104290
104310
 
104291
- const result = new Promise(function (resolve, reject) {
104292
- lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, resolve);
104293
- });
104311
+ const sm = engine.sceneManager;
104294
104312
 
104295
- lifecycleHook(lifecycle);
104313
+ const scene = sm.current_scene;
104296
104314
 
104297
- return result;
104298
- };
104299
-
104300
- /**
104301
- *
104302
- * @param {Scene} scene
104303
- * @return {SceneGUIContext}
104304
- */
104305
- GUIEngine.prototype.obtainSceneContext = function (scene) {
104306
-
104307
- let context = this.sceneContexts.get(scene);
104315
+ if (scene === null) {
104316
+ return null;
104317
+ }
104308
104318
 
104309
- if (context === undefined) {
104310
- context = new SceneGUIContext();
104319
+ return this.obtainSceneContext(scene);
104320
+ }
104311
104321
 
104312
- context.initialize(scene);
104313
- context.startup();
104322
+ /**
104323
+ * Invoked when locale is updated
104324
+ * @private
104325
+ */
104326
+ __update_localization() {
104327
+ // write locale to the view class so that CSS can be modifier on per-locale basis
104328
+ this.view.removeClassesByPattern(/locale-/);
104314
104329
 
104315
- this.sceneContexts.set(scene, context);
104330
+ this.view.addClass(`locale-${this.localization.locale.getValue()}`);
104316
104331
  }
104317
104332
 
104318
- return context;
104319
- };
104333
+ /**
104334
+ *
104335
+ * @param {Engine} engine
104336
+ */
104337
+ startup(engine) {
104338
+ this.engine = engine;
104339
+ this.entityManager = engine.entityManager;
104320
104340
 
104321
- /**
104322
- * @returns {SceneGUIContext|null}
104323
- */
104324
- GUIEngine.prototype.getActiveSceneContext = function () {
104325
- const engine = this.engine;
104341
+ const self = this;
104326
104342
 
104327
- if (engine === null) {
104328
- throw new Error(`Engine is not set`);
104329
- }
104343
+ /**
104344
+ *
104345
+ * @type {Localization}
104346
+ */
104347
+ const localization = engine.localization;
104330
104348
 
104331
- const sm = engine.sceneManager;
104349
+ this.gml.initialize(engine.staticKnowledge, localization);
104332
104350
 
104333
- const scene = sm.current_scene;
104351
+ this.tooltips.initialize(this.gml, engine.devices.pointer);
104334
104352
 
104335
- if (scene === null) {
104336
- return null;
104337
- }
104353
+ //attach tooltips to GML
104354
+ this.gml.tooltips = this.viewTooltips;
104338
104355
 
104339
- return this.obtainSceneContext(scene);
104340
- };
104356
+ this.view.addChild(this.tooltips.contextView);
104341
104357
 
104342
- /**
104343
- * Invoked when locale is updated
104344
- * @private
104345
- */
104346
- GUIEngine.prototype.__update_localization = function () {
104347
- // write locale to the view class so that CSS can be modifier on per-locale basis
104348
- this.view.removeClassesByPattern(/locale-/);
104358
+ engine.gameView.addChild(this.view);
104349
104359
 
104350
- this.view.addClass(`locale-${this.localization.locale.getValue()}`);
104351
- };
104360
+ engine.gameView.size.process(function (x, y) {
104361
+ self.view.size.set(x, y);
104352
104362
 
104353
- /**
104354
- *
104355
- * @param {Engine} engine
104356
- */
104357
- GUIEngine.prototype.startup = function (engine) {
104358
- this.engine = engine;
104359
- this.entityManager = engine.entityManager;
104363
+ self.tooltips.contextView.size.set(x, y);
104364
+ });
104360
104365
 
104361
- const self = this;
104366
+ this.ticker.start();
104362
104367
 
104363
- /**
104364
- *
104365
- * @type {Localization}
104366
- */
104367
- const localization = engine.localization;
104368
-
104369
- this.gml.initialize(engine.staticKnowledge, localization);
104368
+ this.localization = localization;
104370
104369
 
104371
- this.tooltips.initialize(this.gml, engine.devices.pointer);
104372
104370
 
104373
- //attach tooltips to GML
104374
- this.gml.tooltips = this.viewTooltips;
104371
+ //register cursor propagation
104372
+ this.cursor.process(function (newValue, oldValue) {
104373
+ function className(cursorName) {
104374
+ return `cursor-${cursorName}`;
104375
+ }
104375
104376
 
104376
- this.view.addChild(this.tooltips.contextView);
104377
+ const classList = engine.graphics.domElement.classList;
104377
104378
 
104378
- engine.gameView.addChild(this.view);
104379
+ if (typeof oldValue === 'string') {
104380
+ classList.remove(className(oldValue));
104381
+ }
104379
104382
 
104380
- engine.gameView.size.process(function (x, y) {
104381
- self.view.size.set(x, y);
104383
+ if (typeof newValue === 'string') {
104384
+ classList.add(className(newValue));
104385
+ }
104386
+ });
104382
104387
 
104383
- self.tooltips.contextView.size.set(x, y);
104384
- });
104388
+ // subscribe to localization changes
104389
+ this.localization.locale.onChanged.add(this.__update_localization, this);
104390
+ this.__update_localization();
104385
104391
 
104386
- this.ticker.start();
104392
+ return Promise.all([
104393
+ this.tooltips.startup()
104394
+ ]);
104395
+ }
104387
104396
 
104388
- this.localization = localization;
104397
+ shutdown() {
104398
+ this.windows.reset();
104399
+ this.entityManager = null;
104389
104400
 
104401
+ const pTooltips = this.tooltips.shutdown();
104390
104402
 
104391
- //register cursor propagation
104392
- this.cursor.process(function (newValue, oldValue) {
104393
- function className(cursorName) {
104394
- return `cursor-${cursorName}`;
104395
- }
104403
+ // unsubscribe from localization changes
104404
+ this.localization.locale.onChanged.remove(this.__update_localization, this);
104396
104405
 
104397
- const classList = engine.graphics.domElement.classList;
104406
+ return Promise.all([
104407
+ pTooltips
104408
+ ]);
104409
+ }
104410
+ }
104398
104411
 
104399
- if (typeof oldValue === 'string') {
104400
- classList.remove(className(oldValue));
104401
- }
104412
+ /**
104413
+ *
104414
+ * @param {View} view
104415
+ * @param {EntityComponentDataset} ecd
104416
+ */
104417
+ function animateView(view, ecd) {
104402
104418
 
104403
- if (typeof newValue === 'string') {
104404
- classList.add(className(newValue));
104405
- }
104406
- });
104419
+ const animationTrack = new AnimationTrack(["alpha", "scale"]);
104420
+ animationTrack.addKey(0, [0, 0.95]);
104421
+ animationTrack.addKey(0.2, [1, 1]);
104407
104422
 
104408
- // subscribe to localization changes
104409
- this.localization.locale.onChanged.add(this.__update_localization, this);
104410
- this.__update_localization();
104423
+ animationTrack.addTransition(0, TransitionFunctions.Linear);
104411
104424
 
104412
- return Promise.all([
104413
- this.tooltips.startup()
104414
- ]);
104415
- };
104425
+ const playback = new AnimationTrackPlayback(animationTrack, function (alpha, scale) {
104426
+ this.el.style.opacity = alpha;
104427
+ this.scale.set(scale, scale);
104428
+ }, view);
104416
104429
 
104417
- GUIEngine.prototype.shutdown = function () {
104418
- this.windows.reset();
104419
- this.entityManager = null;
104430
+ //force view status to initial key of animation
104431
+ playback.update();
104420
104432
 
104421
- const pTooltips = this.tooltips.shutdown();
104433
+ playTrackRealTime(playback, ecd);
104434
+ }
104422
104435
 
104423
- // unsubscribe from localization changes
104424
- this.localization.locale.onChanged.remove(this.__update_localization, this);
104436
+ /**
104437
+ *
104438
+ * @param {string} text
104439
+ * @return {View}
104440
+ */
104441
+ function createTextView(text) {
104442
+ const content = new View();
104443
+ content.el = document.createElement('div');
104444
+ content.el.classList.add('text');
104445
+ content.el.innerText = text;
104425
104446
 
104426
- return Promise.all([
104427
- pTooltips
104428
- ]);
104429
- };
104447
+ content.size.set(300, 100);
104448
+ return content;
104449
+ }
104430
104450
 
104431
104451
  /**
104432
104452
  * Created by Alex on 04/11/2016.
@@ -121033,7 +121053,7 @@ class EngineHarness {
121033
121053
  autoClip: cameraAutoClip
121034
121054
  });
121035
121055
 
121036
- const cameraEntity = camera.entity;
121056
+ const cameraEntity = camera.id;
121037
121057
 
121038
121058
  if (enableTerrain) {
121039
121059
  await EngineHarness.buildTerrain({