Refactor simulation state management using dedicated controller

This commit is contained in:
2026-04-27 15:42:22 +02:00
parent 5548eaa17f
commit e79a1dec22

View File

@@ -3957,96 +3957,29 @@ export function App({ store, initialStatusMessage }: AppProps) {
}, [editorState.projectDocument.time]);
useEffect(() => {
setEditorSimulationClockOverride((currentClock) => {
if (currentClock === null) {
return null;
}
return editorSimulationController.subscribeUiSnapshot(
setEditorSimulationSnapshot
);
}, [editorSimulationController]);
const reconfiguredClock = reconfigureRuntimeClockState(
currentClock,
editorState.projectDocument.time
);
return areRuntimeClockStatesEqual(currentClock, reconfiguredClock)
? currentClock
: reconfiguredClock;
useEffect(() => {
editorSimulationController.updateInputs({
document: editorState.document,
loadedModelAssets
});
}, [editorState.projectDocument.time.dayLengthMinutes]);
useEffect(() => {
if (editorState.toolMode !== "play") {
return;
}
setEditorSimulationPlaying(false);
}, [editorState.toolMode]);
useEffect(() => {
if (editorState.toolMode === "play" || !editorSimulationPlaying) {
return;
}
let animationFrame = 0;
let previousFrameTime: number | null = null;
const tick = (timestamp: number) => {
if (previousFrameTime !== null) {
const dtSeconds = Math.min(
0.25,
(timestamp - previousFrameTime) / 1000
);
setEditorSimulationClockOverride((currentClock) =>
advanceRuntimeClockState(
currentClock ??
createRuntimeClockState(editorState.projectDocument.time),
dtSeconds
)
);
}
previousFrameTime = timestamp;
animationFrame = window.requestAnimationFrame(tick);
};
animationFrame = window.requestAnimationFrame(tick);
return () => {
if (animationFrame !== 0) {
window.cancelAnimationFrame(animationFrame);
}
};
}, [
editorSimulationPlaying,
editorState.projectDocument.time,
editorState.toolMode
]);
}, [editorSimulationController, editorState.document, loadedModelAssets]);
useEffect(() => {
if (editorState.toolMode === "play") {
return;
editorSimulationController.pause();
}
}, [editorSimulationController, editorState.toolMode]);
try {
const nextEditorSimulationScene = applyResolvedControlStateToRuntimeScene(
buildRuntimeSceneFromDocument(editorState.document, {
loadedModelAssets,
runtimeClock: editorSimulationClock
})
);
setEditorSimulationScene(nextEditorSimulationScene);
setEditorSimulationMessage(null);
} catch (error) {
setEditorSimulationScene(null);
setEditorSimulationMessage(getErrorMessage(error));
}
}, [
editorSimulationClock.dayCount,
editorSimulationClock.dayLengthMinutes,
editorSimulationClock.timeOfDayHours,
editorState.document,
editorState.toolMode,
loadedModelAssets
]);
useEffect(() => {
return () => {
editorSimulationController.dispose();
};
}, [editorSimulationController]);
useEffect(() => {
if (selectedScheduleRoutineId === null) {