diff options
author | Tyler Schicke <tyler_schicke@brown.edu> | 2019-03-19 20:29:51 -0400 |
---|---|---|
committer | Tyler Schicke <tyler_schicke@brown.edu> | 2019-03-19 20:29:51 -0400 |
commit | 6cee1e69703463cd6410d24a96c1f9eb33e996a5 (patch) | |
tree | e54632ec1a9e2bd13dfaff71ee1d3a430ee9b3e5 /src | |
parent | 9914582c733bbd345ab725609d9b122d6fe57d5f (diff) |
Refactored undo stuff
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/UndoManager.ts | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts index 46ad558f3..3cbb994b7 100644 --- a/src/client/util/UndoManager.ts +++ b/src/client/util/UndoManager.ts @@ -1,4 +1,13 @@ import { observable, action } from "mobx"; +import 'source-map-support/register' + +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 +22,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 +41,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 +79,53 @@ export namespace UndoManager { return redoStack.length > 0; } - export function StartBatch(): void { + let openBatches: Batch[] = []; + export function GetOpenBatches(): { batchName: string, cancel: () => void }[] { + 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(() => { |