fix: preserve analysis bands across input workflows

This commit is contained in:
2026-08-29 08:05:15 +09:00
parent 122b6cf7be
commit 62971e07ec
10 changed files with 282 additions and 24 deletions
+34 -7
View File
@@ -981,7 +981,8 @@ function applyValidation(validation) {
if (!state.lastRun && document.documentElement.dataset.runState === "idle") {
setRunStatus(
`${state.arrayDefinition.microphones.length} ch · ` +
`${state.experiment.scan.columns}×${state.experiment.scan.rows} · 실행 준비 완료`,
`${state.experiment.scan.columns}×${state.experiment.scan.rows} · ` +
`분석 대역 ${state.experiment.frequencyBands.length}개 · 실행 준비 완료`,
);
}
}
@@ -1470,6 +1471,18 @@ function toggleLivePlayback() {
async function loadMovingExample() {
if (state.active) return;
const bandCount = state.experiment?.frequencyBands?.length ?? 0;
if (
(bandCount > 1 || hasUnsavedWork()) &&
!window.confirm(
"이동 예제는 현재 Scene·Array·Experiment 전체와 " +
String(bandCount) +
"개 분석 대역을 교체합니다. 계속할까요?",
)
) {
setRunStatus("이동 예제를 열지 않았습니다. 현재 입력과 분석 대역을 유지합니다.");
return;
}
beginInputOperation();
try {
setRunStatus("이동 음원 예제를 불러오고 있습니다…");
@@ -1494,7 +1507,7 @@ async function loadMovingExample() {
assetRuntime.reset();
markChanged({ syncControls: true, renderBands: true, dirty: "none" });
renderAssets();
setRunStatus("이동 음원 예제를 열었습니다. ‘라이브 준비’를 누르세요.");
setRunStatus("Scene·Array·Experiment를 이동 음원 예제 전체로 교체했습니다. ‘Map 준비’를 누르세요.");
} catch (error) {
setTransientError(error, "이동 예제 불러오기 실패");
} finally {
@@ -1561,10 +1574,10 @@ async function importDocument(kind, input) {
} else if (kind === "scene") {
issues = await validateScene(value);
} else {
issues = await validateExperiment(value, {
arrayDefinition: state.arrayDefinition,
scene: state.scene,
});
// An Experiment is a useful editable document even before its referenced
// Scene or Array has been loaded. Validate its own contract here, then let
// validateCurrent() keep Run disabled until the document IDs line up.
issues = await validateExperiment(value);
}
if (generation !== state.importGenerations[kind]) return;
if (issues.length > 0) throw new Error(issues.slice(0, 4).map(formatIssue).join(" · "));
@@ -1588,7 +1601,21 @@ async function importDocument(kind, input) {
dirty: kind === "experiment" ? "none" : "experiment",
});
renderAssets();
setRunStatus(`${file.name} ${kind} 문서를 불러왔습니다.`);
const bandStatus = kind === "scene"
? ` · 분석 대역 ${state.experiment.frequencyBands.length}개 유지`
: kind === "experiment"
? ` · 분석 대역 ${state.experiment.frequencyBands.length}개`
: "";
const pendingReferences = kind === "experiment"
? [
value.sceneId !== state.scene?.id ? `Scene ${value.sceneId}` : null,
value.arrayId !== state.arrayDefinition?.id ? `Array ${value.arrayId}` : null,
].filter(Boolean)
: [];
const referenceStatus = pendingReferences.length > 0
? ` · ${pendingReferences.join(" · ")} 연결 대기`
: "";
setRunStatus(`${file.name} ${kind} 문서를 불러왔습니다.${bandStatus}${referenceStatus}`);
} catch (error) {
setTransientError(error, `${file.name} 불러오기 실패`);
} finally {