import { create } from 'zustand'; import { DirtyRectManager, type DirtyRect } from '@/lib/dirty-rect'; interface RenderState { /** Dirty rectangle manager instance */ dirtyRectManager: DirtyRectManager | null; /** Whether dirty rect optimization is enabled */ enableDirtyRects: boolean; /** Frame counter for debugging */ frameCount: number; /** Last render time */ lastRenderTime: number; /** Initialize dirty rect manager */ initDirtyRects: (canvasWidth: number, canvasHeight: number) => void; /** Mark a region as dirty */ markDirty: (x: number, y: number, width: number, height: number) => void; /** Mark entire canvas as dirty */ markAllDirty: () => void; /** Clear all dirty regions */ clearDirtyRects: () => void; /** Check if anything is dirty */ isDirty: () => boolean; /** Get dirty regions for rendering */ getDirtyRegions: () => DirtyRect[]; /** Update canvas size */ updateCanvasSize: (width: number, height: number) => void; /** Toggle dirty rect optimization */ toggleDirtyRects: () => void; /** Increment frame counter */ incrementFrame: () => void; /** Update render time */ setRenderTime: (time: number) => void; } export const useRenderStore = create((set, get) => ({ dirtyRectManager: null, enableDirtyRects: true, frameCount: 0, lastRenderTime: 0, initDirtyRects: (canvasWidth: number, canvasHeight: number) => { set({ dirtyRectManager: new DirtyRectManager(canvasWidth, canvasHeight), }); }, markDirty: (x: number, y: number, width: number, height: number) => { const { dirtyRectManager, enableDirtyRects } = get(); if (dirtyRectManager && enableDirtyRects) { dirtyRectManager.markDirty(x, y, width, height); } }, markAllDirty: () => { const { dirtyRectManager } = get(); if (dirtyRectManager) { dirtyRectManager.markAllDirty(); } }, clearDirtyRects: () => { const { dirtyRectManager } = get(); if (dirtyRectManager) { dirtyRectManager.clear(); } }, isDirty: () => { const { dirtyRectManager, enableDirtyRects } = get(); if (!enableDirtyRects) return true; // Always dirty if optimization is off return dirtyRectManager ? dirtyRectManager.isDirty() : true; }, getDirtyRegions: () => { const { dirtyRectManager, enableDirtyRects } = get(); if (!enableDirtyRects || !dirtyRectManager) { // Return full canvas if optimization is off return []; } return dirtyRectManager.getDirtyRegions(); }, updateCanvasSize: (width: number, height: number) => { const { dirtyRectManager } = get(); if (dirtyRectManager) { dirtyRectManager.setCanvasSize(width, height); dirtyRectManager.markAllDirty(); // Mark everything dirty on resize } }, toggleDirtyRects: () => { set((state) => ({ enableDirtyRects: !state.enableDirtyRects, })); get().markAllDirty(); // Force full redraw after toggle }, incrementFrame: () => { set((state) => ({ frameCount: state.frameCount + 1 })); }, setRenderTime: (time: number) => { set({ lastRenderTime: time }); }, }));