@woosh/meep-engine 2.47.23 → 2.47.26

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 (31) hide show
  1. package/build/meep.cjs +544 -342
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +544 -342
  4. package/editor/tools/SelectionTool.js +17 -17
  5. package/editor/view/EditorView.js +4 -5
  6. package/editor/view/ecs/EntityList.js +0 -2
  7. package/package.json +1 -1
  8. package/src/core/geom/3d/topology/samples/sampleFloodFill.js +8 -8
  9. package/src/core/json/abstractJSONSerializer.js +1 -1
  10. package/src/engine/ecs/EntityComponentDataset.js +28 -3
  11. package/src/engine/ecs/EntityManager.js +264 -221
  12. package/src/engine/ecs/System.d.ts +2 -0
  13. package/src/engine/ecs/System.js +37 -30
  14. package/src/engine/ecs/gui/menu/radial/RadialContextMenu.js +0 -4
  15. package/src/engine/ecs/systems/TimerSystem.js +61 -41
  16. package/src/engine/ecs/terrain/util/obtainTerrain.js +2 -3
  17. package/src/engine/graphics/GraphicsEngine.js +4 -3
  18. package/src/engine/graphics/ecs/camera/Camera.js +37 -0
  19. package/src/engine/graphics/ecs/camera/filter/setup_filtered_camera_controller.js +78 -0
  20. package/src/engine/graphics/ecs/camera/pp/NOTES.md +48 -0
  21. package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +164 -0
  22. package/src/engine/graphics/ecs/camera/pp/Perfect_Panning.png +0 -0
  23. package/src/engine/graphics/ecs/camera/pp/Zooming.png +0 -0
  24. package/src/engine/graphics/ecs/camera/pp/pan_a.png +0 -0
  25. package/src/engine/graphics/ecs/camera/pp/pan_b.png +0 -0
  26. package/src/engine/graphics/ecs/mesh/MeshSystem.js +1 -1
  27. package/src/engine/graphics/make_ray_from_viewport_position.js +28 -0
  28. package/src/engine/input/devices/PointerDevice.js +32 -0
  29. package/src/engine/intelligence/behavior/decorator/RepeatBehavior.js +17 -8
  30. package/src/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +2 -2
  31. package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.js +9 -5
@@ -8,6 +8,7 @@ import { computeSystemName, System } from "./System.js";
8
8
  import { assert } from "../../core/assert.js";
9
9
  import { EntityObserver } from "./EntityObserver.js";
10
10
  import { IllegalStateException } from "../../core/fsm/exceptions/IllegalStateException.js";
11
+ import { noop } from "../../core/function/Functions.js";
11
12
 
12
13
  /**
13
14
  *
@@ -39,26 +40,25 @@ export const EntityManagerState = {
39
40
  */
