import { AnyNode } from "../../schema"; import useScene from "../../store/use-scene"; import { spatialGridManager } from "./spatial-grid-manager"; 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]); }