'use client' import { type FenceNode, useRegistry, useScene } from '@pascal-app/core' import { DEFAULT_STAIR_MATERIAL, useNodeEvents } from '@pascal-app/viewer' import { useEffect, useLayoutEffect, useMemo, useRef } from 'react' import type { Mesh } from 'three' /** * Thin fence renderer — registers an empty mesh, marks the node dirty so * `FenceSystem` (re-exported via `./system`) fills the geometry next * frame, and wires pointer events through `useNodeEvents`. * * Behaviorally identical to the legacy `FenceRenderer` in * `@pascal-app/viewer/components/renderers/fence/fence-renderer.tsx`. * Phase 0 shims pick which one mounts based on `nodeRegistry.has('fence')`. * * Material is `DEFAULT_STAIR_MATERIAL` (legacy reuse; fence and stairs * share the wood-tone preset). */ let didLogFirstRegistryFenceMount = false const FenceRenderer = ({ node }: { node: FenceNode }) => { const ref = useRef(null!) const handlers = useNodeEvents(node, 'fence') const material = useMemo(() => DEFAULT_STAIR_MATERIAL, []) useRegistry(node.id, 'fence', ref) useLayoutEffect(() => { useScene.getState().markDirty(node.id) }, [node.id]) useEffect(() => { if (didLogFirstRegistryFenceMount) return didLogFirstRegistryFenceMount = true console.info( '[fence:registry] first registry-driven FenceRenderer mounted — legacy FenceRenderer is NOT in use', ) }, []) return ( ) } export default FenceRenderer