40
41
  function EntityManager() {
41
42
  /**
42
- *
43
- * @type {Array.<System>}
43
+ * @readonly
44
+ * @type {System[]}
44
45
  */
45
46
  this.systems = [];
46
47
 
47
48
  /**
48
- *
49
- * @type {Array<EntityObserver>}
49
+ * @readonly
50
+ * @type {EntityObserver[]}
50
51
  */
51
52
  this.systemObservers = [];
52
53
 
54
+ /**
55
+ * @readonly
56
+ */
53
57
  this.on = {
54
58
  systemStarted: new Signal(),
55
59
  systemStopped: new Signal(),
56
60
  systemAdded: new Signal(),
57
61
  systemRemoved: new Signal(),
58
- /**
59
- * @deprecated
60
- */
61
- reset: new Signal()
62
62
  };
63
63
 
64
64
  /**
@@ -67,6 +67,19 @@ function EntityManager() {
67
67
  */
68
68
  this.state = EntityManagerState.Initial;
69
69
 
70
+ /**
71
+ * @private
72
+ * @readonly
73
+ * @type {Map<System, number>}
74
+ */
75
+ this.systemAccumulatedFixedStepTime = new Map();
76
+
77
+ /**
78
+ * In seconds
79
+ * @type {number}
80
+ */
81
+ this.fixedUpdateStepSize = 0.015;
82
+
70
83
  /**
71
84
  *
72
85
  * @type {EntityComponentDataset}
@@ -141,170 +154,6 @@ EntityManager.prototype.attachDataSet = function (dataset) {
141
154
  });
142
155
  };
143
156
 
144
- /**
145
- * @deprecated
146
- * @returns {number}
147
- */
148
- EntityManager.prototype.createEntity = function () {
149
- console.warn("EntityManager.createEntity is deprecated");
150
-
151
- return this.dataset.createEntity();
152
- };
153
-
154
- /**
155
- * @deprecated
156
- * @param id
157
- */
158
- EntityManager.prototype.createEntitySpecific = function (id) {
159
- console.warn("EntityManager.createEntitySpecific is deprecated");
160
- this.dataset.createEntitySpecific(id);
161
- };
162
-
163
-
164
- /**
165
- * @deprecated
166
- * Remove association of specified component type from entity
167
- * @param {Number} entityId
168
- * @param {Number} componentType
169
- */
170
- EntityManager.prototype.removeComponentFromEntity = function (entityId, componentType) {
171
- console.warn("EntityManager.removeComponentFromEntity is deprecated");
172
-
173
- this.dataset.removeComponentFromEntityByIndex(entityId, componentType);
174
- };
175
-
176
- /**
177
- * @deprecated use dataset directly
178
- * Retrieves component instance associated with entity
179
- * @template T
180
- * @param {Number} entityId
181
- * @param {class.<T>} componentClass
182
- * @returns {T|null}
183
- * @nosideeffects
184
- */
185
- EntityManager.prototype.getComponent = function (entityId, componentClass) {
186
- return this.dataset.getComponent(entityId, componentClass);
187
- };
188
-
189
- /**
190
- *
191
- * @param {number} entityIndex
192
- * @returns {boolean}
193
- */
194
- EntityManager.prototype.entityExists = function (entityIndex) {
195
- if (this.dataset === null) {
196
- //no dataset - no entities
197
- return false;
198
- }
199
- return this.dataset.entityExists(entityIndex);
200
- };
201
-
202
- /**
203
- * same as getComponent when component exists, if component is not associated with the entity, callback will be invoked once when it is added.
204
- * @param {Number} entityId
205
- * @param {Class} componentClass
206
- * @param {function} callback
207
- * @param {*} [thisArg]
208
- */
209
- EntityManager.prototype.getComponentAsync = function (entityId, componentClass, callback, thisArg) {
210
- const self = this;
211
- const component = this.getComponent(entityId, componentClass);
212
-
213
- function handler(options) {
214
- if (options.klass === componentClass) {
215
- self.removeEntityEventListener(entityId, EventType.ComponentAdded, handler);
216
- callback.call(thisArg, options.instance);
217
- }
218
- }
219
-
220
- if (component === void 0 || component === null) {
221
- this.addEntityEventListener(entityId, EventType.ComponentAdded, handler);
222
- } else {
223
- callback.call(thisArg, component);
224
- }
225
- };
226
-
227
- /**
228
- * @deprecated Use {@link EntityManager#dataset} direction
229
- * @param entity
230
- * @returns {Array}
231
- */
232
- EntityManager.prototype.getComponents = function (entity) {
233
- console.warn("EntityManager.getComponents is deprecated");
234
-
235
- return this.dataset.getAllComponents(entity);
236
- };
237
-
238
- /**
239
- * @deprecated
240
- * Retrieves component instance associated with entity
241
- * @param {Number} entityId
242
- * @param {Number} componentType
243
- * @returns {*|undefined} component of specified type or undefined if it was not found
244
- */
245
- EntityManager.prototype.getComponentByType = function (entityId, componentType) {
246
- console.warn("EntityManager.getComponentByType is deprecated");
247
- return this.dataset.getComponentByIndex(entityId, componentType);
248
- };
249
-
250
- /**
251
- * @deprecated
252
- * does traversal on a subset of entities which have specified components.
253
- * @example traverseEntities([Transform,Renderable,Tag],function(transform, renderable, tag, entity){ ... }, this);
254
- * @param {Array.<class>} classes
255
- * @param {Function} callback
256
- * @param {Object} [thisArg] specifies context object on which callbacks are to be called, optional
257
- */
258
- EntityManager.prototype.traverseEntities = function (classes, callback, thisArg) {
259
- if (this.dataset === null) {
260
- //no data to traverse
261
- return;
262
- }
263
- this.dataset.traverseEntities(classes, callback, thisArg);
264
- };
265
-
266
- /**
267
- * @deprecated
268
- * @param entity
269
- * @param eventName
270
- * @param listener
271
- */
272
- EntityManager.prototype.addEntityEventListener = function (entity, eventName, listener) {
273
- this.dataset.addEntityEventListener(entity, eventName, listener);
274
- };
275
-
276
- /**
277
- * @deprecated
278
- * @param {number} entity
279
- * @param {string} eventName
280
- * @param {function} listener
281
- */
282
- EntityManager.prototype.removeEntityEventListener = function (entity, eventName, listener) {
283
- this.dataset.removeEntityEventListener(entity, eventName, listener);
284
- };
285
-
286
- /**
287
- * @deprecated use dataset directly instead
288
- * @param entity
289
- * @param eventName
290
- * @param event
291
- */
292
- EntityManager.prototype.sendEvent = function (entity, eventName, event) {
293
- this.dataset.sendEvent(entity, eventName, event);
294
- };
295
-
296
- /**
297
- * @deprecated
298
- * @param {function} klazz
299
- * @param {function(component: *, entity: number):boolean} callback
300
- * @param {*} [thisArg]
301
- * @deprecated
302
- */
303
- EntityManager.prototype.traverseComponents = function (klazz, callback, thisArg) {
304
- if (this.dataset !== null) {
305
- this.dataset.traverseComponents(klazz, callback, thisArg);
306
- }
307
- };
308
157
 
309
158
  /**
310
159
  * @template T
@@ -336,33 +185,6 @@ EntityManager.prototype.getSystem = function (systemClass) {
336
185
  return null;
337
186
  };
338
187
 
339
- /**
340
- * @deprecated Use {@link #getSystem} instead
341
- * @template T,C
342
- * @param {C} klazz
343
- * @returns {System|T}
344
- */
345
- EntityManager.prototype.getOwnerSystemByComponentClass = function (klazz) {
346
- const index = this.getOwnerSystemIdByComponentClass(klazz);
347
- return this.systems[index];
348
- };
349
-
350
- /**
351
- * @deprecated
352
- * @param {function} clazz
353
- * @returns {number} value >= 0, representing system Id, or -1 if system was not found
354
- */
355
- EntityManager.prototype.getOwnerSystemIdByComponentClass = function (clazz) {
356
- const systems = this.systems;
357
- let i = 0;
358
- const l = systems.length;
359
- for (; i < l; i++) {
360
- if (systems[i].componentClass === clazz) {
361
- return i;
362
- }
363
- }
364
- return -1;
365
- };
366
188
 
367
189
  /**
368
190
  * @template T
@@ -384,19 +206,6 @@ EntityManager.prototype.getComponentClassByName = function (className) {
384
206
  return null;
385
207
  };
386
208
 
387
- /**
388
- *
389
- * @param {System} system
390
- * @param {number} timeDelta
391
- */
392
- function tryUpdateSystem(system, timeDelta) {
393
- try {
394
- system.update(timeDelta);
395
- } catch (e) {
396
- console.error(`Failed to update system '${computeSystemName(system)}': `, e);
397
- }
398
- }
399
-
400
209
  /**
401
210
  * Advance simulation forward by a specified amount of time
402
211
  * @param {number} timeDelta in seconds, real number
@@ -406,12 +215,51 @@ EntityManager.prototype.simulate = function (timeDelta) {
406
215
  assert.notNaN(timeDelta, 'timeDelta');
407
216
  assert.greaterThanOrEqual(timeDelta, 0, 'timeDelta must be >= 0');
408
217
 
218
+ /**
219
+ *
220
+ * @type {System[]}
221
+ */
409
222
  const systems = this.systems;
410
- let i = 0;
411
- const l = systems.length;
412
- for (; i < l; i++) {
223
+
224
+ const system_count = systems.length;
225
+
226
+ const fixed_step = this.fixedUpdateStepSize;
227
+ const accumulatedTime = this.systemAccumulatedFixedStepTime;
228
+
229
+ for (let i = 0; i < system_count; i++) {
230
+
413
231
  const system = systems[i];
414
- tryUpdateSystem(system, timeDelta);
232
+
233
+ if (system.fixedUpdate !== noop) {
234
+ let accumulated_time = accumulatedTime.get(system) + timeDelta;
235
+
236
+
237
+ while (accumulated_time > fixed_step) {
238
+
239
+ try {
240
+ system.fixedUpdate(fixed_step)
241
+ } catch (e) {
242
+ console.error(`Failed during fixedUpdate of system '${computeSystemName(system)}': `, e);
243
+ }
244
+
245
+ accumulated_time -= fixed_step;
246
+ }
247
+
248
+ // record whatever remains
249
+ accumulatedTime.set(system, accumulated_time);
250
+
251
+ }
252
+
253
+ if (system.update !== noop) {
254
+
255
+ try {
256
+ system.update(timeDelta);
257
+ } catch (e) {
258
+ console.error(`Failed during update of system '${computeSystemName(system)}': `, e);
259
+ }
260
+
261
+ }
262
+
415
263
  }
416
264
  };
417
265
 
@@ -534,6 +382,8 @@ EntityManager.prototype.addSystem = async function (system) {
534
382
  this.dataset.addObserver(linkObserver);
535
383
  }
536
384
 
385
+ this.systemAccumulatedFixedStepTime.set(system, 0);
386
+
537
387
  this.on.systemAdded.send1(system);
538
388
 
539
389
  await startup_promise;
@@ -577,6 +427,8 @@ EntityManager.prototype.removeSystem = async function (system) {
577
427
  });
