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