@woosh/meep-engine 2.60.1 → 2.61.0

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 (63) hide show
  1. package/build/meep.cjs +20117 -20157
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +20117 -20157
  4. package/package.json +1 -1
  5. package/src/core/binary/BitSet.js +1 -1
  6. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +30 -182
  7. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.spec.js +27 -1
  8. package/src/core/geom/ConicRay.js +16 -21
  9. package/src/core/geom/ConicRay.spec.js +24 -0
  10. package/src/core/geom/packing/miniball/Miniball.js +68 -117
  11. package/src/core/geom/packing/miniball/Miniball.spec.js +3 -3
  12. package/src/core/geom/packing/miniball/Subspan.js +47 -34
  13. package/src/core/geom/packing/miniball/miniball_compute_quality.js +64 -0
  14. package/src/core/math/bessel_3.js +1 -0
  15. package/src/core/math/random/randomBytes.js +2 -2
  16. package/src/core/math/sqr.js +8 -0
  17. package/src/core/model/node-graph/Connection.js +21 -23
  18. package/src/core/model/node-graph/DataType.js +16 -17
  19. package/src/core/model/node-graph/NodeGraph.js +49 -50
  20. package/src/core/model/node-graph/node/NodeDescription.js +42 -44
  21. package/src/core/model/node-graph/node/NodeInstance.js +59 -60
  22. package/src/core/model/node-graph/node/NodeInstancePortReference.js +27 -29
  23. package/src/core/model/node-graph/node/NodeRegistry.js +16 -18
  24. package/src/core/model/node-graph/node/Port.js +35 -37
  25. package/src/core/model/node-graph/node/parameter/NodeParameterDescription.js +27 -13
  26. package/src/core/path/computePathDirectory.spec.js +8 -0
  27. package/src/core/process/BaseProcess.d.ts +5 -0
  28. package/src/core/process/WatchDog.js +76 -75
  29. package/src/core/process/action/AsynchronousAction.js +24 -22
  30. package/src/core/process/executor/profile/Profile.js +34 -24
  31. package/src/core/process/executor/profile/TraceEvent.js +75 -75
  32. package/src/core/process/worker/OnDemandWorkerManager.js +27 -30
  33. package/src/core/process/worker/WorkerBuilder.js +149 -149
  34. package/src/core/process/worker/WorkerProxy.js +25 -21
  35. package/src/core/process/worker/extractTransferables.js +2 -2
  36. package/src/engine/Engine.js +58 -53
  37. package/src/engine/EngineConfiguration.d.ts +4 -4
  38. package/src/engine/ecs/EntityManager.js +517 -614
  39. package/src/engine/ecs/System.js +2 -2
  40. package/src/engine/ecs/transform/Transform.d.ts +7 -5
  41. package/src/engine/ecs/transform/Transform.js +30 -16
  42. package/src/engine/ecs/validateSystem.js +89 -0
  43. package/src/engine/graphics/GraphicsEngine.js +433 -483
  44. package/src/engine/graphics/camera/testClippingPlaneComputation.js +46 -48
  45. package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +2 -2
  46. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +2 -2
  47. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +2 -2
  48. package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +60 -62
  49. package/src/engine/graphics/ecs/water2/shader/testWaterShader.js +20 -22
  50. package/src/engine/graphics/particles/particular/engine/ParticularEngine.js +156 -180
  51. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +69 -71
  52. package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +51 -53
  53. package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +67 -69
  54. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +56 -58
  55. package/src/engine/graphics/shadows/testShadowMapRendering.js +30 -34
  56. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.spec.js +22 -20
  57. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_linear.js +10 -13
  58. package/src/engine/graphics/texture/virtual/VirtualTexture.spec.js +1 -1
  59. package/src/engine/plugin/EnginePluginManager.d.ts +6 -1
  60. package/src/engine/ecs/components/ClingToHeightMap.js +0 -19
  61. package/src/engine/ecs/components/SynchronizePosition.js +0 -15
  62. package/src/engine/ecs/systems/ClingToHeightMapSystem.js +0 -170
  63. package/src/engine/ecs/systems/SynchronizePositionSystem.js +0 -43
@@ -2,22 +2,23 @@
2
2
  * Created by Alex on 01/04/2014.
3
3
  */
4
4
 
5
- import { array_copy_unique } from "../../core/collection/array/array_copy_unique.js";
5
+ import {assert} from "../../core/assert.js";
6
+ import {array_copy_unique} from "../../core/collection/array/array_copy_unique.js";
6
7
  import Signal from "../../core/events/signal/Signal.js";
7
- import { computeSystemName, System } from "./System.js";
8
- import { assert } from "../../core/assert.js";
9
- import { EntityObserver } from "./EntityObserver.js";
10
- import { IllegalStateException } from "../../core/fsm/exceptions/IllegalStateException.js";
11
- import { noop } from "../../core/function/Functions.js";
12
- import { ResourceAccessKind } from "../../core/model/ResourceAccessKind.js";
13
- import { computeSystemComponentDependencyGraph } from "./system/computeSystemComponentDependencyGraph.js";
8
+ import {IllegalStateException} from "../../core/fsm/exceptions/IllegalStateException.js";
9
+ import {noop} from "../../core/function/Functions.js";
10
+ import {ResourceAccessKind} from "../../core/model/ResourceAccessKind.js";
11
+ import {EntityObserver} from "./EntityObserver.js";
12
+ import {computeSystemName, System, SystemState} from "./System.js";
13
+ import {computeSystemComponentDependencyGraph} from "./system/computeSystemComponentDependencyGraph.js";
14
+ import {validateSystem} from "./validateSystem.js";
14
15
 
15
16
  /**
16
17
  *
17
18
  * @enum {string}
18
19
  * @readonly
19
20
  */
