import { IUndoRedoStep, UndoRedoStep } from './undoRedoStep' import { UndoRedoRecord } from './types'; export interface IUndoRedoStepManager { readonly isMin: boolean; readonly isMax: boolean; getStep(index: number): IUndoRedoStep | undefined; addStep(step: IUndoRedoStep): void; undoStep(): IUndoRedoStep | undefined; redoStep(): IUndoRedoStep | undefined; } export class UndoRedoStepManager implements IUndoRedoStepManager { private static readonly _initialCapacity = 3; private static readonly _initialUndoIndex = -2; private static readonly _initialRedoIndex = 0; private _stepList: UndoRedoStep[]; private _capacity: number; private _undoIndex: number; private _redoIndex: number; constructor(capacity: number) { this._stepList = []; this._capacity = capacity > UndoRedoStepManager._initialCapacity ? capacity : UndoRedoStepManager._initialCapacity; this._undoIndex = UndoRedoStepManager._initialUndoIndex; this._redoIndex = UndoRedoStepManager._initialRedoIndex; } get isMin() { return this._undoIndex < 0; } get isMax() { return this._redoIndex >= this._stepList.length; } getStep(index?: number): UndoRedoStep | undefined { return index === undefined ? this._stepList[this._redoIndex - 1] : this._stepList[index]; } addStep(step: UndoRedoStep) { for (let i = this._stepList.length - 1; i > this._undoIndex + 1; i--) { this._stepList.splice(i, 1); } if (this._stepList.length >= this._capacity) { this._stepList.splice(0, 1); } this._stepList.push(step); this._undoIndex = this._stepList.length - 2; this._redoIndex = this._stepList.length; } undoStep() { let step: UndoRedoStep | undefined; if (this._undoIndex >= 0 && this._undoIndex < this._stepList.length - 1) { step = this._stepList[this._undoIndex]; this._undoIndex--; this._redoIndex--; } return step; } redoStep() { let step: UndoRedoStep | undefined; if (this._redoIndex > 0 && this._redoIndex < this._stepList.length) { step = this._stepList[this._redoIndex]; this._undoIndex++; this._redoIndex++; } return step; } }