@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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
436
|
+
await this.__barrier();
|
|
399
437
|
|
|
400
|
-
|
|
438
|
+
const p = new Promise(async (resolve, reject) => {
|
|
401
439
|
|
|
402
|
-
const
|
|
440
|
+
const n = actions.length;
|
|
403
441
|
|
|
404
|
-
|
|
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.
|
|
463
|
+
await this.__barrier();
|
|
415
464
|
|
|
416
|
-
|
|
465
|
+
const p = this.__unsafe_do(action);
|
|
417
466
|
|
|
418
|
-
|
|
467
|
+
this.__last_promise = p;
|
|
419
468
|
|
|
420
|
-
|
|
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
|
|
438
|
-
|
|
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
|
-
|
|
445
|
-
throw new IllegalStateException();
|
|
446
|
-
}
|
|
481
|
+
this.historyMemoryUsage += action.computeByteSize();
|
|
447
482
|
|
|
448
|
-
|
|
483
|
+
const history = this.history;
|
|
449
484
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
8
|
+
"version": "2.37.2",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|