20
- const EventType = {
21
+ export const EventType = {
21
22
  EntityRemoved: "entityRemoved",
22
23
  ComponentAdded: "componentAdded",
23
24
  ComponentRemoved: "componentRemoved"
@@ -36,33 +37,30 @@ export const EntityManagerState = {
36
37
  Stopped: 5
37
38
  };
38
39
 
39
- /**
40
- *
41
- * @constructor
42
- */
43
- function EntityManager() {
40
+ export class EntityManager {
41
+
44
42
  /**
45
43
  * @readonly
46
44
  * @type {System[]}
47
45
  */
48
- this.systems = [];
46
+ systems = [];
49
47
 
50
48
  /**
51
49
  * @readonly
52
50
  * @type {System[]}
53
51
  */
54
- this.systemsExecutionOrder = [];
52
+ systemsExecutionOrder = [];
55
53
 
56
54
  /**
57
55
  * @readonly
58
56
  * @type {EntityObserver[]}
59
57
  */
60
- this.systemObservers = [];
58
+ systemObservers = [];
61
59
 
62
60
  /**
63
61
  * @readonly
64
62
  */
65
- this.on = {
63
+ on = {
66
64
  systemStarted: new Signal(),
67
65
  systemStopped: new Signal(),
68
66
  systemAdded: new Signal(),
@@ -73,819 +71,724 @@ function EntityManager() {
73
71
  *
74
72
  * @type {EntityManagerState}
75
73
  */
76
- this.state = EntityManagerState.Initial;
74
+ state = EntityManagerState.Initial;
77
75
 
78
76
  /**
79
77
  * @private
80
78
  * @readonly
81
79
  * @type {Map<System, number>}
82
80
  */
83
- this.systemAccumulatedFixedStepTime = new Map();
81
+ systemAccumulatedFixedStepTime = new Map();
84
82
 
85
83
  /**
84
+ * Value used to execute {@link System#fixedUpdate}
86
85
  * In seconds
87
86
  * @type {number}
88
87
  */
89
- this.fixedUpdateStepSize = 0.015;
88
+ fixedUpdateStepSize = 0.015;
90
89
 
91
90
  /**
92
91
  *
93
92
  * @type {EntityComponentDataset}
94
93
  */
95
- this.dataset = null;
94
+ dataset = null;
96
95
 
97
96
  /**
98
97
  *
99
98
  * @type {boolean}
100
99
  * @private
101
100
  */
102
- this.__execution_order_needs_update = true;
103
- }
104
-
105
- /**
106
- * Rebuild execution order
107
- */
108
- EntityManager.prototype.updateExecutionOrder = function () {
109
- // console.time('updateExecutionOrder')
110
-
111
- const order = this.systemsExecutionOrder;
112
-
113
- order.splice(0, order.length);
114
-
115
- const systems = this.systems;
116
- const system_count = systems.length;
117
-
118
- let executable_system_count = 0;
119
-
120
- for (let i = 0; i < system_count; i++) {
121
- const system = systems[i];
122
-
123
- if (system.update === noop && system.fixedUpdate === noop) {
124
- // not a simulation system
125
- continue;
126
- }
127
-
128
- order[executable_system_count++] = system;
129
- }
130
-
131
- // build dependency graphs amongst components
132
- const dependency_graph = computeSystemComponentDependencyGraph(executable_system_count, order);
133
-
101
+ __execution_order_needs_update = true;
134
102
 
135
103
  /**
136
- *
137
- * @param {System} system
138
- * @returns {number} higher values means it should be scheduled before others
104
+ * Rebuild execution order
105
+ * @private
139
106
  */
140
- function scoreSystem(system) {
141
- let result = 0;
142
-
143
- const components = system.referenced_components;
144
- const component_count = components.length;
107
+ updateExecutionOrder() {
108
+ // console.time('updateExecutionOrder')
145
109
 
146
- for (let i = 0; i < component_count; i++) {
147
- const component = components[i];
110
+ const order = this.systemsExecutionOrder;
148
111
 
149
- result += 0.0001;
112
+ order.splice(0, order.length);
150
113
 
114
+ const systems = this.systems;
115
+ const system_count = systems.length;
151
116
 
152
- // count number of incoming edges
153
- const attached_edge_count = dependency_graph.getNodeContainer(component).getIncomingEdgeCount();
117
+ let executable_system_count = 0;
154
118
 
155
- const access = system.getAccessForComponent(component);
119
+ for (let i = 0; i < system_count; i++) {
120
+ const system = systems[i];
156
121
 
157
- if ((access & ResourceAccessKind.Create) !== 0) {
158
- result += attached_edge_count * 4
159
- } else if ((access & ResourceAccessKind.Write) !== 0) {
160
- result += attached_edge_count * 2
161
- } else {
162
- result += attached_edge_count;
122
+ if (system.update === noop && system.fixedUpdate === noop) {
123
+ // not a simulation system
124
+ continue;
163
125
  }
164
126
 
127
+ order[executable_system_count++] = system;
165
128
  }
166
129
 
167
- return result;
168
- }
130
+ // build dependency graphs amongst components
131
+ const dependency_graph = computeSystemComponentDependencyGraph(executable_system_count, order);
169
132
 
170
- // pre-score systems for faster sorting
171
- const scores = new Map();
172
133
 
173
- for (let i = 0; i < executable_system_count; i++) {
174
- const system = order[i];
134
+ /**
135
+ *
136
+ * @param {System} system
137
+ * @returns {number} higher values means it should be scheduled before others
138
+ */
139
+ function scoreSystem(system) {
140
+ let result = 0;
175
141
 
176
- scores.set(system, scoreSystem(system));
177
- }
142
+ const components = system.referenced_components;
143
+ const component_count = components.length;
178
144
 
179
- order.sort((a, b) => {
180
- return scores.get(b) - scores.get(a);
181
- });
145
+ for (let i = 0; i < component_count; i++) {
146
+ const component = components[i];
182
147
 
183
- // clear update flag
184
- this.__execution_order_needs_update = false;
185
- // console.timeEnd('updateExecutionOrder')
186
- };
148
+ result += 0.0001;
187
149
 
188
- EntityManager.prototype.detachDataSet = function () {
189
- const dataset = this.dataset;
190
150
 
191
- if (dataset === null) {
192
- //no dataset attached
193
- return;
194
- }
151
+ // count number of incoming edges
152
+ const attached_edge_count = dependency_graph.getNodeContainer(component).getIncomingEdgeCount();
195
153
 
196
- //remove system observers
197
- this.systemObservers.forEach(function (observer) {
198
- dataset.removeObserver(observer, true);
199
- });
154
+ const access = system.getAccessForComponent(component);
200
155
 
201
- this.dataset = null;
202
- };
156
+ if ((access & ResourceAccessKind.Create) !== 0) {
157
+ result += attached_edge_count * 4
158
+ } else if ((access & ResourceAccessKind.Write) !== 0) {
159
+ result += attached_edge_count * 2
160
+ } else {
161
+ result += attached_edge_count;
162
+ }
203
163
 
204
- /**
205
- * Get list of all components referenced by active systems
206
- * @returns {Class[]}
207
- */
208
- EntityManager.prototype.getComponentTypeMap = function () {
209
- const componentTypes = [];
164
+ }
210
165
 
211
- const systems = this.systems;
166
+ return result;
167
+ }
212
168
 
213
- const systemCount = systems.length;
169
+ // pre-score systems for faster sorting
170
+ const scores = new Map();
214
171
 
215
- for (let i = 0; i < systemCount; i++) {
216
- /**
217
- *
218
- * @type {System}
219
- */
220
- const system = systems[i];
172
+ for (let i = 0; i < executable_system_count; i++) {
173
+ const system = order[i];
221
174
 
175
+ scores.set(system, scoreSystem(system));
176
+ }
222
177
 
223
- const referencedComponents = system.referenced_components;
178
+ order.sort((a, b) => {
179
+ return scores.get(b) - scores.get(a);
180
+ });
224
181
 
225
- array_copy_unique(referencedComponents, 0, componentTypes, componentTypes.length, referencedComponents.length);
182
+ // clear update flag
183
+ this.__execution_order_needs_update = false;
184
+ // console.timeEnd('updateExecutionOrder')
226
185
  }
227
186
 
228
- return componentTypes;
229
- };
230
-
231
- /**
232
- *
233
- * @param {EntityComponentDataset} dataset
234
- * @throws {Error} if another dataset is attached
235
- * @throws {Error} if dataset is incompatible with current system set
236
- */
237
- EntityManager.prototype.attachDataSet = function (dataset) {
238
- //check if another dataset is attached
239
- if (this.dataset !== null) {
187
+ detachDataSet() {
188
+ const dataset = this.dataset;
240
189
 
241
- if (this.dataset === dataset) {
242
- // special case, we already have this dataset attached. Nothing to more to do
190
+ if (dataset === null) {
191
+ //no dataset attached
243
192
  return;
244
193
  }
245
194
 
246
- throw new Error("Illegal status, another dataset is currently attached");
247
- }
248
-
249
- const localComponentTypeMap = this.getComponentTypeMap();
250
-
251
- //ensure compatibility with system-used component map
252
- dataset.registerManyComponentTypes(localComponentTypeMap);
253
-
254
- this.dataset = dataset;
255
-
256
- this.systemObservers.forEach(function (observer) {
257
- dataset.addObserver(observer, true);
258
- });
259
- };
260
-
195
+ //remove system observers
196
+ this.systemObservers.forEach(function (observer) {
197
+ dataset.removeObserver(observer, true);
198
+ });
261
199
 
262
- /**
263
- * @template T
264
- * @param {Class<T>} systemClass
265
- * @returns {boolean}
266
- */
267
- EntityManager.prototype.hasSystem = function (systemClass) {
268
- return this.getSystem(systemClass) !== null;
269
- };
200
+ this.dataset = null;
201
+ }
270
202
 
271
- /**
272
- * @template T
273
- * @param {Class<T>} systemClass
274
- * @returns {T|null}
275
- */
276
- EntityManager.prototype.getSystem = function (systemClass) {
277
- const systems = this.systems;
278
- const numSystems = systems.length;
203
+ /**
204
+ * Get list of all components referenced by active systems
205
+ * @returns {Class[]}
206
+ */
207
+ getComponentTypeMap() {
208
+ const componentTypes = [];
279
209
 
280
- for (let i = 0; i < numSystems; i++) {
281
- const system = systems[i];
210
+ const systems = this.systems;
282
211
 
283
- if (system instanceof systemClass) {
284
- return system;
285
- }
286
- }
212
+ const systemCount = systems.length;
287
213
 
288
- //not found
289
- return null;
290
- };
214
+ for (let i = 0; i < systemCount; i++) {
215
+ /**
216
+ *
217
+ * @type {System}
218
+ */
219
+ const system = systems[i];
291
220
 
292
221
 
293
- /**
294
- * @deprecated use {@link EntityComponentDataset.getComponentClassByName} instead
295
- * @template T
296
- * @param {string} className
297
- * @returns {null|Class<T>}
298
- */
299
- EntityManager.prototype.getComponentClassByName = function (className) {
300
- const componentTypes = this.getComponentTypeMap();
222
+ const referencedComponents = system.referenced_components;
301
223
 
302
- let i = 0;
303
- const l = componentTypes.length;
304
- for (; i < l; i++) {
305
- const componentClass = componentTypes[i];
306
- const name = componentClass.typeName;
307
- if (name === className) {
308
- return componentClass;
224
+ array_copy_unique(referencedComponents, 0, componentTypes, componentTypes.length, referencedComponents.length);
309
225
  }
310
- }
311
- return null;
312
- };
313
226
 
314
- /**
315
- * Advance simulation forward by a specified amount of time
316
- * @param {number} timeDelta in seconds, real number
317
- */
318
- EntityManager.prototype.simulate = function (timeDelta) {
319
- assert.isNumber(timeDelta, 'timeDelta');
320
- assert.notNaN(timeDelta, 'timeDelta');
321
- assert.greaterThanOrEqual(timeDelta, 0, 'timeDelta must be >= 0');
322
-
323
- if (this.__execution_order_needs_update) {
324
- this.updateExecutionOrder();
227
+ return componentTypes;
325
228
  }
326
229
 
327
-
328
230
  /**
329
231
  *
330
- * @type {System[]}
232
+ * @param {EntityComponentDataset} dataset
233
+ * @throws {Error} if another dataset is attached
234
+ * @throws {Error} if dataset is incompatible with current system set
331
235
  */
332
- const systems = this.systems;
236
+ attachDataSet(dataset) {
237
+ //check if another dataset is attached
238
+ if (this.dataset !== null) {
333
239
 
334
- const system_count = systems.length;
240
+ if (this.dataset === dataset) {
241
+ // special case, we already have this dataset attached. Nothing to more to do
242
+ return;
243
+ }
335
244
 
336
- const fixed_step = this.fixedUpdateStepSize;
337
- const accumulatedTime = this.systemAccumulatedFixedStepTime;
245
+ throw new Error("Illegal status, another dataset is currently attached");
246
+ }
338
247
 
339
- assert.notNaN(fixed_step, 'fixed_step');
340
- assert.greaterThan(fixed_step, 0, 'fixed_step must be greater than 0');
248
+ const localComponentTypeMap = this.getComponentTypeMap();
341
249
 
342
- for (let i = 0; i < system_count; i++) {
250
+ //ensure compatibility with system-used component map
251
+ dataset.registerManyComponentTypes(localComponentTypeMap);
343
252
 
344
- const system = systems[i];
253
+ this.dataset = dataset;
345
254
 
346
- if (system.fixedUpdate !== noop) {
347
- let accumulated_time = accumulatedTime.get(system) + timeDelta;
255
+ this.systemObservers.forEach(function (observer) {
256
+ dataset.addObserver(observer, true);
257
+ });
258
+ }
348
259
 
260
+ /**
261
+ * @template T
262
+ * @param {Class<T>} systemClass
263
+ * @returns {boolean}
264
+ */
265
+ hasSystem(systemClass) {
266
+ return this.getSystem(systemClass) !== null;
267
+ }
349
268
 
350
- while (accumulated_time >= fixed_step) {
269
+ /**
270
+ * @template T
271
+ * @param {Class<T>} systemClass
272
+ * @returns {T|null}
273
+ */
274
+ getSystem(systemClass) {
275
+ const systems = this.systems;
276
+ const numSystems = systems.length;
351
277
 
352
- try {
353
- system.fixedUpdate(fixed_step)
354
- } catch (e) {
355
- console.error(`Failed during fixedUpdate of system '${computeSystemName(system)}': `, e);
356
- }
278
+ for (let i = 0; i < numSystems; i++) {
279
+ const system = systems[i];
357
280
 
358
- accumulated_time -= fixed_step;
281
+ if (system instanceof systemClass) {
282
+ return system;
359
283
  }
360
-
361
- // record whatever remains
362
- accumulatedTime.set(system, accumulated_time);
363
-
364
284
  }
365
285
 
366
- if (system.update !== noop) {
286
+ //not found
287
+ return null;
288
+ }
367
289
 
368
- try {
369
- system.update(timeDelta);
370
- } catch (e) {
371
- console.error(`Failed during update of system '${computeSystemName(system)}': `, e);
290
+ /**
291
+ * @deprecated use {@link EntityComponentDataset.getComponentClassByName} instead
292
+ * @template T
293
+ * @param {string} className
294
+ * @returns {null|Class<T>}
295
+ */
296
+ getComponentClassByName(className) {
297
+ const componentTypes = this.getComponentTypeMap();
298
+
299
+ let i = 0;
300
+ const l = componentTypes.length;
301
+ for (; i < l; i++) {
302
+ const componentClass = componentTypes[i];
303
+ const name = componentClass.typeName;
304
+ if (name === className) {
305
+ return componentClass;
372
306
  }
373
-
374
307
  }
375
-
308
+ return null;
376
309
  }
377
- };
378
310
 
379
- /**
380
- *
381
- * @param {System} system
382
- * @throws if system fails validation
383
- */
384
- function validateSystem(system) {
385
- if (system === undefined) {
386
- throw new Error("System is undefined");
387
- }
311
+ /**
312
+ * Advance simulation forward by a specified amount of time
313
+ * @param {number} timeDelta in seconds
314
+ */
315
+ simulate(timeDelta) {
316
+ assert.isNumber(timeDelta, 'timeDelta');
317
+ assert.notNaN(timeDelta, 'timeDelta');
318
+ assert.greaterThanOrEqual(timeDelta, 0, 'timeDelta must be >= 0');
388
319
 
389
- if (system === null) {
390
- throw new Error("System is null");
391
- }
320
+ if (this.__execution_order_needs_update) {
321
+ this.updateExecutionOrder();
322
+ }
392
323
 
393
- if (!(system instanceof System)) {
394
- throw new TypeError("System does not inherit from \"System\" class");
395
- }
396
324
 
397
- if (typeof system.add === "function") {
398
- throw new Error(`uses deprecated 'add' method, should use 'link' instead`);
399
- }
325
+ /**
326
+ *
327
+ * @type {System[]}
328
+ */
329
+ const systems = this.systems;
400
330
 
401
- if (typeof system.remove === "function") {
402
- throw new Error(`uses deprecated 'remove' method, should use 'unlink' instead`);
403
- }
331
+ const system_count = systems.length;
404
332
 
405
- // validate 'components_used' section
406
- const components_used = system.components_used;
407
- const components_used_count = components_used.length;
333
+ const fixed_step = this.fixedUpdateStepSize;
334
+ const accumulatedTime = this.systemAccumulatedFixedStepTime;
408
335
 
409
- for (let i = 0; i < components_used_count; i++) {
410
- const spec = components_used[i];
336
+ assert.notNaN(fixed_step, 'fixed_step');
337
+ assert.greaterThan(fixed_step, 0, 'fixed_step must be greater than 0');
411
338
 
412
- if (spec === undefined || spec === null || spec.isResourceAccessSpecification !== true) {
413
- throw new Error(`Invalid access specification[${i}], expected an instance of ResourceAccessSpecification, but got something else`);
414
- }
339
+ for (let i = 0; i < system_count; i++) {
415
340
 
416
- if (spec.resource === null) {
417
- throw new Error(`No component specified for element [${i}]`);
418
- }
341
+ const system = systems[i];
419
342
 
420
- if (spec.access === 0) {
421
- throw new Error('No access modifiers specified, must have at least one (such as Read, Write, Create)');
422
- }
343
+ if (system.fixedUpdate !== noop) {
344
+ let accumulated_time = accumulatedTime.get(system) + timeDelta;
423
345
 
424
- // backtrace to make sure there are no duplicates
425
- for (let j = 0; j < i - 1; j++) {
426
- const spec_other = components_used[j];
427
346
 
428
- if (spec_other.resource === spec.resource) {
429
- throw new Error(`Duplicate specification of component [${j}] and [${i}]`);
430
- }
431
- }
432
- }
347
+ while (accumulated_time >= fixed_step) {
433
348
 
434
- //validate dependencies
435
- const dependencies = system.dependencies;
349
+ try {
350
+ system.fixedUpdate(fixed_step)
351
+ } catch (e) {
352
+ console.error(`Failed during fixedUpdate of system '${computeSystemName(system)}': `, e);
353
+ }
436
354
 
437
- const numDependencies = dependencies.length;
355
+ accumulated_time -= fixed_step;
356
+ }
438
357
 
439
- if (numDependencies < 1) {
440
- throw new Error(`A system must declare at least one dependency`);
441
- }
358
+ // record whatever remains
359
+ accumulatedTime.set(system, accumulated_time);
442
360
 
443
- if (numDependencies > 1) {
444
- //check for duplicates
445
- for (let i = 0; i < numDependencies; i++) {
446
- const dependencyA = dependencies[i];
447
- for (let j = i + 1; j < numDependencies; j++) {
448
- if (dependencyA === dependencies[j]) {
449
- throw new Error(`Detected duplicate dependency: ${dependencyA.constructor.typeName}`);
450
- }
451
361
  }
452
- }
453
- }
454
362
 
363
+ if (system.update !== noop) {
455
364
 
456
- const linkArgumentCount = numDependencies + 1;
365
+ try {
366
+ system.update(timeDelta);
367
+ } catch (e) {
368
+ console.error(`Failed during update of system '${computeSystemName(system)}': `, e);
369
+ }
457
370
 
458
- if (system.link !== System.prototype.link && system.link.length !== linkArgumentCount && system.__validation_ignore_link_argument_count !== true) {
459
- throw new Error(`'link' method declares ${system.link.length} instead of expected ${linkArgumentCount} based on it's ${numDependencies} dependencies`);
460
- }
371
+ }
461
372
 
462
- if (system.unlink !== System.prototype.unlink && system.unlink.length !== linkArgumentCount && system.__validation_ignore_link_argument_count !== true) {
463
- throw new Error(`'unlink' method declares ${system.unlink.length} instead of expected ${linkArgumentCount} based on it's ${numDependencies} dependencies`);
373
+ }
464
374
  }
465
- }
466
375
 
376
+ /**
377
+ * If the {@link EntityManager} is already started, the system will be started automatically before being added
378
+ * @param {System} system
379
+ * @returns {Promise}
380
+ * @throws {IllegalStateException}
381
+ */
382
+ addSystem(system) {
383
+ assert.defined(system, "system");
384
+ assert.isInstanceOf(system, System, 'system', 'System');
467
385
 
468
- /**
469
- * If the {@link EntityManager} is already started, the system will be started automatically before being added
470
- * @param {System} system
471
- * @returns {Promise}
472
- * @throws {IllegalStateException}
473
- */
474
- EntityManager.prototype.addSystem = function (system) {
475
- assert.defined(system, "system");
476
- assert.isInstanceOf(system, System, 'system', 'System');
477
-
478
- const existing = this.getSystem(Object.getPrototypeOf(system).constructor);
386
+ const existing = this.getSystem(Object.getPrototypeOf(system).constructor);
479
387
 
480
- if (existing !== null) {
481
- if (existing === system) {
482
- //system already added, do nothing
483
- return Promise.resolve();
484
- } else {
485
- throw new IllegalStateException(`Another instance of system '${computeSystemName(system)}' is already registered`);
388
+ if (existing !== null) {
389
+ if (existing === system) {
390
+ //system already added, do nothing
391
+ return Promise.resolve();
392
+ } else {
393
+ throw new IllegalStateException(`Another instance of system '${computeSystemName(system)}' is already registered`);
394
+ }
486
395
  }
487
- }
488
396
 
489
397
 
490
- try {
491
- validateSystem(system);
492
- } catch (e) {
493
- console.error(`System validation failed '${computeSystemName(system)}' : `, e, system);
494
- }
398
+ try {
399
+ validateSystem(system);
400
+ } catch (e) {
401
+ console.error(`System validation failed '${computeSystemName(system)}' : `, e, system);
402
+ }
495
403
 
496
- //check system state
497
- const systemState = system.state.getValue();
404
+ //check system state
405
+ const systemState = system.state.getValue();
498
406
 
499
- const legalStates = [System.State.INITIAL, System.State.STOPPED];
407
+ const legalStates = [SystemState.INITIAL, SystemState.STOPPED];
500
408
 
501
- if (legalStates.indexOf(systemState) === -1) {
502
- //illegal state
503
- throw new IllegalStateException(`System must be in one of these states: [${legalStates.join(",")}], instead was ${systemState}`);
504
- }
409
+ if (legalStates.indexOf(systemState) === -1) {
410
+ //illegal state
411
+ throw new IllegalStateException(`System must be in one of these states: [${legalStates.join(",")}], instead was ${systemState}`);
412
+ }
505
413
 
506
- const systems = this.systems;
507
- const systemIndex = systems.length;
414
+ const systems = this.systems;
415
+ const systemIndex = systems.length;
508
416
 
509
- systems[systemIndex] = system;
417
+ systems[systemIndex] = system;
510
418
 
511
- // request exec order update
512
- this.__execution_order_needs_update = true;
419
+ // request exec order update
420
+ this.__execution_order_needs_update = true;
513
421
 
514
- //build observer
515
- const linkObserver = new EntityObserver(system.dependencies, system.link, system.unlink, system);
516
- this.systemObservers[systemIndex] = linkObserver;
422
+ //build observer
423
+ const linkObserver = new EntityObserver(system.dependencies, system.link, system.unlink, system);
424
+ this.systemObservers[systemIndex] = linkObserver;
517
425
 
518
- let startup_promise;
519
- if (this.state === EntityManagerState.Running) {
520
- //initialize the system
521
- startup_promise = new Promise((resolve, reject) => {
522
- this.startSystem(system, resolve, reject);
523
- });
524
- } else {
525
- startup_promise = Promise.resolve();
526
- }
426
+ let startup_promise;
427
+ if (this.state === EntityManagerState.Running) {
428
+ //initialize the system
429
+ startup_promise = new Promise((resolve, reject) => {
430
+ this.startSystem(system, resolve, reject);
431
+ });
432
+ } else {
433
+ startup_promise = Promise.resolve();
434
+ }
527
435
 
528
- if (this.dataset !== null) {
436
+ if (this.dataset !== null) {
529
437
 
530
- // link dependency components
531
- this.dataset.registerManyComponentTypes(system.referenced_components);
438
+ // link dependency components
439
+ this.dataset.registerManyComponentTypes(system.referenced_components);
532
440
 
533
- this.dataset.addObserver(linkObserver);
534
- }
441
+ this.dataset.addObserver(linkObserver);
442
+ }
535
443
 
536
- this.systemAccumulatedFixedStepTime.set(system, 0);
444
+ this.systemAccumulatedFixedStepTime.set(system, 0);
537
445
 
538
- this.on.systemAdded.send1(system);
446
+ this.on.systemAdded.send1(system);
539
447
 
540
- return startup_promise;
541
- };
448
+ return startup_promise;
449
+ }
542
450
 
543
- /**
544
- *
545
- * @param {System} system
546
- * @returns {Promise<boolean>}
547
- */
548
- EntityManager.prototype.removeSystem = async function (system) {
549
- assert.defined(system, "system");
550
- assert.isInstanceOf(system, System, 'system', 'System');
451
+ /**
452
+ *
453
+ * @param {System} system
454
+ * @returns {Promise<boolean>}
455
+ */
456
+ async removeSystem(system) {
457
+ assert.defined(system, "system");
458
+ assert.isInstanceOf(system, System, 'system', 'System');
551
459
 
552
460
 
553
- const systemIndex = this.systems.indexOf(system);
461
+ const systemIndex = this.systems.indexOf(system);
554
462
 
555
- if (systemIndex === -1) {
556
- //system not found
557
- return false;
558
- }
463
+ if (systemIndex === -1) {
464
+ //system not found
465
+ return false;
466
+ }
559
467
 
560
- //unlink system observer
561
- const systemObserver = this.systemObservers[systemIndex];
562
- this.systemObservers.splice(systemIndex, 1);
468
+ //unlink system observer
469
+ const systemObserver = this.systemObservers[systemIndex];
470
+ this.systemObservers.splice(systemIndex, 1);
563
471
 
564
- assert.notEqual(systemObserver, undefined, "System observer is undefined, it was possibly removed illegally or was not created");
472
+ assert.notEqual(systemObserver, undefined, "System observer is undefined, it was possibly removed illegally or was not created");
565
473
 
566
474
 
567
- //shutdown system
568
- this.systems.splice(systemIndex, 1);
475
+ //shutdown system
476
+ this.systems.splice(systemIndex, 1);
569
477
 
570
- // request exec order update
571
- this.__execution_order_needs_update = true;
478
+ // request exec order update
479
+ this.__execution_order_needs_update = true;
572
480
 
573
- if (this.dataset !== null) {
574
- this.dataset.removeObserver(systemObserver);
575
- }
481
+ if (this.dataset !== null) {
482
+ this.dataset.removeObserver(systemObserver);
483
+ }
576
484
 
577
- await new Promise((resolve, reject) => {
578
- this.stopSystem(system, resolve, (reason) => {
485
+ await new Promise((resolve, reject) => {
486
+ this.stopSystem(system, resolve, (reason) => {
579
487
 
580
- reject(`system ${computeSystemName(system)} shutdown failed: ${reason}`);
488
+ reject(`system ${computeSystemName(system)} shutdown failed: ${reason}`);
489
+ });
581
490
  });
582
- });
583
491
 
584
- this.systemAccumulatedFixedStepTime.delete(system);
492
+ this.systemAccumulatedFixedStepTime.delete(system);
585
493
 
586
- this.on.systemRemoved.send1(system);
494
+ this.on.systemRemoved.send1(system);
587
495
 
588
- return true;
589
- };
496
+ return true;
497
+ }
590
498
 
499
+ /**
500
+ * @private
501
+ * @param {System} system
502
+ * @param {function(system: System)} successCallback
503
+ * @param {function(reason:*)} errorCallback
504
+ */
505
+ stopSystem(system, successCallback, errorCallback) {
506
+ const self = this;
591
507
 
592
- /**
593
- * @private
594
- * @param {System} system
595
- * @param {function(system: System)} successCallback
596
- * @param {function(reason:*)} errorCallback
597
- */
598
- EntityManager.prototype.stopSystem = function (system, successCallback, errorCallback) {
599
- const self = this;
600
-
601
- try {
602
- system.state.set(System.State.STOPPING);
603
- } catch (e) {
604
- console.error(`Failed to set system state to STOPPING`, e);
605
- errorCallback(e);
606
- return;
607
- }
508
+ try {
509
+ system.state.set(SystemState.STOPPING);
510
+ } catch (e) {
511
+ console.error(`Failed to set system state to STOPPING`, e);
512
+ errorCallback(e);
513
+ return;
514
+ }
608
515
 
609
- function systemReady() {
610
- system.state.set(System.State.STOPPED);
516
+ function systemReady() {
517
+ system.state.set(SystemState.STOPPED);
611
518
 
612
- self.on.systemStopped.send1(system);
519
+ self.on.systemStopped.send1(system);
613
520
 
614
- successCallback(system);
615
- }
521
+ successCallback(system);
522
+ }
616
523
 
617
- function systemFailed(reason) {
618
- errorCallback(reason);
619
- }
524
+ function systemFailed(reason) {
525
+ errorCallback(reason);
526
+ }
620
527
 
621
- try {
622
- system.shutdown(self, systemReady, systemFailed);
623
- } catch (e) {
624
- console.error(`Failed to execute system shutdown`, e);
625
- errorCallback(e);
528
+ try {
529
+ system.shutdown(self, systemReady, systemFailed);
530
+ } catch (e) {
531
+ console.error(`Failed to execute system shutdown`, e);
532
+ errorCallback(e);
533
+ }
626
534
  }
627
- };
628
535
 
629
- /**
630
- * @private
631
- * @param {System} system
632
- * @param {function(system: System)} successCallback
633
- * @param {function(reason:*)} errorCallback
634
- */
635
- EntityManager.prototype.startSystem = function (system, successCallback, errorCallback) {
636
- assert.defined(system, "system");
637
- assert.isFunction(successCallback, "successCallback");
638
- assert.isFunction(errorCallback, "errorCallback");
639
-
640
- if (system.state.getValue() === System.State.RUNNING) {
641
- //system is already running
642
- console.warn(`System '${computeSystemName(system)}' is already running, nothing to do`);
643
- successCallback(system);
644
- return;
645
- }
536
+ /**
537
+ * @private
538
+ * @param {System} system
539
+ * @param {function(system: System)} successCallback
540
+ * @param {function(reason:*)} errorCallback
541
+ */
542
+ startSystem(system, successCallback, errorCallback) {
543
+ assert.defined(system, "system");
544
+ assert.isFunction(successCallback, "successCallback");
545
+ assert.isFunction(errorCallback, "errorCallback");
546
+
547
+ if (system.state.getValue() === SystemState.RUNNING) {
548
+ //system is already running
549
+ console.warn(`System '${computeSystemName(system)}' is already running, nothing to do`);
550
+ successCallback(system);
551
+ return;
552
+ }
646
553
 
647
- const self = this;
554
+ const self = this;
648
555
 
649
- try {
650
- system.state.set(System.State.STARTING);
651
- } catch (e) {
652
- console.error(`Failed to set system state to STARTING`, e);
653
- errorCallback(e);
654
- return;
655
- }
556
+ try {
557
+ system.state.set(SystemState.STARTING);
558
+ } catch (e) {
559
+ console.error(`Failed to set system state to STARTING`, e);
560
+ errorCallback(e);
561
+ return;
562
+ }
656
563
 
657
- function systemReady() {
658
- system.state.set(System.State.RUNNING);
564
+ function systemReady() {
565
+ system.state.set(SystemState.RUNNING);
659
566
 
660
- self.on.systemStarted.dispatch(system);
567
+ self.on.systemStarted.dispatch(system);
661
568
 
662
- successCallback(system);
663
- }
569
+ successCallback(system);
570
+ }
664
571
 
665
- function systemFailed(reason) {
666
- errorCallback(reason);
667
- }
572
+ function systemFailed(reason) {
573
+ errorCallback(reason);
574
+ }
668
575
 
669
- try {
670
- system.startup(self, systemReady, systemFailed);
671
- } catch (e) {
672
- console.error(`Failed to execute system startup`, e);
673
- systemFailed(e);
576
+ try {
577
+ system.startup(self, systemReady, systemFailed);
578
+ } catch (e) {
579
+ console.error(`Failed to execute system startup`, e);
580
+ systemFailed(e);
581
+ }
674
582
  }
675
- };
676
583
 
677
- /**
678
- *
679
- * @param {function} readyCallback executed once entity manager successfully completes startup
680
- * @param {function} errorCallback executed if entity manager encounters an error during startup
681
- */
682
- EntityManager.prototype.startup = function (readyCallback, errorCallback) {
683
- if (this.state === EntityManagerState.Starting) {
684
- throw new IllegalStateException(`System is currently in starting state`);
685
- }
584
+ /**
585
+ *
586
+ * @param {function} readyCallback executed once entity manager successfully completes startup
587
+ * @param {function} errorCallback executed if entity manager encounters an error during startup
588
+ */
589
+ startup(readyCallback, errorCallback) {
590
+ if (this.state === EntityManagerState.Starting) {
591
+ throw new IllegalStateException(`System is currently in starting state`);
592
+ }
686
593
 
687
- if (this.state === EntityManagerState.Running) {
688
- // already running, do nothing
689
- readyCallback();
690
- return;
691
- }
594
+ if (this.state === EntityManagerState.Running) {
595
+ // already running, do nothing
596
+ readyCallback();
597
+ return;
598
+ }
692
599
 
693
- assert.isFunction(readyCallback, 'readyCallback');
694
- assert.isFunction(errorCallback, 'errorCallback');
600
+ assert.isFunction(readyCallback, 'readyCallback');
601
+ assert.isFunction(errorCallback, 'errorCallback');
695
602
 
696
- this.state = EntityManagerState.Starting;
603
+ this.state = EntityManagerState.Starting;
697
604
 
698
- const self = this;
699
- const systems = this.systems;
700
- let readyCount = 0;
701
- const expectedReadyCount = systems.length;
605
+ const self = this;
606
+ const systems = this.systems;
607
+ let readyCount = 0;
608
+ const expectedReadyCount = systems.length;
702
609
 
703
- console.log(`EntityManager startup initialized, starting ${expectedReadyCount} systems.`);
610
+ console.log(`EntityManager startup initialized, starting ${expectedReadyCount} systems.`);
704
611
 
705
- function finalizeStartup() {
706
- self.state = EntityManagerState.Running;
612
+ function finalizeStartup() {
613
+ self.state = EntityManagerState.Running;
707
614
 
708
- console.log(`EntityManager startup finished, all systems started`);
709
- try {
710
- readyCallback();
711
- } catch (e) {
712
- console.error("All systems were started OK, but readyCallback failed.", e);
615
+ console.log(`EntityManager startup finished, all systems started`);
616
+ try {
617
+ readyCallback();
618
+ } catch (e) {
619
+ console.error("All systems were started OK, but readyCallback failed.", e);
620
+ }
713
621
  }
714
- }
715
622
 
716
- function systemReady() {
717
- //startup all systems
718
- readyCount++;
623
+ function systemReady() {
624
+ //startup all systems
625
+ readyCount++;
719
626
 
720
- if (readyCount === expectedReadyCount) {
721
- finalizeStartup();
627
+ if (readyCount === expectedReadyCount) {
628
+ finalizeStartup();
629
+ }
722
630
  }
723
- }
724
631
 
725
- let firstFailure = true;
632
+ let firstFailure = true;
726
633
 
727
- function systemError(system, error) {
728
- console.error("Failed to start system", system, 'Error:', error);
634
+ function systemError(system, error) {
635
+ console.error("Failed to start system", system, 'Error:', error);
729
636
 
730
- if (firstFailure) {
731
- firstFailure = false;
637
+ if (firstFailure) {
638
+ firstFailure = false;
732
639
 
733
- self.state = EntityManagerState.Failed;
640
+ self.state = EntityManagerState.Failed;
734
641
 
735
- errorCallback(error);
642
+ errorCallback(error);
643
+ }
736
644
  }
737
- }
738
645
 
739
- if (expectedReadyCount === 0) {
740
- //no systems registered, we're done
741
- finalizeStartup();
742
- return;
743
- }
646
+ if (expectedReadyCount === 0) {
647
+ //no systems registered, we're done
648
+ finalizeStartup();
649
+ return;
650
+ }
744
651
 
745
- systems.forEach(function (system) {
746
- //ensure eventManager are there
747
- //start the system
748
- const cbOK = systemReady.bind(null, system);
749
- const cbError = systemError.bind(null, system);
652
+ systems.forEach(function (system) {
653
+ //ensure eventManager are there
654
+ //start the system
655
+ const cbOK = systemReady.bind(null, system);
656
+ const cbError = systemError.bind(null, system);
750
657
 
751
- self.startSystem(system, cbOK, cbError);
658
+ self.startSystem(system, cbOK, cbError);
752
659
 
753
- });
754
- };
660
+ });
661
+ }
755
662
 
756
- /**
757
- *
758
- * @param {Class} systemClass
759
- * @returns {Promise.<System>}
760
- */
761
- EntityManager.prototype.promiseSystem = function (systemClass) {
762
663
  /**
763
664
  *
764
- * @type {EntityManager}
665
+ * @param {Class} systemClass
666
+ * @returns {Promise.<System>}
765
667
  */
766
- const em = this;
668
+ promiseSystem(systemClass) {
669
+ /**
670
+ *
671
+ * @type {EntityManager}
672
+ */
673
+ const em = this;
767
674
 
768
- return new Promise(function (resolve, reject) {
675
+ return new Promise(function (resolve, reject) {
769
676
 
770
- function systemAdded(s) {
771
- if (s instanceof systemClass) {
772
- //unregister listener
773
- em.on.systemAdded.remove(systemAdded);
774
- resolve(s);
677
+ function systemAdded(s) {
678
+ if (s instanceof systemClass) {
679
+ //unregister listener
680
+ em.on.systemAdded.remove(systemAdded);
681
+ resolve(s);
682
+ }
775
683
  }
776
- }
777
684
 
778
- const system = em.getSystem(systemClass);
779
- if (system !== null) {
780
- resolve(system);
781
- } else {
782
- em.on.systemAdded.add(systemAdded);
783
- }
784
- });
785
- };
685
+ const system = em.getSystem(systemClass);
686
+ if (system !== null) {
687
+ resolve(system);
688
+ } else {
689
+ em.on.systemAdded.add(systemAdded);
690
+ }
691
+ });
692
+ }
786
693
 
787
- /**
788
- *
789
- * @param {Class} systemClass
790
- * @param {System.State} state
791
- * @returns {Promise.<System>}
792
- */
793
- EntityManager.prototype.promiseSystemInState = function (systemClass, state) {
794
- const em = this;
694
+ /**
695
+ *
696
+ * @param {Class} systemClass
697
+ * @param {SystemState} state
698
+ * @returns {Promise.<System>}
699
+ */
700
+ promiseSystemInState(systemClass, state) {
701
+ const em = this;
795
702
 
796
- return new Promise(function (resolve, reject) {
703
+ return new Promise(function (resolve, reject) {
797
704
 
798
- const pSystem = em.promiseSystem(systemClass);
705
+ const pSystem = em.promiseSystem(systemClass);
799
706
 
800
- pSystem.then(function (system) {
801
- function tryProcessSystem() {
802
- if (system.state.get() !== state) {
803
- system.state.onChanged.addOne(tryProcessSystem);
804
- } else {
805
- resolve(system);
707
+ pSystem.then(function (system) {
708
+ function tryProcessSystem() {
709
+ if (system.state.get() !== state) {
710
+ system.state.onChanged.addOne(tryProcessSystem);
711
+ } else {
712
+ resolve(system);
713
+ }
806
714
  }
807
- }
808
715
 
809
- tryProcessSystem();
810
- }, reject);
716
+ tryProcessSystem();
717
+ }, reject);
811
718
 
812
- });
813
- };
719
+ });
720
+ }
814
721
 
815
- /**
816
- *
817
- * @param {function} readyCallback
818
- * @param {function} errorCallback
819
- */
820
- EntityManager.prototype.shutdown = function (readyCallback, errorCallback) {
821
- this.state = EntityManagerState.Stopping;
722
+ /**
723
+ *
724
+ * @param {function} readyCallback
725
+ * @param {function} errorCallback
726
+ */
727
+ shutdown(readyCallback, errorCallback) {
728
+ this.state = EntityManagerState.Stopping;
822
729
 
823
- if (this.dataset !== null) {
824
- // a dataset is still attached, to properly dispose of all the component-bound resources, we first detach the dataset
825
- this.detachDataSet();
826
- }
730
+ if (this.dataset !== null) {
731
+ // a dataset is still attached, to properly dispose of all the component-bound resources, we first detach the dataset
732
+ this.detachDataSet();
733
+ }
827
734
 
828
- const self = this;
829
- const systems = this.systems;
830
- let readyCount = 0;
831
- const expectedReadyCount = systems.length;
735
+ const self = this;
736
+ const systems = this.systems;
737
+ let readyCount = 0;
738
+ const expectedReadyCount = systems.length;
832
739
 
833
- function finalizeShutdown() {
834
- self.state = EntityManagerState.Stopped;
740
+ function finalizeShutdown() {
741
+ self.state = EntityManagerState.Stopped;
835
742
 
836
- try {
837
- readyCallback();
838
- } catch (e) {
839
- console.error("All systems were shutdown OK, but readyCallback failed.", e);
743
+ try {
744
+ readyCallback();
745
+ } catch (e) {
746
+ console.error("All systems were shutdown OK, but readyCallback failed.", e);
747
+ }
840
748
  }
841
- }
842
749
 
843
- function systemReady(system) {
844
- //startup all systems
845
- readyCount++;
750
+ function systemReady(system) {
751
+ //startup all systems
752
+ readyCount++;
846
753
 
847
- system.state.set(System.State.STOPPED);
754
+ system.state.set(SystemState.STOPPED);
848
755
 
849
- self.on.systemStopped.send1(system);
850
- if (readyCount === expectedReadyCount) {
851
- finalizeShutdown();
756
+ self.on.systemStopped.send1(system);
757
+ if (readyCount === expectedReadyCount) {
758
+ finalizeShutdown();
759
+ }
852
760
  }
853
- }
854
761
 
855
- let firstFailure = true;
762
+ let firstFailure = true;
856
763
 
857
- function systemError(system) {
858
- console.error("Failed to shutdown system", system);
764
+ function systemError(system) {
765
+ console.error("Failed to shutdown system", system);
859
766
 
860
- if (firstFailure) {
861
- firstFailure = false;
767
+ if (firstFailure) {
768
+ firstFailure = false;
862
769
 
863
- self.state = EntityManagerState.Failed;
770
+ self.state = EntityManagerState.Failed;
864
771
 
865
- errorCallback();
772
+ errorCallback();
773
+ }
866
774
  }
867
- }
868
-
869
- if (expectedReadyCount === 0) {
870
- //no systems registered, we're done
871
- finalizeShutdown();
872
- }
873
775
 
874
- systems.forEach(function (system) {
875
- system.state.set(System.State.STOPPING);
876
- //start the system
877
- const cbOK = systemReady.bind(null, system);
878
- const cbError = systemError.bind(null, system);
879
- try {
880
- system.shutdown(self, cbOK, cbError);
881
- } catch (e) {
882
- //failure in shutdown function
883
- cbError(e);
776
+ if (expectedReadyCount === 0) {
777
+ //no systems registered, we're done
778
+ finalizeShutdown();
884
779
  }
885
- });
886
- };
887
780
 
888
- export {
889
- EventType,
890
- EntityManager
891
- };
781
+ systems.forEach(function (system) {
782
+ system.state.set(SystemState.STOPPING);
783
+ //start the system
784
+ const cbOK = systemReady.bind(null, system);
785
+ const cbError = systemError.bind(null, system);
786
+ try {
787
+ system.shutdown(self, cbOK, cbError);
788
+ } catch (e) {
789
+ //failure in shutdown function
790
+ cbError(e);
791
+ }
792
+ });
793
+ }
794
+ }