578
428
  });
579
429
 
430
+ this.systemAccumulatedFixedStepTime.delete(system);
431
+
580
432
  this.on.systemRemoved.send1(system);
581
433
  };
582
434
 
@@ -875,17 +727,208 @@ EntityManager.prototype.shutdown = function (readyCallback, errorCallback) {
875
727
  });
876
728
  };
877
729
 
730
+
731
+ /**
732
+ * @deprecated
733
+ * @returns {number}
734
+ */
735
+ EntityManager.prototype.createEntity = function () {
736
+ console.warn("EntityManager.createEntity is deprecated");
737
+
738
+ return this.dataset.createEntity();
739
+ };
740
+
741
+ /**
742
+ * @deprecated
743
+ * @param id
744
+ */
745
+ EntityManager.prototype.createEntitySpecific = function (id) {
746
+ console.warn("EntityManager.createEntitySpecific is deprecated");
747
+ this.dataset.createEntitySpecific(id);
748
+ };
749
+
750
+
751
+ /**
752
+ * @deprecated
753
+ * Remove association of specified component type from entity
754
+ * @param {Number} entityId
755
+ * @param {Number} componentType
756
+ */
757
+ EntityManager.prototype.removeComponentFromEntity = function (entityId, componentType) {
758
+ console.warn("EntityManager.removeComponentFromEntity is deprecated");
759
+
760
+ this.dataset.removeComponentFromEntityByIndex(entityId, componentType);
761
+ };
762
+
763
+ /**
764
+ * @deprecated use dataset directly
765
+ * Retrieves component instance associated with entity
766
+ * @template T
767
+ * @param {Number} entityId
768
+ * @param {class.<T>} componentClass
769
+ * @returns {T|null}
770
+ * @nosideeffects
771
+ */
772
+ EntityManager.prototype.getComponent = function (entityId, componentClass) {
773
+ console.warn("EntityManager.getComponent is deprecated");
774
+
775
+ return this.dataset.getComponent(entityId, componentClass);
776
+ };
777
+
778
+ /**
779
+ * @deprecated use {@link EntityComponentDataset.entityExists} instead
780
+ * @param {number} entityIndex
781
+ * @returns {boolean}
782
+ */
783
+ EntityManager.prototype.entityExists = function (entityIndex) {
784
+ console.warn("EntityManager.entityExists is deprecated");
785
+ if (this.dataset === null) {
786
+ //no dataset - no entities
787
+ return false;
788
+ }
789
+ return this.dataset.entityExists(entityIndex);
790
+ };
791
+
792
+
793
+ /**
794
+ * @deprecated Use {@link EntityManager#dataset} direction
795
+ * @param entity
796
+ * @returns {Array}
797
+ */
798
+ EntityManager.prototype.getComponents = function (entity) {
799
+ console.warn("EntityManager.getComponents is deprecated");
800
+
801
+ return this.dataset.getAllComponents(entity);
802
+ };
803
+
878
804
  /**
879
805
  * @deprecated
806
+ * Retrieves component instance associated with entity
807
+ * @param {Number} entityId
808
+ * @param {Number} componentType
809
+ * @returns {*|undefined} component of specified type or undefined if it was not found
880
810
  */
