import type { AnyNode } from '../../schema' import useScene from '../../store/use-scene' import { spatialGridManager } from './spatial-grid-manager' export function resolveLevelId(node: AnyNode, nodes: Record): string { // If the node itself is a level if (node.type === 'level') return node.id // Walk up parent chain to find level // This assumes you track parentId or can derive it let current: AnyNode | undefined = node while (current) { if (current.type === 'level') return current.id // Find parent (you might need to add parentId to your schema or derive it) if (!current.parentId) { current = undefined } else { current = nodes[current.parentId] } } return 'default' // fallback for orphaned items } // Call this once at app initialization export function initSpatialGridSync() { const store = useScene // Subscribe to all changes store.subscribe((state, prevState) => { // Detect added nodes for (const [id, node] of Object.entries(state.nodes)) { if (!prevState.nodes[id as AnyNode['id']]) { const levelId = resolveLevelId(node, state.nodes) spatialGridManager.handleNodeCreated(node, levelId) } } // Detect removed nodes for (const [id, node] of Object.entries(prevState.nodes)) { if (!state.nodes[id as AnyNode['id']]) { const levelId = resolveLevelId(node, prevState.nodes) spatialGridManager.handleNodeDeleted(id, node.type, levelId) } } // Detect updated nodes (items with position/rotation/parentId changes) for (const [id, node] of Object.entries(state.nodes)) { const prev = prevState.nodes[id as AnyNode['id']] if (prev && node.type === 'item' && prev.type === 'item') { if ( !arraysEqual(node.position, prev.position) || !arraysEqual(node.rotation, prev.rotation) || node.parentId !== prev.parentId ) { const levelId = resolveLevelId(node, state.nodes) spatialGridManager.handleNodeUpdated(node, levelId) } } } }) } function arraysEqual(a: number[], b: number[]): boolean { return a.length === b.length && a.every((v, i) => v === b[i]) }