@woosh/meep-engine 2.36.30 → 2.37.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.
- package/core/process/undo/Action.d.ts +2 -2
- package/core/process/undo/Action.js +4 -4
- package/core/process/undo/ActionGroup.js +4 -4
- package/core/process/undo/ActionProcessor.d.ts +6 -6
- package/core/process/undo/ActionProcessor.js +106 -16
- package/core/process/undo/ActionProcessor.spec.js +20 -15
- package/editor/actions/concrete/ComponentAddAction.js +2 -2
- package/editor/actions/concrete/ComponentRemoveAction.js +2 -2
- package/editor/actions/concrete/EntityCreateAction.js +2 -2
- package/editor/actions/concrete/EntityRemoveAction.js +2 -2
- package/editor/actions/concrete/PaintTerrainOverlayAction.js +2 -2
- package/editor/actions/concrete/PatchTerrainHeightAction.js +2 -2
- package/editor/actions/concrete/PatchTerrainTextureAction.js +2 -2
- package/editor/actions/concrete/SelectionAddAction.js +2 -2
- package/editor/actions/concrete/SelectionClearAction.js +2 -2
- package/editor/actions/concrete/SelectionRemoveAction.js +2 -2
- package/editor/actions/concrete/TransformModifyAction.js +2 -2
- package/editor/actions/concrete/WriteGridValueAction.js +2 -2
- package/editor/view/EditorView.js +11 -9
- package/package.json +1 -1
|
@@ -21,16 +21,16 @@ export class Action {
|
|
|
21
21
|
* Apply action
|
|
22
22
|
* @param {CTX} context
|
|
23
23
|
*/
|
|
24
|
-
apply(context) {
|
|
25
|
-
|
|
24
|
+
async apply(context) {
|
|
25
|
+
throw new Error('Not Implemented. Needs to be overridden in subclass');
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Revert action, restoring state to just before this action was applied
|
|
30
30
|
* @param {CTX} context
|
|
31
31
|
*/
|
|
32
|
-
revert(context) {
|
|
33
|
-
|
|
32
|
+
async revert(context) {
|
|
33
|
+
throw new Error('Not Implemented. Needs to be overridden in subclass');
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -41,24 +41,24 @@ export class ActionGroup extends Action {
|
|
|
41
41
|
return result;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
apply(context) {
|
|
44
|
+
async apply(context) {
|
|
45
45
|
const members = this.members;
|
|
46
46
|
const n = members.length;
|
|
47
47
|
for (let i = 0; i < n; i++) {
|
|
48
48
|
const action = members[i];
|
|
49
49
|
|
|
50
|
-
action.apply(context);
|
|
50
|
+
await action.apply(context);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
revert(context) {
|
|
54
|
+
async revert(context) {
|
|
55
55
|
const members = this.members;
|
|
56
56
|
const n = members.length;
|
|
57
57
|
|
|
58
58
|
for (let i = n - 1; i >= 0; i--) {
|
|
59
59
|
const action = members[i];
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
await action.revert(context);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -8,20 +8,20 @@ export class ActionProcessor<CTX, MD> {
|
|
|
8
8
|
|
|
9
9
|
getMarkCount(): number
|
|
10
10
|
|
|
11
|
-
getMarkDescription(index: number): MD
|
|
11
|
+
getMarkDescription(index: number): Readonly<MD>
|
|
12
12
|
|
|
13
13
|
readonly onMarkAdded: Signal<MD>
|
|
14
14
|
readonly onMarkRemoved: Signal<MD>
|
|
15
15
|
|
|
16
|
-
undo(): void
|
|
16
|
+
undo(): Promise<void>
|
|
17
17
|
|
|
18
|
-
redo(): void
|
|
18
|
+
redo(): Promise<void>
|
|
19
19
|
|
|
20
|
-
navigateTo(mark: MD): boolean
|
|
20
|
+
navigateTo(mark: MD): Promise<boolean>
|
|
21
21
|
|
|
22
|
-
doMany(actions: Action<CTX>[]): void
|
|
22
|
+
doMany(actions: Action<CTX>[]): Promise<void>
|
|
23
23
|
|
|
24
|
-
do(action: Action<CTX>):
|
|
24
|
+
do(action: Action<CTX>): Promise<void>
|
|
25
25
|
|
|
26
26
|
clear(): void
|
|
27
27
|
}
|
|
@@ -9,6 +9,7 @@ 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";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* @template C, M
|
|
@@ -26,11 +27,13 @@ export class ActionProcessor {
|
|
|
26
27
|
* @type {List<Action>}
|
|
27
28
|
*/
|
|
28
29
|
this.history = new List();
|
|
30
|
+
|
|
29
31
|
/**
|
|
30
32
|
*
|
|
31
33
|
* @type {C}
|
|
32
34
|
*/
|
|
33
35
|
this.context = context;
|
|
36
|
+
|
|
34
37
|
/**
|
|
35
38
|
*
|
|
36
39
|
* @type {Array<Mark<M>>}
|
|
@@ -53,6 +56,7 @@ export class ActionProcessor {
|
|
|
53
56
|
* @type {number}
|
|
54
57
|
*/
|
|
55
58
|
this.historyMarkLimit = 10000;
|
|
59
|
+
|
|
56
60
|
/**
|
|
57
61
|
* Maximum amount of memory allowed for the history
|
|
58
62
|
* @type {number}
|
|
@@ -64,11 +68,26 @@ export class ActionProcessor {
|
|
|
64
68
|
* @type {Signal<M> | Signal}
|
|
65
69
|
*/
|
|
66
70
|
this.onMarkAdded = new Signal();
|
|
71
|
+
|
|
67
72
|
/**
|
|
68
73
|
*
|
|
69
74
|
* @type {Signal<M> | Signal}
|
|
70
75
|
*/
|
|
71
76
|
this.onMarkRemoved = new Signal();
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
* @type {boolean}
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
this.__action_in_progress = false;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* @type {Promise<never>}
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
this.__last_promise = Promise.resolve();
|
|
72
91
|
}
|
|
73
92
|
|
|
74
93
|
/**
|
|
@@ -154,6 +173,10 @@ export class ActionProcessor {
|
|
|
154
173
|
* @param {D} description
|
|
155
174
|
*/
|
|
156
175
|
mark(description) {
|
|
176
|
+
if (this.__action_in_progress) {
|
|
177
|
+
throw new IllegalStateException('Action is currently in progress');
|
|
178
|
+
}
|
|
179
|
+
|
|
157
180
|
const marks = this.marks;
|
|
158
181
|
const numMarks = marks.length;
|
|
159
182
|
|
|
@@ -241,7 +264,7 @@ export class ActionProcessor {
|
|
|
241
264
|
* @returns {boolean} true on success, false otherwise (e.g. mark not found)
|
|
242
265
|
* @throws {Error} when mark is non-unique
|
|
243
266
|
*/
|
|
244
|
-
navigateTo(mark_descriptor) {
|
|
267
|
+
async navigateTo(mark_descriptor) {
|
|
245
268
|
// find all matching marks
|
|
246
269
|
const matching_marks = this.__find_mark_indices_by_description(mark_descriptor);
|
|
247
270
|
|
|
@@ -270,7 +293,7 @@ export class ActionProcessor {
|
|
|
270
293
|
|
|
271
294
|
while (target > this.cursor) {
|
|
272
295
|
// navigate forward
|
|
273
|
-
this.redo();
|
|
296
|
+
await this.redo();
|
|
274
297
|
|
|
275
298
|
if (temp_cursor === this.cursor) {
|
|
276
299
|
// no cursor change
|
|
@@ -284,7 +307,7 @@ export class ActionProcessor {
|
|
|
284
307
|
|
|
285
308
|
while (target < this.cursor) {
|
|
286
309
|
// navigate backwards
|
|
287
|
-
this.undo();
|
|
310
|
+
await this.undo();
|
|
288
311
|
|
|
289
312
|
if (temp_cursor === this.cursor) {
|
|
290
313
|
// no cursor change
|
|
@@ -299,7 +322,7 @@ export class ActionProcessor {
|
|
|
299
322
|
return true;
|
|
300
323
|
}
|
|
301
324
|
|
|
302
|
-
undo() {
|
|
325
|
+
async undo() {
|
|
303
326
|
let markAddress = 0;
|
|
304
327
|
/**
|
|
305
328
|
*
|
|
@@ -327,7 +350,8 @@ export class ActionProcessor {
|
|
|
327
350
|
while (this.cursor > markAddress && this.cursor > 0) {
|
|
328
351
|
this.cursor--;
|
|
329
352
|
const action = this.history.get(this.cursor);
|
|
330
|
-
|
|
353
|
+
|
|
354
|
+
await this.__action_revert(action);
|
|
331
355
|
}
|
|
332
356
|
|
|
333
357
|
if (mark !== null) {
|
|
@@ -338,7 +362,7 @@ export class ActionProcessor {
|
|
|
338
362
|
/**
|
|
339
363
|
* redo previous sequence of actions on the timeline, up to the next mark
|
|
340
364
|
*/
|
|
341
|
-
redo() {
|
|
365
|
+
async redo() {
|
|
342
366
|
|
|
343
367
|
let mark = this.history.length;
|
|
344
368
|
//find mark
|
|
@@ -358,7 +382,7 @@ export class ActionProcessor {
|
|
|
358
382
|
while (this.cursor < mark) {
|
|
359
383
|
const action = this.history.get(this.cursor);
|
|
360
384
|
|
|
361
|
-
|
|
385
|
+
await this.__action_apply(action);
|
|
362
386
|
|
|
363
387
|
this.historyMemoryUsage += action.computeByteSize();
|
|
364
388
|
|
|
@@ -370,14 +394,14 @@ export class ActionProcessor {
|
|
|
370
394
|
*
|
|
371
395
|
* @param {Action[]} actions
|
|
372
396
|
*/
|
|
373
|
-
doMany(actions) {
|
|
397
|
+
async doMany(actions) {
|
|
374
398
|
const n = actions.length;
|
|
375
399
|
|
|
376
400
|
for (let i = 0; i < n; i++) {
|
|
377
401
|
|
|
378
402
|
const action = actions[i];
|
|
379
403
|
|
|
380
|
-
this.do(action);
|
|
404
|
+
await this.do(action);
|
|
381
405
|
|
|
382
406
|
}
|
|
383
407
|
}
|
|
@@ -385,22 +409,88 @@ export class ActionProcessor {
|
|
|
385
409
|
/**
|
|
386
410
|
* Execute a given action and add it to the timeline
|
|
387
411
|
* @param {Action} action
|
|
388
|
-
* @returns {ActionProcessor} this instance, useful for call chaining
|
|
389
412
|
*/
|
|
390
|
-
do(action) {
|
|
391
|
-
|
|
413
|
+
async do(action) {
|
|
414
|
+
await this.__action_apply(action);
|
|
392
415
|
|
|
393
416
|
this.historyMemoryUsage += action.computeByteSize();
|
|
394
417
|
|
|
418
|
+
const history = this.history;
|
|
419
|
+
|
|
395
420
|
//doing action invalidates "future" branch of history, we need to clear all actions beyond cursor
|
|
396
|
-
if (this.cursor <
|
|
397
|
-
|
|
421
|
+
if (this.cursor < history.length) {
|
|
422
|
+
history.crop(0, this.cursor);
|
|
398
423
|
// TODO clear future marks
|
|
399
424
|
}
|
|
400
425
|
|
|
401
|
-
|
|
426
|
+
history.add(action);
|
|
427
|
+
|
|
402
428
|
this.cursor++;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
*
|
|
433
|
+
* @param {Action} action
|
|
434
|
+
* @returns {Promise<void>}
|
|
435
|
+
* @private
|
|
436
|
+
*/
|
|
437
|
+
async __action_apply(action) {
|
|
438
|
+
try {
|
|
439
|
+
await this.__last_promise;
|
|
440
|
+
} catch (e) {
|
|
441
|
+
// ignore
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (this.__action_in_progress) {
|
|
445
|
+
throw new IllegalStateException();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
this.__action_in_progress = true;
|
|
449
|
+
|
|
450
|
+
let p;
|
|
451
|
+
try {
|
|
452
|
+
p = action.apply(this.context);
|
|
453
|
+
} finally {
|
|
454
|
+
this.__action_in_progress = false;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (p !== undefined) {
|
|
458
|
+
this.__last_promise = p;
|
|
459
|
+
await p;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
*
|
|
466
|
+
* @param {Action} action
|
|
467
|
+
* @returns {Promise<void>}
|
|
468
|
+
* @private
|
|
469
|
+
*/
|
|
470
|
+
async __action_revert(action) {
|
|
471
|
+
try {
|
|
472
|
+
await this.__last_promise;
|
|
473
|
+
} catch (e) {
|
|
474
|
+
// ignore
|
|
475
|
+
}
|
|
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
|
+
}
|
|
403
494
|
|
|
404
|
-
return this;
|
|
405
495
|
}
|
|
406
496
|
}
|
|
@@ -8,52 +8,57 @@ class DummyContext {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
class DummyAction extends Action {
|
|
11
|
-
apply(context) {
|
|
11
|
+
async apply(context) {
|
|
12
12
|
// do nothing
|
|
13
13
|
context.value++;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
revert(context) {
|
|
16
|
+
async revert(context) {
|
|
17
17
|
context.value--;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
test('navigateTo backwards', () => {
|
|
21
|
+
test('navigateTo backwards', async () => {
|
|
22
22
|
const ctx = new DummyContext();
|
|
23
23
|
const ap = new ActionProcessor(ctx);
|
|
24
24
|
|
|
25
25
|
ap.mark('a');
|
|
26
|
-
ap.do(new DummyAction());
|
|
26
|
+
await ap.do(new DummyAction());
|
|
27
27
|
ap.mark('b');
|
|
28
|
-
ap.do(new DummyAction());
|
|
28
|
+
await ap.do(new DummyAction());
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
const nav_result = await ap.navigateTo('a');
|
|
31
|
+
|
|
32
|
+
expect(nav_result).toBe(true);
|
|
31
33
|
|
|
32
34
|
expect(ctx.value).toBe(1);
|
|
33
35
|
});
|
|
34
36
|
|
|
35
|
-
test('navigateTo forward', () => {
|
|
37
|
+
test('navigateTo forward', async () => {
|
|
36
38
|
const ctx = new DummyContext();
|
|
37
39
|
const ap = new ActionProcessor(ctx);
|
|
38
40
|
|
|
39
41
|
ap.mark('a');
|
|
40
|
-
ap.do(new DummyAction());
|
|
42
|
+
await ap.do(new DummyAction());
|
|
41
43
|
ap.mark('b');
|
|
42
|
-
ap.do(new DummyAction());
|
|
44
|
+
await ap.do(new DummyAction());
|
|
43
45
|
ap.mark('c');
|
|
44
46
|
|
|
45
|
-
ap.undo();
|
|
46
|
-
ap.undo();
|
|
47
|
-
ap.undo();
|
|
47
|
+
await ap.undo();
|
|
48
|
+
await ap.undo();
|
|
49
|
+
await ap.undo();
|
|
50
|
+
|
|
51
|
+
const nav_result = await ap.navigateTo('c');
|
|
48
52
|
|
|
49
|
-
expect(
|
|
53
|
+
expect(nav_result).toBe(true);
|
|
50
54
|
|
|
51
55
|
expect(ctx.value).toBe(2);
|
|
52
56
|
});
|
|
53
57
|
|
|
54
|
-
test('navigateTo non-existent on empty', () => {
|
|
58
|
+
test('navigateTo non-existent on empty', async () => {
|
|
55
59
|
const ctx = new DummyContext();
|
|
56
60
|
const ap = new ActionProcessor(ctx);
|
|
57
61
|
|
|
58
|
-
|
|
62
|
+
const nav_result = await ap.navigateTo('a');
|
|
63
|
+
expect(nav_result).toBe(false);
|
|
59
64
|
});
|
|
@@ -15,7 +15,7 @@ class ComponentAddAction extends Action {
|
|
|
15
15
|
this.dataset = null;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
apply(editor) {
|
|
18
|
+
async apply(editor) {
|
|
19
19
|
/**
|
|
20
20
|
* @type {EntityManager}
|
|
21
21
|
*/
|
|
@@ -38,7 +38,7 @@ class ComponentAddAction extends Action {
|
|
|
38
38
|
dataset.addComponentToEntity(this.entity, this.component);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
revert(editor) {
|
|
41
|
+
async revert(editor) {
|
|
42
42
|
const clazz = this.component.constructor;
|
|
43
43
|
this.dataset.removeComponentFromEntity(this.entity, clazz);
|
|
44
44
|
}
|
|
@@ -13,7 +13,7 @@ class ComponentRemoveAction extends Action {
|
|
|
13
13
|
this.component = null;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
apply(editor) {
|
|
16
|
+
async apply(editor) {
|
|
17
17
|
/**
|
|
18
18
|
* @type {Engine}
|
|
19
19
|
*/
|
|
@@ -29,7 +29,7 @@ class ComponentRemoveAction extends Action {
|
|
|
29
29
|
this.component = ecd.removeComponentFromEntity(this.entity, this.componentType);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
revert(editor) {
|
|
32
|
+
async revert(editor) {
|
|
33
33
|
const em = editor.engine.entityManager;
|
|
34
34
|
em.addComponentToEntity(this.entity, this.component);
|
|
35
35
|
}
|
|
@@ -19,7 +19,7 @@ class EntityCreateAction extends Action {
|
|
|
19
19
|
this.ecd = null;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
apply(editor) {
|
|
22
|
+
async apply(editor) {
|
|
23
23
|
if (this.ecd === null) {
|
|
24
24
|
/**
|
|
25
25
|
* @type {EntityManager}
|
|
@@ -39,7 +39,7 @@ class EntityCreateAction extends Action {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
revert(editor) {
|
|
42
|
+
async revert(editor) {
|
|
43
43
|
this.ecd.removeEntity(this.entity);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -18,7 +18,7 @@ class EntityRemoveAction extends Action {
|
|
|
18
18
|
*
|
|
19
19
|
* @param {Editor} editor
|
|
20
20
|
*/
|
|
21
|
-
apply(editor) {
|
|
21
|
+
async apply(editor) {
|
|
22
22
|
const em = editor.engine.entityManager;
|
|
23
23
|
|
|
24
24
|
const ecd = em.dataset;
|
|
@@ -32,7 +32,7 @@ class EntityRemoveAction extends Action {
|
|
|
32
32
|
*
|
|
33
33
|
* @param {Editor} editor
|
|
34
34
|
*/
|
|
35
|
-
revert(editor) {
|
|
35
|
+
async revert(editor) {
|
|
36
36
|
const em = editor.engine.entityManager;
|
|
37
37
|
|
|
38
38
|
const ecd = em.dataset;
|
|
@@ -22,7 +22,7 @@ class PaintTerrainOverlayAction extends Action {
|
|
|
22
22
|
this.oldColor = new Vector4();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
apply(editor) {
|
|
25
|
+
async apply(editor) {
|
|
26
26
|
const terrain = obtainTerrain(editor.engine.entityManager.dataset);
|
|
27
27
|
const overlay = this.overlay = terrain.overlay;
|
|
28
28
|
|
|
@@ -33,7 +33,7 @@ class PaintTerrainOverlayAction extends Action {
|
|
|
33
33
|
overlay.paintPoint(this.x, this.y, this.color);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
revert(editor) {
|
|
36
|
+
async revert(editor) {
|
|
37
37
|
const overlay = this.overlay;
|
|
38
38
|
|
|
39
39
|
overlay.clearPoint(this.x, this.y);
|
|
@@ -109,7 +109,7 @@ export class PatchTerrainHeightAction extends Action {
|
|
|
109
109
|
terrain.heightTexture.needsUpdate = true;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
apply(context) {
|
|
112
|
+
async apply(context) {
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
115
|
*
|
|
@@ -135,7 +135,7 @@ export class PatchTerrainHeightAction extends Action {
|
|
|
135
135
|
this.updateTerrain();
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
revert(context) {
|
|
138
|
+
async revert(context) {
|
|
139
139
|
|
|
140
140
|
/**
|
|
141
141
|
*
|
|
@@ -99,7 +99,7 @@ export class PatchTerrainTextureAction extends Action {
|
|
|
99
99
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
apply(context) {
|
|
102
|
+
async apply(context) {
|
|
103
103
|
/**
|
|
104
104
|
*
|
|
105
105
|
* @type {Terrain}
|
|
@@ -126,7 +126,7 @@ export class PatchTerrainTextureAction extends Action {
|
|
|
126
126
|
this.updateTerrain();
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
revert(context) {
|
|
129
|
+
async revert(context) {
|
|
130
130
|
/**
|
|
131
131
|
*
|
|
132
132
|
* @type {Terrain}
|
|
@@ -20,7 +20,7 @@ class SelectionAddAction extends Action {
|
|
|
20
20
|
this.entities = entities;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
apply(editor) {
|
|
23
|
+
async apply(editor) {
|
|
24
24
|
this.oldState = editor.selection.clone();
|
|
25
25
|
|
|
26
26
|
const selection = editor.selection;
|
|
@@ -28,7 +28,7 @@ class SelectionAddAction extends Action {
|
|
|
28
28
|
selection.addAllUnique(this.entities);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
revert(editor) {
|
|
31
|
+
async revert(editor) {
|
|
32
32
|
editor.selection.copy(this.oldState);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -9,12 +9,12 @@ class SelectionClearAction extends Action {
|
|
|
9
9
|
this.oldState = null;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
apply(editor) {
|
|
12
|
+
async apply(editor) {
|
|
13
13
|
this.oldState = editor.selection.clone();
|
|
14
14
|
editor.selection.reset();
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
revert(editor) {
|
|
17
|
+
async revert(editor) {
|
|
18
18
|
editor.selection.copy(this.oldState);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -10,7 +10,7 @@ class SelectionRemoveAction extends Action {
|
|
|
10
10
|
this.entities = entities;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
apply(editor) {
|
|
13
|
+
async apply(editor) {
|
|
14
14
|
const selection = editor.selection;
|
|
15
15
|
this.oldState = selection.clone();
|
|
16
16
|
for (let i = 0; i < this.entities.length; i++) {
|
|
@@ -22,7 +22,7 @@ class SelectionRemoveAction extends Action {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
revert(editor) {
|
|
25
|
+
async revert(editor) {
|
|
26
26
|
editor.selection.copy(this.oldState);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -24,7 +24,7 @@ class TransformModifyAction extends Action {
|
|
|
24
24
|
*
|
|
25
25
|
* @param {Editor} editor
|
|
26
26
|
*/
|
|
27
|
-
apply(editor) {
|
|
27
|
+
async apply(editor) {
|
|
28
28
|
const entityManager = editor.engine.entityManager;
|
|
29
29
|
|
|
30
30
|
const component = entityManager.getComponent(this.entity, Transform);
|
|
@@ -34,7 +34,7 @@ class TransformModifyAction extends Action {
|
|
|
34
34
|
component.copy(this.modified);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
revert(editor) {
|
|
37
|
+
async revert(editor) {
|
|
38
38
|
const entityManager = editor.engine.entityManager;
|
|
39
39
|
|
|
40
40
|
const component = entityManager.getComponent(this.entity, Transform);
|
|
@@ -15,7 +15,7 @@ class WriteGridValueAction extends Action {
|
|
|
15
15
|
this.oldValue = null;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
apply(editor) {
|
|
18
|
+
async apply(editor) {
|
|
19
19
|
const obstacle = editor.engine.entityManager.getComponent(this.entity, GridObstacle);
|
|
20
20
|
this.obstacle = obstacle;
|
|
21
21
|
|
|
@@ -26,7 +26,7 @@ class WriteGridValueAction extends Action {
|
|
|
26
26
|
gridField.pointSet(this.x, this.y, this.value);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
revert(editor) {
|
|
29
|
+
async revert(editor) {
|
|
30
30
|
const gridField = obstacle2grid(this.obstacle);
|
|
31
31
|
|
|
32
32
|
gridField.pointSet(this.x, this.y, this.oldValue);
|
|
@@ -199,9 +199,10 @@ function prepareMeshLibrary(editor) {
|
|
|
199
199
|
|
|
200
200
|
const transform = new Transform();
|
|
201
201
|
|
|
202
|
-
editor.actions
|
|
202
|
+
const actions = editor.actions;
|
|
203
|
+
actions.mark('New Mesh Placed from Library');
|
|
203
204
|
const entityCreateAction = new EntityCreateAction();
|
|
204
|
-
|
|
205
|
+
actions.do(entityCreateAction);
|
|
205
206
|
|
|
206
207
|
terrain.raycast(source, direction, function (hit, normal, geometry) {
|
|
207
208
|
function handleMeshSetEvent() {
|
|
@@ -217,7 +218,7 @@ function prepareMeshLibrary(editor) {
|
|
|
217
218
|
transform.position.add(offset);
|
|
218
219
|
|
|
219
220
|
//remove listener
|
|
220
|
-
|
|
221
|
+
ecd.removeEntityEventListener(entityCreateAction.entity, MeshEvents.DataSet, handleMeshSetEvent);
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
if (hit !== null) {
|
|
@@ -229,7 +230,7 @@ function prepareMeshLibrary(editor) {
|
|
|
229
230
|
|
|
230
231
|
|
|
231
232
|
//wait for mesh to load
|
|
232
|
-
|
|
233
|
+
ecd.addEntityEventListener(entityCreateAction.entity, MeshEvents.DataSet, handleMeshSetEvent);
|
|
233
234
|
}
|
|
234
235
|
}, noop);
|
|
235
236
|
|
|
@@ -238,12 +239,13 @@ function prepareMeshLibrary(editor) {
|
|
|
238
239
|
mesh.url = url;
|
|
239
240
|
|
|
240
241
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
actions.doMany([
|
|
243
|
+
new ComponentAddAction(entityCreateAction.entity, transform),
|
|
244
|
+
new ComponentAddAction(entityCreateAction.entity, mesh),
|
|
244
245
|
//automatically select newly placed object
|
|
245
|
-
|
|
246
|
-
|
|
246
|
+
new SelectionClearAction(),
|
|
247
|
+
new SelectionAddAction([entityCreateAction.entity])
|
|
248
|
+
]);
|
|
247
249
|
|
|
248
250
|
}
|
|
249
251
|
|
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.
|
|
8
|
+
"version": "2.37.0",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|