fix perfs and broken undo stack by various move tools

This commit is contained in:
wass08
2026-04-17 17:26:38 -04:00
parent 5c16aa4225
commit 28bbf14836
5 changed files with 62 additions and 11 deletions
@@ -139,6 +139,14 @@ export const MoveCeilingTool: React.FC<{ node: CeilingNode }> = ({ node }) => {
const preview = previewRef.current ?? { polygon: originalPolygon, holes: originalHoles }
wasCommitted = true
// Restore original baseline while paused so the next resume+update
// registers as a single tracked change (undo reverts to original).
useScene.getState().updateNode(node.id, {
polygon: originalPolygon,
holes: originalHoles,
})
useScene.temporal.getState().resume()
useScene.getState().updateNode(node.id, preview)
useScene.getState().markDirty(node.id as AnyNodeId)
@@ -112,6 +112,14 @@ export const MoveSlabTool: React.FC<{ node: SlabNode }> = ({ node }) => {
const preview = previewRef.current ?? { polygon: originalPolygon, holes: originalHoles }
wasCommitted = true
// Restore original baseline while paused so the next resume+update
// registers as a single tracked change (undo reverts to original).
useScene.getState().updateNode(node.id, {
polygon: originalPolygon,
holes: originalHoles,
})
useScene.temporal.getState().resume()
useScene.getState().updateNode(node.id, preview)
useScene.getState().markDirty(node.id as AnyNodeId)
@@ -110,12 +110,18 @@ export const CurveWallTool: React.FC<{ node: WallNode }> = ({ node }) => {
const curveOffset = previewOffsetRef.current
wasCommitted = true
useScene.temporal.getState().resume()
if (curveOffset !== getClampedWallCurveOffset(node)) {
if (curveOffset !== originalCurveOffset) {
// Restore original baseline while paused so the next resume+update
// registers as a single tracked change (undo reverts to original).
useScene.getState().updateNode(nodeId, { curveOffset: originalCurveOffset })
useScene.getState().markDirty(nodeId as AnyNodeId)
useScene.temporal.getState().resume()
useScene.getState().updateNode(nodeId, { curveOffset })
useScene.getState().markDirty(nodeId as AnyNodeId)
useScene.temporal.getState().pause()
}
useScene.temporal.getState().pause()
sfxEmitter.emit('sfx:item-place')
useViewer.getState().setSelection({ selectedIds: [nodeId] })
@@ -201,6 +201,14 @@ export const MoveWallEndpointTool: React.FC<{ target: MovingWallEndpoint }> = ({
if (hasChanged && isWallLongEnough(preview.start, preview.end)) {
wasCommitted = true
// Restore original baseline while paused so the next resume+update
// registers as a single tracked change (undo reverts to original).
applyNodePreview([
{ id: nodeId, start: originalStart, end: originalEnd },
...linkedOriginalsRef.current,
])
useScene.temporal.getState().resume()
applyNodePreview([
{ id: nodeId, start: preview.start, end: preview.end },
@@ -229,22 +229,43 @@ export const MoveWallTool: React.FC<{ node: WallNode }> = ({ node }) => {
const preview = previewRef.current ?? { start: originalStart, end: originalEnd }
wasCommitted = true
useScene.temporal.getState().resume()
// Restore original baseline while paused so the next resume+update
// registers as a single tracked change (undo reverts to original).
applyNodePreview([
{ id: nodeId, start: preview.start, end: preview.end },
{ id: nodeId, start: originalStart, end: originalEnd },
...linkedOriginalsRef.current,
])
useScene.temporal.getState().resume()
const commitUpdates = [
{
id: nodeId as AnyNodeId,
data: isNew
? {
start: preview.start,
end: preview.end,
metadata: stripWallIsNewMetadata(node.metadata),
}
: { start: preview.start, end: preview.end },
},
...getLinkedWallUpdates(
linkedOriginalsRef.current,
originalStart,
originalEnd,
preview.start,
preview.end,
),
])
if (isNew) {
useScene.getState().updateNode(nodeId, {
metadata: stripWallIsNewMetadata(node.metadata),
})
).map((entry) => ({
id: entry.id as AnyNodeId,
data: { start: entry.start, end: entry.end },
})),
]
useScene.getState().updateNodes(commitUpdates)
for (const { id } of commitUpdates) {
useScene.getState().markDirty(id)
}
useScene.temporal.getState().pause()
sfxEmitter.emit('sfx:item-place')