@woosh/meep-engine 2.37.1 → 2.37.2

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.
@@ -9,7 +9,6 @@ import List from "../../collection/list/List.js";
9
9
  import Signal from "../../events/signal/Signal.js";
10
10
  import { min2 } from "../../math/min2.js";
11
11
  import { Mark } from "./Mark.js";
12
- import { IllegalStateException } from "../../fsm/exceptions/IllegalStateException.js";
13
12
 
14
13
  /**
15
14
  * @template C, M
@@ -75,13 +74,6 @@ export class ActionProcessor {
75
74
  */
76
75
  this.onMarkRemoved = new Signal();
77
76
 
78
- /**
79
- *
80
- * @type {boolean}
81
- * @private
82
- */
83
- this.__action_in_progress = false;
84
-
85
77
  /**
86
78
  *
87
79
  * @type {Promise<never>}
@@ -172,10 +164,8 @@ export class ActionProcessor {
172
164
  * Insert a mark into the timeline, all actions between marks are grouped logically for UNDO and REDO mechanism
173
165
  * @param {D} description
174
166
  */
175
- mark(description) {
176
- if (this.__action_in_progress) {
177
- throw new IllegalStateException('Action is currently in progress');
178
- }
167
+ async mark(description) {
168
+ await this.__barrier();
179
169
 
180
170
  const marks = this.marks;
181
171
  const numMarks = marks.length;
@@ -265,6 +255,24 @@ export class ActionProcessor {
265
255
  * @throws {Error} when mark is non-unique
266
256
  */
267
257
  async navigateTo(mark_descriptor) {
258
+ await this.__barrier();
259
+
260
+ const p = this.__unsafe_navigateTo(mark_descriptor);
261
+
262
+ this.__last_promise = p;
263
+
264
+ return await p;
265
+ }
266
+
267
+ /**
268
+ * Navigate to a specific mark back or forward
269
+ * @param {M} mark_descriptor specific mark description
270
+ * @returns {boolean} true on success, false otherwise (e.g. mark not found)
271
+ * @throws {Error} when mark is non-unique
272
+ * @private
273
+ */
274
+ async __unsafe_navigateTo(mark_descriptor) {
275
+
268
276
  // find all matching marks
269
277
  const matching_marks = this.__find_mark_indices_by_description(mark_descriptor);
270
278
 
@@ -293,7 +301,7 @@ export class ActionProcessor {
293
301
 
294
302
  while (target > this.cursor) {
295
303
  // navigate forward
296
- await this.redo();
304
+ await this.__unsafe_redo();
297
305
 
298
306
  if (temp_cursor === this.cursor) {
299
307
  // no cursor change
@@ -307,7 +315,7 @@ export class ActionProcessor {
307
315
 
308
316
  while (target < this.cursor) {
309
317
  // navigate backwards
310
- await this.undo();
318
+ await this.__unsafe_undo();
311
319
 
312
320
  if (temp_cursor === this.cursor) {
313
321
  // no cursor change
@@ -323,6 +331,21 @@ export class ActionProcessor {
323
331
  }
324
332
 
325
333
  async undo() {
334
+ await this.__barrier();
335
+
336
+ const p = this.__unsafe_undo();
337
+
338
+ this.__last_promise = p;
339
+
340
+ await p;
341
+ }
342
+
343
+ /**
344
+ *
345
+ * @returns {Promise<void>}
346
+ * @private
347
+ */
348
+ async __unsafe_undo() {
326
349
  let markAddress = 0;
327
350
  /**
328
351
  *
@@ -351,7 +374,7 @@ export class ActionProcessor {
351
374
  this.cursor--;
352
375
  const action = this.history.get(this.cursor);
353
376
 
354
- await this.__action_revert(action);
377
+ await action.revert(this.context);
355
378
  }
356
379
 
357
380
  if (mark !== null) {
@@ -363,8 +386,23 @@ export class ActionProcessor {
363
386
  * redo previous sequence of actions on the timeline, up to the next mark
364
387
  */
365
388
  async redo() {
389
+ await this.__barrier();
390
+
391
+ const p = this.__unsafe_redo();
366
392
 
393
+ this.__last_promise = p;
394
+
395
+ await p;
396
+ }
397
+
398
+ /**
399
+ *
400
+ * @returns {Promise<void>}
401
+ * @private
402
+ */
403
+ async __unsafe_redo() {
367
404
  let mark = this.history.length;
405
+
368
406
  //find mark
369
407
  const marks = this.marks;
370
408
 
@@ -382,7 +420,7 @@ export class ActionProcessor {
382
420
  while (this.cursor < mark) {
383
421
  const action = this.history.get(this.cursor);
384
422
 
385
- await this.__action_apply(action);
423
+ await action.apply(this.context);
386
424
 
387
425
  this.historyMemoryUsage += action.computeByteSize();
388
426
 
@@ -395,15 +433,26 @@ export class ActionProcessor {
395
433
  * @param {Action[]} actions
396
434
  */
397
435
  async doMany(actions) {
398
- const n = actions.length;
436
+ await this.__barrier();
399
437
 
400
- for (let i = 0; i < n; i++) {
438
+ const p = new Promise(async (resolve, reject) => {
401
439
 
402
- const action = actions[i];
440
+ const n = actions.length;
403
441
 
404
- await this.do(action);
442
+ for (let i = 0; i < n; i++) {
405
443
 
406
- }
444
+ const action = actions[i];
445
+
446
+ await this.__unsafe_do(action);
447
+
448
+ }
449
+
450
+ resolve();
451
+ });
452
+
453
+ this.__last_promise = p;
454
+
455
+ await p;
407
456
  }
408
457
 
409
458
  /**
@@ -411,21 +460,13 @@ export class ActionProcessor {
411
460
  * @param {Action} action
412
461
  */
413
462
  async do(action) {
414
- await this.__action_apply(action);
463
+ await this.__barrier();
415
464
 
416
- this.historyMemoryUsage += action.computeByteSize();
465
+ const p = this.__unsafe_do(action);
417
466
 
418
- const history = this.history;
467
+ this.__last_promise = p;
419
468
 
420
- //doing action invalidates "future" branch of history, we need to clear all actions beyond cursor
421
- if (this.cursor < history.length) {
422
- history.crop(0, this.cursor);
423
- // TODO clear future marks
424
- }
425
-
426
- history.add(action);
427
-
428
- this.cursor++;
469
+ await p;
429
470
  }
430
471
 
431
472
  /**
@@ -434,63 +475,34 @@ export class ActionProcessor {
434
475
  * @returns {Promise<void>}
435
476
  * @private
436
477
  */
437
- async __action_apply(action) {
438
- try {
439
- await this.__last_promise;
440
- } catch (e) {
441
- // ignore
442
- }
478
+ async __unsafe_do(action) {
479
+ await action.apply(this.context);
443
480
 
444
- if (this.__action_in_progress) {
445
- throw new IllegalStateException();
446
- }
481
+ this.historyMemoryUsage += action.computeByteSize();
447
482
 
448
- this.__action_in_progress = true;
483
+ const history = this.history;
449
484
 
450
- let p;
451
- try {
452
- p = action.apply(this.context);
453
- } finally {
454
- this.__action_in_progress = false;
485
+ //doing action invalidates "future" branch of history, we need to clear all actions beyond cursor
486
+ if (this.cursor < history.length) {
487
+ history.crop(0, this.cursor);
488
+ // TODO clear future marks
455
489
  }
456
490
 
457
- if (p !== undefined) {
458
- this.__last_promise = p;
459
- await p;
460
- }
491
+ history.add(action);
461
492
 
493
+ this.cursor++;
462
494
  }
463
495
 
464
496
  /**
465
- *
466
- * @param {Action} action
497
+ * Await for synchronization barrier
467
498
  * @returns {Promise<void>}
468
499
  * @private
469
500
  */
470
- async __action_revert(action) {
501
+ async __barrier() {
471
502
  try {
472
503
  await this.__last_promise;
473
504
  } catch (e) {
474
505
  // ignore
475
506
  }
476
-
477
- if (this.__action_in_progress) {
478
- throw new IllegalStateException();
479
- }
480
-
481
- this.__action_in_progress = true;
482
-
483
- let p;
484
- try {
485
- p = action.revert(this.context);
486
- } finally {
487
- this.__action_in_progress = false;
488
- }
489
-
490
- if (p !== undefined) {
491
- this.__last_promise = p;
492
- await p;
493
- }
494
-
495
507
  }
496
508
  }
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.37.1",
8
+ "version": "2.37.2",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",