import { UndoRedoStep } from './undoRedoStep'; import { UndoRedoRecord, UndoRedoActionCollection } from './types'; import { UndoRedoStepManager } from './undoRedoStepManager'; export interface IUndoRedo { readonly isMin: boolean; readonly isMax: boolean; getRecord(): T | undefined; setAndStoreRecord(record: T): void; undo(): void; redo(): void; } export class UndoRedo implements IUndoRedo { private _undoRedoRecord?: UndoRedoRecord; private _undoRedoStepManager: UndoRedoStepManager; private _actionCollection: UndoRedoActionCollection; constructor( capacity: number, actionCollection: UndoRedoActionCollection ) { this._undoRedoStepManager = new UndoRedoStepManager(capacity); this._actionCollection = actionCollection; this.setAndStoreRecord({ set: { params: [], action: '' }, restore: { params: [], action: '' } }); } get isMin() { return this._undoRedoStepManager.isMin; } get isMax() { return this._undoRedoStepManager.isMax; } private _setRecord(record: UndoRedoRecord, isUndo: boolean) { this._undoRedoRecord = record; let action = this._actionCollection[isUndo ? record.restore.action : record.set.action]; action && action(...(isUndo ? record.restore.params : record.set.params)); } private _createStep() { if (this._undoRedoRecord) { return new UndoRedoStep(this._undoRedoRecord); } } private _restoreStep(step: UndoRedoStep, undo: boolean) { let record = step.getRecord()!; record && this._setRecord(record, undo); } getRecord() { return this._undoRedoRecord; } setAndStoreRecord(record: UndoRedoRecord) { this._setRecord(record, false); const step = this._undoRedoStepManager.getStep(); step && step.setRecord({ ...step.getRecord()!, restore: record.restore }); this._undoRedoStepManager.addStep(this._createStep()!); } undo() { let step = this._undoRedoStepManager.undoStep(); step && this._restoreStep(step, true); } redo() { let step = this._undoRedoStepManager.redoStep(); step && this._restoreStep(step, false); } }