@woosh/meep-engine 2.58.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 (66) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/build/meep.cjs +15297 -20126
  4. package/build/meep.min.js +1 -1
  5. package/build/meep.module.js +15298 -20126
  6. package/editor/process/symbolic/SymbolicDisplayInternalAPI.js +3 -3
  7. package/editor/process/symbolic/makeParticleEmitterSymbolicDisplay.js +1 -1
  8. package/editor/process/symbolic/makePathSymbolicDisplay.js +1 -1
  9. package/editor/process/symbolic/makeSoundEmitterSymbolicDisplay.js +1 -1
  10. package/editor/tools/TopDownCameraControlTool.js +2 -2
  11. package/editor/tools/v2/TransformControls.js +1 -1
  12. package/editor/tools/v2/prototypeTransformControls.js +1 -1
  13. package/package.json +2 -2
  14. package/samples/generation/main.js +1 -1
  15. package/samples/terrain/editor.js +1 -1
  16. package/src/core/collection/array/arraySetDiff.js +11 -7
  17. package/src/core/geom/3d/aabb/aabb3_array_intersects_point.spec.js +48 -0
  18. package/src/core/geom/3d/aabb/aabb3_array_intersects_ray.js +5 -1
  19. package/src/core/geom/3d/aabb/aabb3_expand_array.spec.js +16 -0
  20. package/src/core/geom/3d/aabb/aabb3_raycast.spec.js +37 -0
  21. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.js +11 -12
  22. package/src/core/geom/3d/aabb/aabb3_score_boxes_SAH.spec.js +14 -0
  23. package/src/core/geom/3d/aabb/aabb3_transformed_compute_plane_side.js +6 -4
  24. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +6 -3
  25. package/src/core/geom/3d/matrix/m4_multiply.spec.js +24 -0
  26. package/src/core/geom/3d/matrix/m4_multiply_alphatensor.js +56 -40
  27. package/src/core/geom/3d/matrix/m4_multiply_alphatensor.spec.js +24 -0
  28. package/src/core/geom/3d/shape/util/shape_to_visual_entity.js +2 -2
  29. package/src/core/geom/Vector3.spec.js +24 -14
  30. package/src/engine/EngineHarness.js +1 -1
  31. package/src/engine/control/ControlContext.js +1 -1
  32. package/src/engine/ecs/Entity.d.ts +2 -0
  33. package/src/engine/ecs/Entity.js +40 -37
  34. package/src/engine/ecs/Entity.spec.js +2 -2
  35. package/src/engine/ecs/EntityBuilderUtils.js +2 -2
  36. package/src/engine/ecs/EntityComponentDataset.js +91 -89
  37. package/src/engine/ecs/EntityFlags.js +4 -4
  38. package/src/engine/ecs/attachment/Attachment.js +5 -2
  39. package/src/engine/ecs/binding/ComponentPropertyBinding.js +13 -13
  40. package/src/engine/ecs/dynamic_actions/RuleExecution.js +1 -1
  41. package/src/engine/ecs/parent/EntityNode.js +2 -2
  42. package/src/engine/ecs/parent/EntityNode.spec.js +2 -2
  43. package/src/engine/ecs/tooltip/testTooltipComponentSystem.js +1 -1
  44. package/src/engine/ecs/util/hideEntityGracefully.js +6 -6
  45. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +1 -0
  46. package/src/engine/graphics/ecs/mesh-v2/render/SGThreeObjectCache.js +30 -7
  47. package/src/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +1 -1
  48. package/src/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +71 -34
  49. package/src/engine/graphics/ecs/mesh-v2/sample/prototype_sg_raycast.js +1 -1
  50. package/src/engine/graphics/ecs/path/PathDisplaySystem.js +4 -4
  51. package/src/engine/graphics/ecs/path/entity/EntityPathMarker.js +1 -1
  52. package/src/engine/graphics/ecs/path/highlight/PathDisplayHighlightSystem.js +3 -3
  53. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +5 -5
  54. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +2 -2
  55. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
  56. package/src/engine/graphics/sh3/prototypeSH3Probe.js +2 -2
  57. package/src/engine/intelligence/behavior/ecs/EntityBehavior.js +14 -17
  58. package/src/engine/intelligence/behavior/util/DelayBehavior.js +6 -6
  59. package/src/engine/ui/GUIEngine.js +368 -371
  60. package/src/engine/ui/notification/NotificationManager.js +1 -1
  61. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessor.js +1 -1
  62. package/src/view/tooltip/gml/TooltipParser.js +21 -28
  63. package/src/view/tooltip/gml/compiler/GMLReferenceCompiler.js +3 -2
  64. package/src/core/geom/3d/aabb/aabb3_intersects_ray_branchless.js +0 -52
  65. package/src/core/geom/3d/aabb/aabb3_intersects_ray_fast.js +0 -176
  66. package/src/core/geom/3d/aabb/aabb3_intersects_ray_slab.js +0 -91
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
  import List from '../../core/collection/list/List.js';