881
- EntityManager.prototype.reset = function () {
882
- console.warn("EntityManager.reset is deprecated and should no longer be used, reset dataset instead");
811
+ EntityManager.prototype.getComponentByType = function (entityId, componentType) {
812
+ console.warn("EntityManager.getComponentByType is deprecated");
813
+ return this.dataset.getComponentByIndex(entityId, componentType);
814
+ };
883
815
 
884
- this.dataset.clear();
816
+ /**
817
+ * @deprecated
818
+ * does traversal on a subset of entities which have specified components.
819
+ * @example traverseEntities([Transform,Renderable,Tag],function(transform, renderable, tag, entity){ ... }, this);
820
+ * @param {Array.<class>} classes
821
+ * @param {Function} callback
822
+ * @param {Object} [thisArg] specifies context object on which callbacks are to be called, optional
823
+ */
824
+ EntityManager.prototype.traverseEntities = function (classes, callback, thisArg) {
825
+ console.warn("EntityManager.traverseEntities is deprecated");
826
+
827
+ if (this.dataset === null) {
828
+ //no data to traverse
829
+ return;
830
+ }
831
+ this.dataset.traverseEntities(classes, callback, thisArg);
832
+ };
833
+
834
+ /**
835
+ * @deprecated
836
+ * @param entity
837
+ * @param eventName
838
+ * @param listener
839
+ */
840
+ EntityManager.prototype.addEntityEventListener = function (entity, eventName, listener) {
841
+ console.warn("EntityManager.addEntityEventListener is deprecated");
842
+ this.dataset.addEntityEventListener(entity, eventName, listener);
843
+ };
844
+
845
+ /**
846
+ * @deprecated
847
+ * @param {number} entity
848
+ * @param {string} eventName
849
+ * @param {function} listener
850
+ */
851
+ EntityManager.prototype.removeEntityEventListener = function (entity, eventName, listener) {
852
+ console.warn("EntityManager.removeEntityEventListener is deprecated");
853
+ this.dataset.removeEntityEventListener(entity, eventName, listener);
854
+ };
855
+
856
+ /**
857
+ * @deprecated use dataset directly instead
858
+ * @param entity
859
+ * @param eventName
860
+ * @param event
861
+ */
862
+ EntityManager.prototype.sendEvent = function (entity, eventName, event) {
863
+ console.warn("EntityManager.sendEvent is deprecated");
864
+ this.dataset.sendEvent(entity, eventName, event);
865
+ };
866
+
867
+ /**
868
+ * @deprecated
869
+ * @param {function} klazz
870
+ * @param {function(component: *, entity: number):boolean} callback
871
+ * @param {*} [thisArg]
872
+ * @deprecated
873
+ */
874
+ EntityManager.prototype.traverseComponents = function (klazz, callback, thisArg) {
875
+ console.warn("EntityManager.traverseComponents is deprecated");
876
+ if (this.dataset !== null) {
877
+ this.dataset.traverseComponents(klazz, callback, thisArg);
878
+ }
879
+ };
880
+
881
+ /**
882
+ * @deprecated Use {@link #getSystem} instead
883
+ * @template T,C
884
+ * @param {C} klazz
885
+ * @returns {System|T}
886
+ */
887
+ EntityManager.prototype.getOwnerSystemByComponentClass = function (klazz) {
888
+
889
+ console.warn("EntityManager.getOwnerSystemByComponentClass is deprecated, use .getSystem instead");
890
+ const index = this.getOwnerSystemIdByComponentClass(klazz);
891
+ return this.systems[index];
892
+ };
893
+
894
+ /**
895
+ * @deprecated
896
+ * @param {function} clazz
897
+ * @returns {number} value >= 0, representing system Id, or -1 if system was not found
898
+ */
899
+ EntityManager.prototype.getOwnerSystemIdByComponentClass = function (clazz) {
900
+ console.warn("EntityManager.getOwnerSystemIdByComponentClass is deprecated, use .getSystem instead");
901
+
902
+ const systems = this.systems;
903
+ let i = 0;
904
+ const l = systems.length;
905
+ for (; i < l; i++) {
906
+ if (systems[i].componentClass === clazz) {
907
+ return i;
908
+ }
909
+ }
910
+ return -1;
911
+ };
912
+
913
+
914
+ /**
915
+ * same as getComponent when component exists, if component is not associated with the entity, callback will be invoked once when it is added.
916
+ * @param {Number} entityId
917
+ * @param {Class} componentClass
918
+ * @param {function} callback
919
+ * @param {*} [thisArg]
920
+ */
921
+ EntityManager.prototype.getComponentAsync = function (entityId, componentClass, callback, thisArg) {
922
+ console.warn("EntityManager.getComponentAsync is deprecated");
923
+
924
+ const dataset = this.dataset;
925
+
926
+ if (dataset === undefined) {
927
+ throw new Error('No dataset attached');
928
+ }
885
929
 
886
- this.on.reset.send0();
930
+ dataset.getComponentAsync(entityId, componentClass, callback, thisArg);
887
931
 
888
- console.log("Entity Manager completed reset");
889
932
  };
890
933
 
891
934
  export {
@@ -27,4 +27,6 @@ export class System<A, B = any, C = any, D = any, E = any> {
27
27
  unlink(a: A, b: B, c: C, d: D, e: E, entity: number): void
28
28
 
29
29
  update(time_delta: number): void
30
+
31
+ fixedUpdate(time_delta: number): void
30
32
  }
@@ -5,39 +5,39 @@
5
5
 
6
6
  import { array_copy_unique } from "../../core/collection/array/array_copy_unique.js";
7
7
  import ObservedValue from "../../core/model/ObservedValue.js";
8
+ import { noop } from "../../core/function/Functions.js";
8
9
 
9
10
  /**
10
11
  *
11
12
  * @template C
12
13
  */
13
14
  class System {
14
- constructor() {
15
15
 
16
- /**
17
- *
18
- * @type {EntityManager}
19
- */
20
- this.entityManager = null;
16
+ /**
17
+ * @protected
18
+ * @type {EntityManager}
19
+ */
20
+ entityManager = null;
21
21
 
22
- /**
23
- *
24
- * @type {ObservedValue.<System.State>}
25
- */
26
- this.state = new ObservedValue(System.State.INITIAL);
22
+ /**
23
+ * @readonly
24
+ * @type {ObservedValue.<System.State>}
25
+ */
26
+ state = new ObservedValue(System.State.INITIAL);
27
27
 
28
- /**
29
- * Other components which have to be present before the system links component
30
- * @type {Array}
31
- */
32
- this.dependencies = [];
28
+ /**
29
+ * Other components which have to be present before the system links component
30
+ * @type {Array}
31
+ */
32
+ dependencies = [];
33
+
34
+ /**
35
+ * Component types that are used internally by the system
36
+ * Declaring this helps EntityManager to ensure that all relevant component types are properly registered for the system
37
+ * @type {Array}
38
+ */
39
+ components_used = [];
33
40
 
34
- /**
35
- * Component types that are used internally by the system
36
- * Declaring this helps EntityManager to ensure that all relevant component types are properly registered for the system
37
- * @type {Array}
38
- */
39
- this.components_used = [];
40
- }
41
41
 
42
42
  /**
43
43
  * @returns {[]}
@@ -68,15 +68,22 @@ class System {
68
68
 
69
69
  }
70
70
 
71
- /**
72
- *
73
- * @param {number} timeDelta Time in seconds
74
- */
75
- update(timeDelta) {
76
-
77
- }
78
71
  }
79
72
 
73
+ /**
74
+ * Fixed update function, every step happens with the same exact time increment
75
+ * useful for systems that must have a fixed time step to be predictable and stable, such as physics
76
+ * @param {number} timeDelta in seconds
77
+ */
78
+ System.prototype.fixedUpdate = noop; // by assigning NO-OP we enable a simple check, whether running the update would be useful
79
+
80
+
81
+ /**
82
+ * This update is generally synchronized with the render loop
83
+ * @param {number} timeDelta Time in seconds
84
+ */
85
+ System.prototype.update = noop; // by assigning NO-OP we enable a simple check, whether running the update would be useful
86
+
80
87
  Object.defineProperties(System.prototype, {
81
88
  /**
82
89
  * @deprecated
@@ -196,10 +196,6 @@ export function makeMenu({
196
196
 
197
197
  selectionMade = true;
198
198
 
199
- if (event !== undefined && event !== null) {
200
- event.stopPropagation();
201
- }
202
-
203
199
  try {
204
200
  mainView.runSelected();
205
201
  } catch (e) {