aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/UndoManager.ts
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2019-04-03 11:45:15 -0400
committerbob <bcz@cs.brown.edu>2019-04-03 11:45:15 -0400
commitbb7d5a26ec68f283c5adb42d4d6554253de7176f (patch)
tree7efa817102ba54e916601611f608dd4bd761a437 /src/client/util/UndoManager.ts
parent43a0768690caa89c606dd5d296d3cc8825c1702b (diff)
parentc406c8d123ce0aa9d63fb8a4dd90adfe83d2889d (diff)
merged with master
Diffstat (limited to 'src/client/util/UndoManager.ts')
-rw-r--r--src/client/util/UndoManager.ts57
1 files changed, 47 insertions, 10 deletions
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts
index 46ad558f3..6d1b2f1b8 100644
--- a/src/client/util/UndoManager.ts
+++ b/src/client/util/UndoManager.ts
@@ -1,4 +1,14 @@
import { observable, action } from "mobx";
+import 'source-map-support/register'
+import { Without } from "../../Utils";
+
+function getBatchName(target: any, key: string | symbol): string {
+ let keyName = key.toString();
+ if (target && target.constructor && target.constructor.name) {
+ return `${target.constructor.name}.${keyName}`;
+ }
+ return keyName;
+}
function propertyDecorator(target: any, key: string | symbol) {
Object.defineProperty(target, key, {
@@ -13,11 +23,11 @@ function propertyDecorator(target: any, key: string | symbol) {
writable: true,
configurable: true,
value: function (...args: any[]) {
+ let batch = UndoManager.StartBatch(getBatchName(target, key));
try {
- UndoManager.StartBatch();
return value.apply(this, args);
} finally {
- UndoManager.EndBatch();
+ batch.end();
}
}
})
@@ -32,11 +42,11 @@ export function undoBatch(target: any, key: string | symbol, descriptor?: TypedP
const oldFunction = descriptor.value;
descriptor.value = function (...args: any[]) {
+ let batch = UndoManager.StartBatch(getBatchName(target, key));
try {
- UndoManager.StartBatch()
return oldFunction.apply(this, args)
} finally {
- UndoManager.EndBatch()
+ batch.end();
}
}
@@ -70,26 +80,53 @@ export namespace UndoManager {
return redoStack.length > 0;
}
- export function StartBatch(): void {
+ let openBatches: Batch[] = [];
+ export function GetOpenBatches(): Without<Batch, 'end'>[] {
+ return openBatches;
+ }
+ export class Batch {
+ private disposed: boolean = false;
+
+ constructor(readonly batchName: string) {
+ openBatches.push(this);
+ }
+
+ private dispose = (cancel: boolean) => {
+ if (this.disposed) {
+ throw new Error("Cannot dispose an already disposed batch");
+ }
+ this.disposed = true;
+ openBatches.splice(openBatches.indexOf(this));
+ EndBatch(cancel);
+ }
+
+ end = () => { this.dispose(false); }
+ cancel = () => { this.dispose(true); }
+ }
+
+ export function StartBatch(batchName: string): Batch {
batchCounter++;
if (batchCounter > 0) {
currentBatch = [];
}
+ return new Batch(batchName);
}
- export const EndBatch = action(() => {
+ const EndBatch = action((cancel: boolean = false) => {
batchCounter--;
if (batchCounter === 0 && currentBatch && currentBatch.length) {
- undoStack.push(currentBatch);
+ if (!cancel) {
+ undoStack.push(currentBatch);
+ }
redoStack.length = 0;
currentBatch = undefined;
}
})
- export function RunInBatch(fn: () => void) {
- StartBatch();
+ export function RunInBatch(fn: () => void, batchName: string) {
+ let batch = StartBatch(batchName);
fn();
- EndBatch();
+ batch.end();
}
export const Undo = action(() => {