fix: prevent crash when duplicating elements (#239)

- Guard _buildCache in merged-outline-node against stale/disposed
  Object3D refs that cause TypeError on .id access during render
- Reset children array when duplicating roofs to prevent inconsistent
  parent-child relationships (matching existing stair behavior)
- Use obj?.parent check in EditorOutlinerSync to ensure objects are
  still in the scene graph before adding to outliner arrays
- Resume temporal state on parse failure to prevent undo/redo freeze

Closes #232
This commit is contained in:
Huy Hoang
2026-04-15 17:25:03 -04:00
committed by GitHub
parent e3ba4ab921
commit 3d1005847b
3 changed files with 17 additions and 5 deletions
@@ -147,6 +147,7 @@ export function FloatingActionMenu() {
duplicate.start = [duplicate.start[0] + 1, duplicate.start[1] + 1]
duplicate.end = [duplicate.end[0] + 1, duplicate.end[1] + 1]
} else if (node.type === 'roof') {
duplicateInfo.children = []
duplicate = RoofNode.parse(duplicateInfo)
} else if (node.type === 'roof-segment') {
duplicate = RoofSegmentNode.parse(duplicateInfo)
@@ -160,6 +161,12 @@ export function FloatingActionMenu() {
}
} catch (error) {
console.error('Failed to parse duplicate', error)
useScene.temporal.getState().resume()
return
}
if (!duplicate) {
useScene.temporal.getState().resume()
return
}
@@ -920,13 +920,13 @@ const EditorOutlinerSync = () => {
outliner.selectedObjects.length = 0
for (const id of idsToHighlight) {
const obj = sceneRegistry.nodes.get(id)
if (obj) outliner.selectedObjects.push(obj)
if (obj?.parent) outliner.selectedObjects.push(obj)
}
outliner.hoveredObjects.length = 0
if (hoveredId) {
const obj = sceneRegistry.nodes.get(hoveredId)
if (obj) outliner.hoveredObjects.push(obj)
if (obj?.parent) outliner.hoveredObjects.push(obj)
}
}, [phase, previewSelectedIds, selection, hoveredId, outliner])