7
- import { playTrackRealTime } from "../animation/playTrackRealTime.js";
7
+ import {playTrackRealTime} from "../animation/playTrackRealTime.js";
8
8
 
9
9
  import GUIElement from '../ecs/gui/GUIElement.js';
10
10
  import ViewportPosition from '../ecs/gui/position/ViewportPosition.js';
@@ -18,82 +18,60 @@ import View from '../../view/View.js';
18
18
  import TransitionFunctions from "../animation/TransitionFunctions.js";
19
19
  import AnimationTrack from "../animation/keyed2/AnimationTrack.js";
20
20
  import AnimationTrackPlayback from "../animation/keyed2/AnimationTrackPlayback.js";
21
- import { TooltipManager } from "../../view/tooltip/TooltipManager.js";
22
- import { DomTooltipManager } from "../../view/tooltip/DomTooltipManager.js";
21
+ import {TooltipManager} from "../../view/tooltip/TooltipManager.js";
22
+ import {DomTooltipManager} from "../../view/tooltip/DomTooltipManager.js";
23
23
  import Ticker from "../simulation/Ticker.js";
24
- import { SimpleLifecycle, SimpleLifecycleStateType } from "../../core/process/SimpleLifecycle.js";
25
- import ObservedBoolean from "../../core/model/ObservedBoolean.js";
24
+ import {SimpleLifecycle, SimpleLifecycleStateType} from "../../core/process/SimpleLifecycle.js";
26
25
  import EmptyView from "../../view/elements/EmptyView.js";
27
- import { GMLEngine } from "../../view/tooltip/gml/GMLEngine.js";
26
+ import {GMLEngine} from "../../view/tooltip/gml/GMLEngine.js";
28
27
  import ObservedString from "../../core/model/ObservedString.js";
29
- import { CursorType } from "./cursor/CursorType.js";
30
- import { noop } from "../../core/function/Functions.js";
31
- import { SerializationMetadata } from "../ecs/components/SerializationMetadata.js";
32
- import { SceneGUIContext } from "./scene/SceneGUIContext.js";
28
+ import {CursorType} from "./cursor/CursorType.js";
29
+ import {noop} from "../../core/function/Functions.js";
30
+ import {SerializationMetadata} from "../ecs/components/SerializationMetadata.js";
31
+ import {SceneGUIContext} from "./scene/SceneGUIContext.js";
33
32
 
34
33
 
