Files
Aislo/B07_DesignDetail/openwebcad/src/helpers/undo-stack.ts
T

95 lines
2.5 KiB
TypeScript

import type { Layer } from '../App.types';
/** 도면층 목록 + 현재 층 — LAYMRG · LAYDEL 이 객체 변경과 함께 담는다 */
export interface LayerSnapshot {
layers: Layer[];
activeLayerId: string;
}
export interface UndoState {
variable: StateVariable;
// biome-ignore lint/suspicious/noExplicitAny: TODO list all undo state types
value: any;
/** 이 단계가 도면층도 바꿨다면 전 · 후 — 되돌리면 before · 다시 하면 after 를 복원 */
layerChange?: { before: LayerSnapshot; after: LayerSnapshot };
}
export enum StateVariable {
canvasSize = 'canvasSize',
canvas = 'canvas',
context = 'context',
screenMouseLocation = 'screenMouseLocation',
activeTool = 'activeTool',
entities = 'entities',
activeEntity = 'activeEntity',
shouldDrawCursor = 'shouldDrawCursor',
helperEntities = 'helperEntities',
debugEntities = 'debugEntities',
angleStep = 'angleStep',
screenOffset = 'screenOffset',
screenZoom = 'screenZoom',
panStartLocation = 'panStartLocation',
snapPoint = 'snapPoint',
snapPointOnAngleGuide = 'snapPointOnAngleGuide',
hoveredSnapPoints = 'hoveredSnapPoints',
lastDrawTimestamp = 'lastDrawTimestamp',
activeLineColor = 'activeLineColor',
activeLineWidth = 'activeLineWidth',
activeLineDash = 'activeLineDash',
activeTextStyle = 'activeTextStyle',
designMeta = 'designMeta',
layers = 'layers',
}
/**
* Based on https://github.com/wobsoriano/undo-stacker
*/
export function createStack() {
let stack: UndoState[] = [];
let index = stack.length;
function peek() {
return stack[index - 1];
}
return {
push: (value: UndoState) => {
stack.length = index;
stack[index++] = value;
// console.log('stack push', JSON.stringify(stack, null, 2));
return peek();
},
replace: (value: UndoState) => {
stack[index - 1] = value;
// console.log('stack replace', JSON.stringify(stack, null, 2));
return peek();
},
peek: () => {
return peek();
},
undo: () => {
if (index > 1) index -= 1;
// console.log('stack undo', JSON.stringify(stack, null, 2));
return peek();
},
redo: () => {
if (index < stack.length) index += 1;
// console.log('stack redo', JSON.stringify(stack, null, 2));
return peek();
},
// Clear certain states from the undo stack
clear: (variable: StateVariable) => {
// Update the index be reducing it by the number of states that are removed to the left of the index
index = index - stack.slice(0, index).filter((state) => state.variable === variable).length;
stack = stack.filter((state) => state.variable !== variable);
},
};
}