@woosh/meep-engine 2.36.30 → 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.
- 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 +123 -21
- 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/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +2 -1
- 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
|
}
|
|
@@ -26,11 +26,13 @@ export class ActionProcessor {
|
|
|
26
26
|
* @type {List<Action>}
|
|
27
27
|
*/
|
|
28
28
|
this.history = new List();
|
|
29
|
+
|
|
29
30
|
/**
|
|
30
31
|
*
|
|
31
32
|
* @type {C}
|
|
32
33
|
*/
|
|
33
34
|
this.context = context;
|
|
35
|
+
|
|
34
36
|
/**
|
|
35
37
|
*
|
|
36
38
|
* @type {Array<Mark<M>>}
|
|
@@ -53,6 +55,7 @@ export class ActionProcessor {
|
|
|
53
55
|
* @type {number}
|
|
54
56
|
*/
|
|
55
57
|
this.historyMarkLimit = 10000;
|
|
58
|
+
|
|
56
59
|
/**
|
|
57
60
|
* Maximum amount of memory allowed for the history
|
|
58
61
|
* @type {number}
|
|
@@ -64,11 +67,19 @@ export class ActionProcessor {
|
|
|
64
67
|
* @type {Signal<M> | Signal}
|
|
65
68
|
*/
|
|
66
69
|
this.onMarkAdded = new Signal();
|
|
70
|
+
|
|
67
71
|
/**
|
|
68
72
|
*
|
|
69
73
|
* @type {Signal<M> | Signal}
|
|
70
74
|
*/
|
|
71
75
|
this.onMarkRemoved = new Signal();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @type {Promise<never>}
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
this.__last_promise = Promise.resolve();
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
/**
|
|
@@ -153,7 +164,9 @@ export class ActionProcessor {
|
|
|
153
164
|
* Insert a mark into the timeline, all actions between marks are grouped logically for UNDO and REDO mechanism
|
|
154
165
|
* @param {D} description
|
|
155
166
|
*/
|
|
156
|
-
mark(description) {
|
|
167
|
+
async mark(description) {
|
|
168
|
+
await this.__barrier();
|
|
169
|
+
|
|
157
170
|
const marks = this.marks;
|
|
158
171
|
const numMarks = marks.length;
|
|
159
172
|
|
|
@@ -241,7 +254,25 @@ export class ActionProcessor {
|
|
|
241
254
|
* @returns {boolean} true on success, false otherwise (e.g. mark not found)
|
|
242
255
|
* @throws {Error} when mark is non-unique
|
|
243
256
|
*/
|
|
244
|
-
navigateTo(mark_descriptor) {
|
|
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
|
+
|
|
245
276
|
// find all matching marks
|
|
246
277
|
const matching_marks = this.__find_mark_indices_by_description(mark_descriptor);
|
|
247
278
|
|
|
@@ -270,7 +301,7 @@ export class ActionProcessor {
|
|
|
270
301
|
|
|
271
302
|
while (target > this.cursor) {
|
|
272
303
|
// navigate forward
|
|
273
|
-
this.
|
|
304
|
+
await this.__unsafe_redo();
|
|
274
305
|
|
|
275
306
|
if (temp_cursor === this.cursor) {
|
|
276
307
|
// no cursor change
|
|
@@ -284,7 +315,7 @@ export class ActionProcessor {
|
|
|
284
315
|
|
|
285
316
|
while (target < this.cursor) {
|
|
286
317
|
// navigate backwards
|
|
287
|
-
this.
|
|
318
|
+
await this.__unsafe_undo();
|
|
288
319
|
|
|
289
320
|
if (temp_cursor === this.cursor) {
|
|
290
321
|
// no cursor change
|
|
@@ -299,7 +330,22 @@ export class ActionProcessor {
|
|
|
299
330
|
return true;
|
|
300
331
|
}
|
|
301
332
|
|
|
302
|
-
undo() {
|
|
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() {
|
|
303
349
|
let markAddress = 0;
|
|
304
350
|
/**
|
|
305
351
|
*
|
|
@@ -327,7 +373,8 @@ export class ActionProcessor {
|
|
|
327
373
|
while (this.cursor > markAddress && this.cursor > 0) {
|
|
328
374
|
this.cursor--;
|
|
329
375
|
const action = this.history.get(this.cursor);
|
|
330
|
-
|
|
376
|
+
|
|
377
|
+
await action.revert(this.context);
|
|
331
378
|
}
|
|
332
379
|
|
|
333
380
|
if (mark !== null) {
|
|
@@ -338,9 +385,24 @@ export class ActionProcessor {
|
|
|
338
385
|
/**
|
|
339
386
|
* redo previous sequence of actions on the timeline, up to the next mark
|
|
340
387
|
*/
|
|
341
|
-
redo() {
|
|
388
|
+
async redo() {
|
|
389
|
+
await this.__barrier();
|
|
390
|
+
|
|
391
|
+
const p = this.__unsafe_redo();
|
|
342
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() {
|
|
343
404
|
let mark = this.history.length;
|
|
405
|
+
|
|
344
406
|
//find mark
|
|
345
407
|
const marks = this.marks;
|
|
346
408
|
|
|
@@ -358,7 +420,7 @@ export class ActionProcessor {
|
|
|
358
420
|
while (this.cursor < mark) {
|
|
359
421
|
const action = this.history.get(this.cursor);
|
|
360
422
|
|
|
361
|
-
action.apply(this.context);
|
|
423
|
+
await action.apply(this.context);
|
|
362
424
|
|
|
363
425
|
this.historyMemoryUsage += action.computeByteSize();
|
|
364
426
|
|
|
@@ -370,37 +432,77 @@ export class ActionProcessor {
|
|
|
370
432
|
*
|
|
371
433
|
* @param {Action[]} actions
|
|
372
434
|
*/
|
|
373
|
-
doMany(actions) {
|
|
374
|
-
|
|
435
|
+
async doMany(actions) {
|
|
436
|
+
await this.__barrier();
|
|
375
437
|
|
|
376
|
-
|
|
438
|
+
const p = new Promise(async (resolve, reject) => {
|
|
377
439
|
|
|
378
|
-
const
|
|
440
|
+
const n = actions.length;
|
|
379
441
|
|
|
380
|
-
|
|
442
|
+
for (let i = 0; i < n; i++) {
|
|
381
443
|
|
|
382
|
-
|
|
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;
|
|
383
456
|
}
|
|
384
457
|
|
|
385
458
|
/**
|
|
386
459
|
* Execute a given action and add it to the timeline
|
|
387
460
|
* @param {Action} action
|
|
388
|
-
* @returns {ActionProcessor} this instance, useful for call chaining
|
|
389
461
|
*/
|
|
390
|
-
do(action) {
|
|
391
|
-
|
|
462
|
+
async do(action) {
|
|
463
|
+
await this.__barrier();
|
|
464
|
+
|
|
465
|
+
const p = this.__unsafe_do(action);
|
|
466
|
+
|
|
467
|
+
this.__last_promise = p;
|
|
468
|
+
|
|
469
|
+
await p;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
*
|
|
474
|
+
* @param {Action} action
|
|
475
|
+
* @returns {Promise<void>}
|
|
476
|
+
* @private
|
|
477
|
+
*/
|
|
478
|
+
async __unsafe_do(action) {
|
|
479
|
+
await action.apply(this.context);
|
|
392
480
|
|
|
393
481
|
this.historyMemoryUsage += action.computeByteSize();
|
|
394
482
|
|
|
483
|
+
const history = this.history;
|
|
484
|
+
|
|
395
485
|
//doing action invalidates "future" branch of history, we need to clear all actions beyond cursor
|
|
396
|
-
if (this.cursor <
|
|
397
|
-
|
|
486
|
+
if (this.cursor < history.length) {
|
|
487
|
+
history.crop(0, this.cursor);
|
|
398
488
|
// TODO clear future marks
|
|
399
489
|
}
|
|
400
490
|
|
|
401
|
-
|
|
491
|
+
history.add(action);
|
|
492
|
+
|
|
402
493
|
this.cursor++;
|
|
494
|
+
}
|
|
403
495
|
|
|
404
|
-
|
|
496
|
+
/**
|
|
497
|
+
* Await for synchronization barrier
|
|
498
|
+
* @returns {Promise<void>}
|
|
499
|
+
* @private
|
|
500
|
+
*/
|
|
501
|
+
async __barrier() {
|
|
502
|
+
try {
|
|
503
|
+
await this.__last_promise;
|
|
504
|
+
} catch (e) {
|
|
505
|
+
// ignore
|
|
506
|
+
}
|
|
405
507
|
}
|
|
406
508
|
}
|
|
@@ -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
|
|
|
@@ -15,7 +15,8 @@ export function three_object_to_entity_composition(root) {
|
|
|
15
15
|
// copy object transform
|
|
16
16
|
node_transform.position.copy(root.position);
|
|
17
17
|
node_transform.scale.copy(root.scale);
|
|
18
|
-
|
|
18
|
+
const euler = root.rotation;
|
|
19
|
+
node_transform.rotation.fromEulerAngles(euler.x, euler.y, euler.z);
|
|
19
20
|
|
|
20
21
|
const entity = node.entity;
|
|
21
22
|
|
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.2",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|