ai-chatbot/packages/core/src/hooks/spatial-grid/spatial-grid-sync.ts
2026-01-19 09:32:46 +09:00

68 lines
2.2 KiB
TypeScript

import { AnyNode } from "../../schema";
import useScene from "../../store/use-scene";
import { spatialGridManager } from "./spatial-grid-manager";
function resolveLevelId(node: AnyNode, nodes: Record<string, AnyNode>): 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]);
}