diff options
author | bob <bcz@cs.brown.edu> | 2019-04-03 11:45:15 -0400 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-04-03 11:45:15 -0400 |
commit | bb7d5a26ec68f283c5adb42d4d6554253de7176f (patch) | |
tree | 7efa817102ba54e916601611f608dd4bd761a437 /src/client/util/UndoManager.ts | |
parent | 43a0768690caa89c606dd5d296d3cc8825c1702b (diff) | |
parent | c406c8d123ce0aa9d63fb8a4dd90adfe83d2889d (diff) |
merged with master
Diffstat (limited to 'src/client/util/UndoManager.ts')
-rw-r--r-- | src/client/util/UndoManager.ts | 57 |
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(() => { |