| | |
| | | lastSocketTimestamp: 0, |
| | | routeReady: false, |
| | | }); |
| | | const renderTimerRef = useRef<ReturnType<typeof setInterval> | null>(null); |
| | | const renderTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null); |
| | | const lastRenderAtRef = useRef(0); |
| | | const prevTripStatusRef = useRef(deps.tripStatus); |
| | | const nativeRouteEraseReadyRef = useRef(false); |
| | |
| | | */ |
| | | const stopRenderLoop = () => { |
| | | if (renderTimerRef.current) { |
| | | clearInterval(renderTimerRef.current); |
| | | clearTimeout(renderTimerRef.current); |
| | | renderTimerRef.current = null; |
| | | } |
| | | lastRenderAtRef.current = 0; |
| | |
| | | |
| | | /** |
| | | * 启动本地补帧循环,在 socket 两帧之间平滑推动车辆和擦线进度。 |
| | | * 用递归 setTimeout 自调度而非 setInterval:同一时刻只保留一个待执行定时器, |
| | | * 渲染层繁忙时不会像 setInterval 那样在桥接层堆积回调。下一帧在帧首调度,早退分支也不会中断循环。 |
| | | */ |
| | | const startRenderLoop = () => { |
| | | if (renderTimerRef.current) { |
| | | return; |
| | | } |
| | | renderTimerRef.current = setInterval(() => { |
| | | const tick = () => { |
| | | // 帧首先排下一帧(早退分支不影响循环延续),由 stopRenderLoop 的 clearTimeout 终止。 |
| | | renderTimerRef.current = setTimeout(tick, TripMotionConfig.RENDER_INTERVAL_MS); |
| | | |
| | | const runtime = runtimeRef.current; |
| | | const routeIndex = runtime.routeIndex; |
| | | if (!runtime.routeReady || !routeIndex) { |
| | |
| | | if (shouldEraseRoute) { |
| | | eraseRouteToDistance(routeIndex, prevDisplayDistance); |
| | | } |
| | | }, TripMotionConfig.RENDER_INTERVAL_MS); |
| | | }; |
| | | renderTimerRef.current = setTimeout(tick, TripMotionConfig.RENDER_INTERVAL_MS); |
| | | }; |
| | | |
| | | /** |