35
- function GUIEngine() {
36
- this.windows = new List();
37
-
38
- /**
39
- * 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
40
- * @readonly
41
- * @type {ObservedBoolean}
42
- */
43
- this.captureInputs = new ObservedBoolean(false);
34
+ class GUIEngine {
35
+ windows = new List();
44
36
 
45
37
  /**
46
38
  *
47
39
  * @type {EntityManager|null}
48
40
  */
49
- this.entityManager = null;
41
+ entityManager = null;
50
42
 
51
43
  /**
52
44
  *
53
45
  * @type {Engine}
54
46
  */
55
- this.engine = null;
47
+ engine = null;
56
48
 
57
49
  /**
58
50
  *
59
51
  * @type {WeakMap<Scene, SceneGUIContext>}
60
52
  */
61
- this.sceneContexts = new WeakMap();
53
+ sceneContexts = new WeakMap();
62
54
 
63
55
  /**
64
56
  *
65
57
  * @type {TooltipManager}
66
58
  */
67
- this.tooltips = new TooltipManager();
59
+ tooltips = new TooltipManager();
68
60
 
69
61
  /**
70
62
  *
71
63
  * @type {DomTooltipManager}
72
64
  */
73
- this.viewTooltips = new DomTooltipManager(this.tooltips);
65
+ viewTooltips = new DomTooltipManager(this.tooltips);
74
66
 
75
67
 
76
68
  /**
77
69
  *
78
70
  * @type {Ticker}
79
71
  */
80
- this.ticker = new Ticker();
81
- this.ticker.subscribe(d => {
82
-
72
+ ticker = new Ticker();
83
73
 
84
- let ctx = null;
85
- try {
86
- ctx = this.getActiveSceneContext();
87
- } catch (e) {
88
- //skip
89
- }
90
-
91
- if (ctx !== null) {
92
- ctx.tick(d);
93
- }
94
- });
95
-
96
- this.view = new EmptyView({
74
+ view = new EmptyView({
97
75
  classList: ['gui-engine-root'],
98
76
  css: {
99
77
  position: "absolute",
@@ -106,458 +84,477 @@ function GUIEngine() {
106
84
  *
107
85
  * @type {GMLEngine}
108
86
  */
109
- this.gml = new GMLEngine();
87
+ gml = new GMLEngine();
110
88
 
111
89
  /**
112
90
  *
113
91
  * @type {ObservedString}
114
92
  */
115
- this.cursor = new ObservedString(CursorType.Normal);
93
+ cursor = new ObservedString(CursorType.Normal);
116
94
 
117
95
 
118
96
  /**
119
97
  *
120
98
  * @type {Localization|null}
121
99
  */
122
- this.localization = null;
123
- }
100
+ localization = null;
124
101
 
125
- /**
126
- * @param {boolean} closeable
127
- * @param {View} content
128
- * @param {string} title
129
- * @param {View} [wrapper]
130
- * @returns {Entity}
131
- */
132
- GUIEngine.prototype.openWindow = function ({ closeable, content, title, wrapper }) {
133
- const entityBuilder = new Entity();
102
+ constructor() {
134
103
 
135
- function closeAction() {
136
- entityBuilder.destroy();
137
- }
104
+ this.ticker.subscribe(d => {
138
105
 
139
- const windowView = new SimpleWindowView(content, {
140
- closeAction,
141
- title,
142
- closeable
143
- });
144
106
 
145
- entityBuilder.add(new ViewportPosition());
107
+ let ctx = null;
108
+ try {
109
+ ctx = this.getActiveSceneContext();
110
+ } catch (e) {
111
+ //skip
112
+ }
113
+
114
+ if (ctx !== null) {
115
+ ctx.tick(d);
116
+ }
117
+ });
146
118
 
147
- let vElement;
148
- if (wrapper !== undefined) {
149
- vElement = wrapper;
150
- wrapper.addChild(windowView);
151
- } else {
152
- vElement = windowView;
153
119
  }
154
120
 
155
- const guiElement = GUIElement.fromView(vElement);
156
- entityBuilder.add(guiElement)
157
- .add(SerializationMetadata.Transient);
121
+ /**
122
+ * @param {boolean} closeable
123
+ * @param {View} content
124
+ * @param {string} title
125
+ * @param {View} [wrapper]
126
+ * @returns {Entity}
127
+ */
128
+ openWindow({closeable, content, title, wrapper}) {
129
+ const entityBuilder = new Entity();
158
130
 
159
- const dataset = this.entityManager.dataset;
131
+ function closeAction() {
132
+ entityBuilder.destroy();
133
+ }
160
134
 
161
- animateView(windowView, dataset);
135
+ const windowView = new SimpleWindowView(content, {
136
+ closeAction,
137
+ title,
138
+ closeable
139
+ });
162
140
 
163
- entityBuilder.build(dataset);
141
+ entityBuilder.add(new ViewportPosition());
164
142
 
165
- return entityBuilder;
166
- };
143
+ let vElement;
144
+ if (wrapper !== undefined) {
145
+ vElement = wrapper;
146
+ wrapper.addChild(windowView);
147
+ } else {
148
+ vElement = windowView;
149
+ }
167
150
 
168
- /**
169
- *
170
- * @param {View} view
171
- * @param {EntityComponentDataset} ecd
172
- */
173
- function animateView(view, ecd) {
151
+ const guiElement = GUIElement.fromView(vElement);
152
+ entityBuilder.add(guiElement)
153
+ .add(SerializationMetadata.Transient);
174
154
 
175
- const animationTrack = new AnimationTrack(["alpha", "scale"]);
176
- animationTrack.addKey(0, [0, 0.95]);
177
- animationTrack.addKey(0.2, [1, 1]);
155
+ const dataset = this.entityManager.dataset;
178
156
 
179
- animationTrack.addTransition(0, TransitionFunctions.Linear);
157
+ animateView(windowView, dataset);
180
158
 
181
- const playback = new AnimationTrackPlayback(animationTrack, function (alpha, scale) {
182
- this.el.style.opacity = alpha;
183
- this.scale.set(scale, scale);
184
- }, view);
159
+ entityBuilder.build(dataset);
185
160
 
186
- //force view status to initial key of animation
187
- playback.update();
161
+ return entityBuilder;
162
+ }
188
163
 
189
- playTrackRealTime(playback, ecd);
190
- }
164
+ /**
165
+ *
166
+ * @param {View} content
167
+ * @param {string} title
168
+ * @param {number} priority
169
+ * @returns {SimpleLifecycle}
170
+ */
171
+ createModal({content, title, priority = 0}) {
172
+ const entityManager = this.entityManager;
191
173
 
192
- /**
193
- *
194
- * @param {View} content
195
- * @param {string} title
196
- * @param {number} priority
197
- * @returns {SimpleLifecycle}
198
- */
199
- GUIEngine.prototype.createModal = function ({ content, title, priority = 0 }) {
200
- const entityManager = this.entityManager;
174
+ const self = this;
175
+ let window = null;
176
+ let overlay = null;
201
177
 
202
- const self = this;
203
- let window = null;
204
- let overlay = null;
205
178
 
179
+ function destroy() {
180
+ window.destroy();
181
+ overlay.destroy();
182
+ }
206
183
 
207
- function destroy() {
208
- window.destroy();
209
- overlay.destroy();
210
- }
184
+ function makeOverlay() {
185
+ const overlay = new View();
186
+ overlay.el = document.createElement('div');
187
+ overlay.el.classList.add('ui-modal-overlay');
188
+ //make overlay dismiss modal
189
+ overlay.el.addEventListener('click', function (event) {
190
+ event.stopPropagation();
191
+ lifecycle.makeDestroyed();
192
+ });
193
+
194
+ const builder = new Entity();
195
+
196
+ builder.add(SerializationMetadata.Transient);
197
+ builder.add(GUIElement.fromView(overlay));
198
+ return builder;
199
+ }
211
200
 
212
- function makeOverlay() {
213
- const overlay = new View();
214
- overlay.el = document.createElement('div');
215
- overlay.el.classList.add('ui-modal-overlay');
216
- //make overlay dismiss modal
217
- overlay.el.addEventListener('click', function (event) {
218
- event.stopPropagation();
219
- lifecycle.makeDestroyed();
220
- });
201
+ function build() {
202
+ overlay = makeOverlay();
221
203
 
222
- const builder = new Entity();
204
+ overlay.build(entityManager.dataset);
223
205
 
224
- builder.add(SerializationMetadata.Transient);
225
- builder.add(GUIElement.fromView(overlay));
226
- return builder;
227
- }
206
+ const view = content;
228
207
 
229
- function build() {
230
- overlay = makeOverlay();
208
+ const vModalContainer = new EmptyView({classList: ['ui-modal-window-container']});
231
209
 
232
- overlay.build(entityManager.dataset);
210
+ window = self.openWindow({
211
+ title: title,
212
+ content: view,
213
+ closeable: false,
214
+ wrapper: vModalContainer
215
+ });
233
216
 
234
- const view = content;
217
+ const windowGuiElement = window.getComponent(GUIElement);
218
+ windowGuiElement.anchor.set(0.5, 0.5);
235
219
 
236
- const vModalContainer = new EmptyView({ classList: ['ui-modal-window-container'] });
220
+ window.removeComponent(ViewportPosition);
237
221
 
238
- window = self.openWindow({
239
- title: title,
240
- content: view,
241
- closeable: false,
242
- wrapper: vModalContainer
243
- });
222
+ }
223
+
224
+ const lifecycle = new SimpleLifecycle({priority});
244
225
 
245
- const windowGuiElement = window.getComponent(GUIElement);
246
- windowGuiElement.anchor.set(0.5, 0.5);
226
+ lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Active, build);
227
+ lifecycle.sm.addEventHandlerStateExit(SimpleLifecycleStateType.Active, destroy);
247
228
 
248
- window.removeComponent(ViewportPosition);
229
+ this.getActiveSceneContext().modals.add(lifecycle);
249
230
 
231
+ return lifecycle;
250
232
  }
251
233
 
252
- const lifecycle = new SimpleLifecycle({ priority });
234
+ /**
235
+ *
236
+ * @param {string} title
237
+ * @param {View} content
238
+ * @param {ObservedBoolean|ReactiveExpression} [confirmationEnabled]
239
+ * @returns {Promise<any>}
240
+ */
241
+ createModalConfirmation({title, content, confirmationEnabled}) {
253
242
 
254
- lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Active, build);
255
- lifecycle.sm.addEventHandlerStateExit(SimpleLifecycleStateType.Active, destroy);
243
+ const self = this;
256
244
 
257
- this.getActiveSceneContext().modals.add(lifecycle);
245
+ let lifecycle = null;
258
246
 
259
- return lifecycle;
260
- };
261
247
 
262
- /**
263
- *
264
- * @param {string} title
265
- * @param {View} content
266
- * @param {ObservedBoolean|ReactiveExpression} [confirmationEnabled]
267
- * @returns {Promise<any>}
268
- */
269
- GUIEngine.prototype.createModalConfirmation = function ({ title, content, confirmationEnabled }) {
248
+ const result = new Promise(function (resolve, reject) {
249
+ //make view
250
+
251
+ let resolved = false;
270
252
 
271
- const self = this;
253
+ function clear() {
254
+ lifecycle.makeDestroyed();
255
+ }
272
256
 
273
- let lifecycle = null;
257
+ function callbackYes() {
258
+ resolved = true;
259
+ clear();
260
+ resolve();
261
+ }
274
262
 
263
+ function callbackNo() {
264
+ resolved = true;
265
+ clear();
266
+ reject();
267
+ }
275
268
 
276
- const result = new Promise(function (resolve, reject) {
277
- //make view
269
+ const view = new ConfirmationDialogView(content,
270
+ [{
271
+ name: "yes",
272
+ displayName: self.localization.getString("system_confirmation_confirm"),
273
+ callback: callbackYes,
274
+ enabled: confirmationEnabled
275
+ }, {
276
+ name: "no",
277
+ displayName: self.localization.getString("system_confirmation_cancel"),
278
+ callback: callbackNo
279
+ }]
280
+ );
281
+
282
+ lifecycle = self.createModal({
283
+ content: view,
284
+ title: title
285
+ });
286
+
287
+ lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, function () {
288
+ if (!resolved) {
289
+ //if destroyed without resolution, reject the promise
290
+ reject();
291
+ }
292
+ });
293
+ });
278
294
 
279
- let resolved = false;
280
295
 
281
- function clear() {
282
- lifecycle.makeDestroyed();
283
- }
296
+ return result;
297
+ }
298
+
299
+ /**
300
+ * @param {string} text
301
+ * @param {string} title
302
+ * @returns {Promise} will be resolved or rejected based on user choice
303
+ */
304
+ confirmTextDialog({text, title}) {
305
+ const content = createTextView(text);
306
+
307
+ return this.createModalConfirmation({
308
+ title,
309
+ content: content
310
+ });
311
+ }
284
312
 
285
- function callbackYes() {
286
- resolved = true;
287
- clear();
288
- resolve();
313
+ /**
314
+ *
315
+ * @param {string} text
316
+ * @param {string} title
317
+ * @returns {Promise}
318
+ */
319
+ createTextAlert({text, title}) {
320
+ const content = createTextView(text);
321
+ return this.createAlert({
322
+ content,
323
+ title
324
+ });
325
+ }
326
+
327
+ /**
328
+ *
329
+ * @param {View} content
330
+ * @param {string} title
331
+ * @param {View[]} [marks]
332
+ * @param {number} priority
333
+ * @param {function(SimpleLifecycle)} [lifecycleHook]
334
+ * @returns {Promise}
335
+ */
336
+ createAlert(
337
+ {
338
+ content,
339
+ title,
340
+ marks = [],
341
+ priority = 0,
342
+ lifecycleHook = noop
289
343
  }
344
+ ) {
345
+ /**
346
+ *
347
+ * @type {SimpleLifecycle|null}
348
+ */
349
+ let lifecycle = null;
290
350
 
291
- function callbackNo() {
292
- resolved = true;
293
- clear();
294
- reject();
351
+ function clear() {
352
+ lifecycle.makeDestroyed();
295
353
  }
296
354
 
355
+ const localization = this.localization;
356
+
297
357
  const view = new ConfirmationDialogView(content,
298
358
  [{
299
- name: "yes",
300
- displayName: self.localization.getString("system_confirmation_confirm"),
301
- callback: callbackYes,
302
- enabled: confirmationEnabled
303
- }, {
304
- name: "no",
305
- displayName: self.localization.getString("system_confirmation_cancel"),
306
- callback: callbackNo
359
+ name: "ok",
360
+ displayName: localization.getString("system_confirmation_continue"),
361
+ callback: clear
307
362
  }]
308
363
  );
309
364
 
310
- lifecycle = self.createModal({
311
- content: view,
312
- title: title
313
- });
365
+ if (marks.length > 0) {
366
+ const vMarks = new EmptyView({classList: ['marks']});
314
367
 
315
- lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, function () {
316
- if (!resolved) {
317
- //if destroyed without resolution, reject the promise
318
- reject();
319
- }
320
- });
321
- });
368
+ marks.forEach(vMarks.addChild, vMarks);
322
369
 
370
+ view.addChild(vMarks);
371
+ }
323
372
 
324
- return result;
325
- };
326
-
327
- /**
328
- *
329
- * @param {string} text
330
- * @return {View}
331
- */
332
- function createTextView(text) {
333
- const content = new View();
334
- content.el = document.createElement('div');
335
- content.el.classList.add('text');
336
- content.el.innerText = text;
337
-
338
- content.size.set(300, 100);
339
- return content;
340
- }
341
373
 
342
- /**
343
- * @param {string} text
344
- * @param {string} title
345
- * @returns {Promise} will be resolved or rejected based on user choice
346
- */
347
- GUIEngine.prototype.confirmTextDialog = function ({ text, title }) {
348
- const content = createTextView(text);
374
+ lifecycle = this.createModal({
375
+ content: view,
376
+ title,
377
+ priority
378
+ });
349
379
 
350
- return this.createModalConfirmation({
351
- title,
352
- content: content
353
- });
354
- };
380
+ const result = new Promise(function (resolve, reject) {
381
+ lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, resolve);
382
+ });
355
383
 
356
- /**
357
- *
358
- * @param {string} text
359
- * @param {string} title
360
- * @returns {Promise}
361
- */
362
- GUIEngine.prototype.createTextAlert = function ({ text, title }) {
363
- const content = createTextView(text);
364
- return this.createAlert({
365
- content,
366
- title
367
- });
368
- };
384
+ lifecycleHook(lifecycle);
369
385
 
370
- /**
371
- *
372
- * @param {View} content
373
- * @param {string} title
374
- * @param {View[]} [marks]
375
- * @param {number} priority
376
- * @param {function(SimpleLifecycle)} [lifecycleHook]
377
- * @returns {Promise}
378
- */
379
- GUIEngine.prototype.createAlert = function (
380
- {
381
- content,
382
- title,
383
- marks = [],
384
- priority = 0,
385
- lifecycleHook = noop
386
+ return result;
386
387
  }
387
- ) {
388
+
388
389
  /**
389
390
  *
390
- * @type {SimpleLifecycle|null}
391
+ * @param {Scene} scene
392
+ * @return {SceneGUIContext}
391
393
  */
392
- let lifecycle = null;
394
+ obtainSceneContext(scene) {
393
395
 
394
- function clear() {
395
- lifecycle.makeDestroyed();
396
- }
397
-
398
- const localization = this.localization;
396
+ let context = this.sceneContexts.get(scene);
399
397
 
400
- const view = new ConfirmationDialogView(content,
401
- [{
402
- name: "ok",
403
- displayName: localization.getString("system_confirmation_continue"),
404
- callback: clear
405
- }]
406
- );
398
+ if (context === undefined) {
399
+ context = new SceneGUIContext();
407
400
 
408
- if (marks.length > 0) {
409
- const vMarks = new EmptyView({ classList: ['marks'] });
401
+ context.initialize(scene);
402
+ context.startup();
410
403
 
411
- marks.forEach(vMarks.addChild, vMarks);
404
+ this.sceneContexts.set(scene, context);
405
+ }
412
406
 
413
- view.addChild(vMarks);
407
+ return context;
414
408
  }
415
409
 
410
+ /**
411
+ * @returns {SceneGUIContext|null}
412
+ */
413
+ getActiveSceneContext() {
414
+ const engine = this.engine;
416
415
 
417
- lifecycle = this.createModal({
418
- content: view,
419
- title,
420
- priority
421
- });
422
-
423
- const result = new Promise(function (resolve, reject) {
424
- lifecycle.sm.addEventHandlerStateEntry(SimpleLifecycleStateType.Destroyed, resolve);
425
- });
426
-
427
- lifecycleHook(lifecycle);
416
+ if (engine === null) {
417
+ throw new Error(`Engine is not set`);
418
+ }
428
419
 
429
- return result;
430
- };
420
+ const sm = engine.sceneManager;
431
421
 
432
- /**
433
- *
434
- * @param {Scene} scene
435
- * @return {SceneGUIContext}
436
- */
437
- GUIEngine.prototype.obtainSceneContext = function (scene) {
422
+ const scene = sm.current_scene;
438
423
 
439
- let context = this.sceneContexts.get(scene);
424
+ if (scene === null) {
425
+ return null;
426
+ }
440
427
 
441
- if (context === undefined) {
442
- context = new SceneGUIContext();
428
+ return this.obtainSceneContext(scene);
429
+ }
443
430
 
444
- context.initialize(scene);
445
- context.startup();
431
+ /**
432
+ * Invoked when locale is updated
433
+ * @private
434
+ */
435
+ __update_localization() {
436
+ // write locale to the view class so that CSS can be modifier on per-locale basis
437
+ this.view.removeClassesByPattern(/locale-/)
446
438
 
447
- this.sceneContexts.set(scene, context);
439
+ this.view.addClass(`locale-${this.localization.locale.getValue()}`);
448
440
  }
449
441
 
450
- return context;
451
- };
442
+ /**
443
+ *
444
+ * @param {Engine} engine
445
+ */
446
+ startup(engine) {
447
+ this.engine = engine;
448
+ this.entityManager = engine.entityManager;
452
449
 
453
- /**
454
- * @returns {SceneGUIContext|null}
455
- */
456
- GUIEngine.prototype.getActiveSceneContext = function () {
457
- const engine = this.engine;
450
+ const self = this;
458
451
 
459
- if (engine === null) {
460
- throw new Error(`Engine is not set`);
461
- }
452
+ /**
453
+ *
454
+ * @type {Localization}
455
+ */
456
+ const localization = engine.localization;
462
457
 
463
- const sm = engine.sceneManager;
458
+ this.gml.initialize(engine.staticKnowledge, localization);
464
459
 
465
- const scene = sm.current_scene;
460
+ this.tooltips.initialize(this.gml, engine.devices.pointer);
466
461
 
467
- if (scene === null) {
468
- return null;
469
- }
462
+ //attach tooltips to GML
463
+ this.gml.tooltips = this.viewTooltips;
470
464
 
471
- return this.obtainSceneContext(scene);
472
- };
465
+ this.view.addChild(this.tooltips.contextView);
473
466
 
474
- /**
475
- * Invoked when locale is updated
476
- * @private
477
- */
478
- GUIEngine.prototype.__update_localization = function () {
479
- // write locale to the view class so that CSS can be modifier on per-locale basis
480
- this.view.removeClassesByPattern(/locale-/)
467
+ engine.gameView.addChild(this.view);
481
468
 
482
- this.view.addClass(`locale-${this.localization.locale.getValue()}`);
483
- };
469
+ engine.gameView.size.process(function (x, y) {
470
+ self.view.size.set(x, y);
484
471
 
485
- /**
486
- *
487
- * @param {Engine} engine
488
- */
489
- GUIEngine.prototype.startup = function (engine) {
490
- this.engine = engine;
491
- this.entityManager = engine.entityManager;
472
+ self.tooltips.contextView.size.set(x, y);
473
+ });
492
474
 
493
- const self = this;
475
+ this.ticker.start();
494
476
 
495
- /**
496
- *
497
- * @type {Localization}
498
- */
499
- const localization = engine.localization;
477
+ this.localization = localization;
500
478
 
501
- this.gml.initialize(engine.staticKnowledge, localization);
502
479
 
503
- this.tooltips.initialize(this.gml, engine.devices.pointer);
504
-
505
- //attach tooltips to GML
506
- this.gml.tooltips = this.viewTooltips;
480
+ //register cursor propagation
481
+ this.cursor.process(function (newValue, oldValue) {
482
+ function className(cursorName) {
483
+ return `cursor-${cursorName}`;
484
+ }
507
485
 
508
- this.view.addChild(this.tooltips.contextView);
486
+ const classList = engine.graphics.domElement.classList;
509
487
 
510
- engine.gameView.addChild(this.view);
488
+ if (typeof oldValue === 'string') {
489
+ classList.remove(className(oldValue));
490
+ }
511
491
 
512
- engine.gameView.size.process(function (x, y) {
513
- self.view.size.set(x, y);
492
+ if (typeof newValue === 'string') {
493
+ classList.add(className(newValue));
494
+ }
495
+ });
514
496
 
515
- self.tooltips.contextView.size.set(x, y);
516
- });
497
+ // subscribe to localization changes
498
+ this.localization.locale.onChanged.add(this.__update_localization, this);
499
+ this.__update_localization();
517
500
 
518
- this.ticker.start();
501
+ return Promise.all([
502
+ this.tooltips.startup()
503
+ ]);
504
+ }
519
505
 
520
- this.localization = localization;
506
+ shutdown() {
507
+ this.windows.reset();
508
+ this.entityManager = null;
521
509
 
510
+ const pTooltips = this.tooltips.shutdown()
522
511
 
523
- //register cursor propagation
524
- this.cursor.process(function (newValue, oldValue) {
525
- function className(cursorName) {
526
- return `cursor-${cursorName}`;
527
- }
512
+ // unsubscribe from localization changes
513
+ this.localization.locale.onChanged.remove(this.__update_localization, this);
528
514
 
529
- const classList = engine.graphics.domElement.classList;
515
+ return Promise.all([
516
+ pTooltips
517
+ ]);
518
+ }
519
+ }
530
520
 
531
- if (typeof oldValue === 'string') {
532
- classList.remove(className(oldValue));
533
- }
521
+ /**
522
+ *
523
+ * @param {View} view
524
+ * @param {EntityComponentDataset} ecd
525
+ */
526
+ function animateView(view, ecd) {
534
527
 
535
- if (typeof newValue === 'string') {
536
- classList.add(className(newValue));
537
- }
538
- });
528
+ const animationTrack = new AnimationTrack(["alpha", "scale"]);
529
+ animationTrack.addKey(0, [0, 0.95]);
530
+ animationTrack.addKey(0.2, [1, 1]);
539
531
 
540
- // subscribe to localization changes
541
- this.localization.locale.onChanged.add(this.__update_localization, this);
542
- this.__update_localization();
532
+ animationTrack.addTransition(0, TransitionFunctions.Linear);
543
533
 
544
- return Promise.all([
545
- this.tooltips.startup()
546
- ]);
547
- };
534
+ const playback = new AnimationTrackPlayback(animationTrack, function (alpha, scale) {
535
+ this.el.style.opacity = alpha;
536
+ this.scale.set(scale, scale);
537
+ }, view);
548
538
 
549
- GUIEngine.prototype.shutdown = function () {
550
- this.windows.reset();
551
- this.entityManager = null;
539
+ //force view status to initial key of animation
540
+ playback.update();
552
541
 
553
- const pTooltips = this.tooltips.shutdown()
542
+ playTrackRealTime(playback, ecd);
543
+ }
554
544
 
555
- // unsubscribe from localization changes
556
- this.localization.locale.onChanged.remove(this.__update_localization, this);
545
+ /**
546
+ *
547
+ * @param {string} text
548
+ * @return {View}
549
+ */
550
+ function createTextView(text) {
551
+ const content = new View();
552
+ content.el = document.createElement('div');
553
+ content.el.classList.add('text');
554
+ content.el.innerText = text;
557
555
 
558
- return Promise.all([
559
- pTooltips
560
- ]);
561
- };
556
+ content.size.set(300, 100);
557
+ return content;
558
+ }
562
559
 
563
560
  export default GUIEngine;