Fix realtime undo updates for wall and fence moves
This commit is contained in:
@@ -54,6 +54,12 @@ export {
|
||||
type ItemInteractiveState,
|
||||
useInteractive,
|
||||
} from './store/use-interactive'
|
||||
export {
|
||||
getSceneHistoryPauseDepth,
|
||||
pauseSceneHistory,
|
||||
resetSceneHistoryPauseDepth,
|
||||
resumeSceneHistory,
|
||||
} from './store/history-control'
|
||||
export { default as useLiveTransforms, type LiveTransform } from './store/use-live-transforms'
|
||||
export { FenceSystem } from './systems/fence/fence-system'
|
||||
export { clearSceneHistory, default as useScene } from './store/use-scene'
|
||||
|
||||
@@ -4,6 +4,11 @@ import {
|
||||
isCurvedWall,
|
||||
} from '../systems/wall/wall-curve'
|
||||
import { CeilingNode, SlabNode, type CeilingNode as CeilingNodeType, type SlabNode as SlabNodeType, type WallNode } from '../schema'
|
||||
import {
|
||||
getSceneHistoryPauseDepth,
|
||||
pauseSceneHistory,
|
||||
resumeSceneHistory,
|
||||
} from '../store/history-control'
|
||||
import { simplifyClosedPolygon } from './polygon-geometry'
|
||||
|
||||
type Point2D = { x: number; y: number }
|
||||
@@ -855,6 +860,7 @@ export function initSpaceDetectionSync(sceneStore: any, editorStore: any): () =>
|
||||
|
||||
const unsubscribe = sceneStore.subscribe((state: any) => {
|
||||
if (isProcessing) return
|
||||
if (getSceneHistoryPauseDepth() > 0) return
|
||||
|
||||
const nodes = state.nodes
|
||||
const wallsByLevel = new Map<string, WallNode[]>()
|
||||
@@ -889,11 +895,11 @@ export function initSpaceDetectionSync(sceneStore: any, editorStore: any): () =>
|
||||
}
|
||||
|
||||
isProcessing = true
|
||||
sceneStore.temporal.getState().pause()
|
||||
pauseSceneHistory(sceneStore)
|
||||
try {
|
||||
runSpaceDetection([...levelsToUpdate], sceneStore, editorStore, nodes)
|
||||
} finally {
|
||||
sceneStore.temporal.getState().resume()
|
||||
resumeSceneHistory(sceneStore)
|
||||
previousSnapshots.clear()
|
||||
for (const [levelId, snapshot] of currentSnapshots.entries()) {
|
||||
previousSnapshots.set(levelId, snapshot)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
let sceneHistoryPauseDepth = 0
|
||||
|
||||
type TemporalStoreLike = {
|
||||
temporal: {
|
||||
getState(): {
|
||||
pause(): void
|
||||
resume(): void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function pauseSceneHistory(sceneStore: TemporalStoreLike): void {
|
||||
if (sceneHistoryPauseDepth === 0) {
|
||||
sceneStore.temporal.getState().pause()
|
||||
}
|
||||
sceneHistoryPauseDepth += 1
|
||||
}
|
||||
|
||||
export function resumeSceneHistory(sceneStore: TemporalStoreLike): void {
|
||||
if (sceneHistoryPauseDepth === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
sceneHistoryPauseDepth -= 1
|
||||
if (sceneHistoryPauseDepth === 0) {
|
||||
sceneStore.temporal.getState().resume()
|
||||
}
|
||||
}
|
||||
|
||||
export function getSceneHistoryPauseDepth(): number {
|
||||
return sceneHistoryPauseDepth
|
||||
}
|
||||
|
||||
export function resetSceneHistoryPauseDepth(): void {
|
||||
sceneHistoryPauseDepth = 0
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { SiteNode } from '../schema/nodes/site'
|
||||
import { StairNode as StairNodeSchema } from '../schema/nodes/stair'
|
||||
import { StairSegmentNode as StairSegmentNodeSchema } from '../schema/nodes/stair-segment'
|
||||
import type { AnyNode, AnyNodeId } from '../schema/types'
|
||||
import { resetSceneHistoryPauseDepth } from './history-control'
|
||||
import * as nodeActions from './actions/node-actions'
|
||||
|
||||
function getFiniteNumber(value: unknown, fallback: number) {
|
||||
@@ -628,6 +629,7 @@ let prevNodesSnapshot: Record<AnyNodeId, AnyNode> | null = null
|
||||
|
||||
export function clearSceneHistory() {
|
||||
useScene.temporal.getState().clear()
|
||||
resetSceneHistoryPauseDepth()
|
||||
prevPastLength = 0
|
||||
prevFutureLength = 0
|
||||
prevNodesSnapshot = null
|
||||
@@ -647,8 +649,9 @@ useScene.temporal.subscribe((state) => {
|
||||
// Capture the previous snapshot before RAF fires
|
||||
const snapshotBefore = prevNodesSnapshot
|
||||
|
||||
// Use RAF to ensure all middleware and store updates are complete
|
||||
requestAnimationFrame(() => {
|
||||
// Defer to a microtask so the scene store has settled before we diff,
|
||||
// but still mark walls/items dirty before the next paint.
|
||||
queueMicrotask(() => {
|
||||
const currentNodes = useScene.getState().nodes
|
||||
const { markDirty } = useScene.getState()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user