import { applySceneMarkerEraserStroke } from '../../shared/sceneMarkerEraser'; import type { SceneMarkerEvent, SceneMarkerState, SceneMarkerStroke } from '../../shared/types'; function emptyState(): SceneMarkerState { return { revision: 1, cacheKey: null, strokes: [], draft: null, }; } function makeStrokeId(prefix: string): string { return `${prefix}_${String(Date.now())}_${String(Math.floor(Math.random() * 1_000_000_000))}`; } export class SceneMarkerStore { private state: SceneMarkerState = emptyState(); /** Кэш штрихов маркера по ключу (graphNodeId или sceneId) на время сессии показа. */ private cache = new Map(); private currentKey: string | null = null; getState(): SceneMarkerState { return { ...this.state, strokes: [...this.state.strokes] }; } /** Сброс кэша при новом запуске показа (кнопка «Запустить»). */ resetSession(): void { this.cache.clear(); this.currentKey = null; this.state = emptyState(); } /** Переключение сцены: сохраняем штрихи в кэш и загружаем новую сцену. */ switchScene(cacheKey: string | null): SceneMarkerState { if (this.currentKey !== null) { this.cache.set(this.currentKey, [...this.state.strokes]); } this.currentKey = cacheKey; const strokes = cacheKey ? [...(this.cache.get(cacheKey) ?? [])] : []; this.state = { revision: this.state.revision + 1, cacheKey, strokes, draft: null, }; return this.getState(); } dispatch(event: SceneMarkerEvent): SceneMarkerState { switch (event.kind) { case 'draft.set': this.state = { ...this.state, revision: this.state.revision + 1, draft: event.draft, }; return this.getState(); case 'stroke.add': { const strokes = [...this.state.strokes, event.stroke]; if (this.currentKey) { this.cache.set(this.currentKey, strokes); } this.state = { ...this.state, revision: this.state.revision + 1, strokes, draft: null, }; return this.getState(); } case 'strokes.erase': { const strokes = applySceneMarkerEraserStroke( this.state.strokes, event.points, event.radiusN, (prefix) => makeStrokeId(prefix), ); if (this.currentKey) { this.cache.set(this.currentKey, strokes); } this.state = { ...this.state, revision: this.state.revision + 1, strokes, draft: null, }; return this.getState(); } case 'strokes.clear': if (this.currentKey) { this.cache.set(this.currentKey, []); } this.state = { ...this.state, revision: this.state.revision + 1, strokes: [], draft: null, }; return this.getState(); default: { // eslint-disable-next-line @typescript-eslint/no-unused-vars const _x: never = event; return this.getState(); } } } }