Remove unused ProjectSequencesPanel component and update sequence document migration and validation
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -157,6 +157,7 @@ import {
|
||||
NPC_DIALOGUE_REFERENCE_SCENE_DOCUMENT_VERSION,
|
||||
PROJECT_DIALOGUE_LIBRARY_SCENE_DOCUMENT_VERSION,
|
||||
PROJECT_SEQUENCE_LIBRARY_SCENE_DOCUMENT_VERSION,
|
||||
PROJECT_SEQUENCE_TIMING_SCENE_DOCUMENT_VERSION,
|
||||
RUNNER_V1_SCENE_DOCUMENT_VERSION,
|
||||
SCENE_TRANSITION_ENTITIES_SCENE_DOCUMENT_VERSION,
|
||||
SPATIAL_AUDIO_SCENE_DOCUMENT_VERSION,
|
||||
@@ -198,8 +199,6 @@ import {
|
||||
type ProjectSequenceLibrary
|
||||
} from "../sequencer/project-sequences";
|
||||
import {
|
||||
DEFAULT_IMPULSE_SEQUENCE_CLIP_DURATION_MINUTES,
|
||||
LEGACY_PROJECT_SEQUENCE_DURATION_MINUTES,
|
||||
type SequenceClip
|
||||
} from "../sequencer/project-sequence-steps";
|
||||
import {
|
||||
@@ -3521,7 +3520,7 @@ function readProjectDialogueLibrary(
|
||||
};
|
||||
}
|
||||
|
||||
function readProjectSequenceClip(value: unknown, label: string): SequenceClip {
|
||||
function readProjectSequenceEffect(value: unknown, label: string): SequenceClip {
|
||||
if (!isRecord(value)) {
|
||||
throw new Error(`${label} must be an object.`);
|
||||
}
|
||||
@@ -3533,35 +3532,9 @@ function readProjectSequenceClip(value: unknown, label: string): SequenceClip {
|
||||
throw new Error(`${label}.stepClass must be held or impulse.`);
|
||||
}
|
||||
|
||||
const startMinute =
|
||||
value.startMinute === undefined
|
||||
? 0
|
||||
: Math.trunc(expectNonNegativeFiniteNumber(value.startMinute, `${label}.startMinute`));
|
||||
const durationMinutes =
|
||||
value.durationMinutes === undefined
|
||||
? stepClass === "held"
|
||||
? LEGACY_PROJECT_SEQUENCE_DURATION_MINUTES
|
||||
: DEFAULT_IMPULSE_SEQUENCE_CLIP_DURATION_MINUTES
|
||||
: Math.max(
|
||||
1,
|
||||
Math.trunc(
|
||||
expectPositiveFiniteNumber(
|
||||
value.durationMinutes,
|
||||
`${label}.durationMinutes`
|
||||
)
|
||||
)
|
||||
);
|
||||
const lane =
|
||||
value.lane === undefined
|
||||
? 0
|
||||
: Math.trunc(expectNonNegativeFiniteNumber(value.lane, `${label}.lane`));
|
||||
|
||||
switch (type) {
|
||||
case "controlEffect":
|
||||
return {
|
||||
startMinute,
|
||||
durationMinutes,
|
||||
lane,
|
||||
stepClass,
|
||||
type: "controlEffect",
|
||||
effect: readControlEffect(value.effect, `${label}.effect`)
|
||||
@@ -3572,9 +3545,6 @@ function readProjectSequenceClip(value: unknown, label: string): SequenceClip {
|
||||
}
|
||||
|
||||
return {
|
||||
startMinute,
|
||||
durationMinutes,
|
||||
lane,
|
||||
stepClass: "impulse",
|
||||
type: "startDialogue",
|
||||
dialogueId: expectString(value.dialogueId, `${label}.dialogueId`)
|
||||
@@ -3585,9 +3555,6 @@ function readProjectSequenceClip(value: unknown, label: string): SequenceClip {
|
||||
}
|
||||
|
||||
return {
|
||||
startMinute,
|
||||
durationMinutes,
|
||||
lane,
|
||||
stepClass: "impulse",
|
||||
type: "teleportPlayer",
|
||||
targetEntityId: expectString(
|
||||
@@ -3601,9 +3568,6 @@ function readProjectSequenceClip(value: unknown, label: string): SequenceClip {
|
||||
}
|
||||
|
||||
return {
|
||||
startMinute,
|
||||
durationMinutes,
|
||||
lane,
|
||||
stepClass: "impulse",
|
||||
type: "toggleVisibility",
|
||||
targetBrushId: expectString(value.targetBrushId, `${label}.targetBrushId`),
|
||||
@@ -3613,7 +3577,7 @@ function readProjectSequenceClip(value: unknown, label: string): SequenceClip {
|
||||
: expectBoolean(value.visible, `${label}.visible`)
|
||||
};
|
||||
default:
|
||||
throw new Error(`${label}.type must be a supported sequence clip.`);
|
||||
throw new Error(`${label}.type must be a supported sequence effect.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3645,13 +3609,15 @@ function readProjectSequenceLibrary(
|
||||
throw new Error(`${label}.sequences.${sequenceKey} must be an object.`);
|
||||
}
|
||||
|
||||
const clipsValue = Array.isArray(sequenceValue.clips)
|
||||
? sequenceValue.clips
|
||||
: sequenceValue.steps;
|
||||
const effectsValue = Array.isArray(sequenceValue.effects)
|
||||
? sequenceValue.effects
|
||||
: Array.isArray(sequenceValue.clips)
|
||||
? sequenceValue.clips
|
||||
: sequenceValue.steps;
|
||||
|
||||
if (!Array.isArray(clipsValue)) {
|
||||
if (!Array.isArray(effectsValue)) {
|
||||
throw new Error(
|
||||
`${label}.sequences.${sequenceKey}.clips must be an array.`
|
||||
`${label}.sequences.${sequenceKey}.effects must be an array.`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3661,22 +3627,10 @@ function readProjectSequenceLibrary(
|
||||
sequenceValue.title,
|
||||
`${label}.sequences.${sequenceKey}.title`
|
||||
),
|
||||
durationMinutes:
|
||||
sequenceValue.durationMinutes === undefined
|
||||
? undefined
|
||||
: Math.max(
|
||||
1,
|
||||
Math.trunc(
|
||||
expectPositiveFiniteNumber(
|
||||
sequenceValue.durationMinutes,
|
||||
`${label}.sequences.${sequenceKey}.durationMinutes`
|
||||
)
|
||||
)
|
||||
),
|
||||
clips: clipsValue.map((clipValue, clipIndex) =>
|
||||
readProjectSequenceClip(
|
||||
clipValue,
|
||||
`${label}.sequences.${sequenceKey}.clips.${clipIndex}`
|
||||
effects: effectsValue.map((effectValue, effectIndex) =>
|
||||
readProjectSequenceEffect(
|
||||
effectValue,
|
||||
`${label}.sequences.${sequenceKey}.effects.${effectIndex}`
|
||||
)
|
||||
)
|
||||
});
|
||||
@@ -4497,7 +4451,8 @@ export function migrateSceneDocument(source: unknown): SceneDocument {
|
||||
source.version !== NPC_DIALOGUE_REFERENCE_SCENE_DOCUMENT_VERSION &&
|
||||
source.version !== PROJECT_DIALOGUE_LIBRARY_SCENE_DOCUMENT_VERSION &&
|
||||
source.version !== PLAYER_START_PAUSE_BINDINGS_SCENE_DOCUMENT_VERSION &&
|
||||
source.version !== PROJECT_SEQUENCE_LIBRARY_SCENE_DOCUMENT_VERSION
|
||||
source.version !== PROJECT_SEQUENCE_LIBRARY_SCENE_DOCUMENT_VERSION &&
|
||||
source.version !== PROJECT_SEQUENCE_TIMING_SCENE_DOCUMENT_VERSION
|
||||
) {
|
||||
throw new Error(
|
||||
`Unsupported scene document version: ${String(source.version)}.`
|
||||
|
||||
@@ -88,8 +88,7 @@ import type {
|
||||
import {
|
||||
getHeldSequenceControlEffects,
|
||||
getProjectScheduleRoutineHeldSteps,
|
||||
getProjectSequenceImpulseSteps,
|
||||
getSequenceClipEndMinute
|
||||
getProjectSequenceImpulseSteps
|
||||
} from "../sequencer/project-sequence-steps";
|
||||
|
||||
export type SceneDiagnosticSeverity = "error" | "warning";
|
||||
@@ -4806,146 +4805,40 @@ function validateProjectSequence(
|
||||
);
|
||||
}
|
||||
|
||||
if (sequence.clips.length === 0) {
|
||||
if (sequence.effects.length === 0) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clips-empty",
|
||||
"Project sequences must contain at least one clip.",
|
||||
`${path}.clips`
|
||||
"invalid-project-sequence-effects-empty",
|
||||
"Project sequences must contain at least one effect.",
|
||||
`${path}.effects`
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFiniteNumber(sequence.durationMinutes)) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-duration",
|
||||
"Project sequence duration must be a finite positive number of minutes.",
|
||||
`${path}.durationMinutes`
|
||||
)
|
||||
);
|
||||
} else if (
|
||||
sequence.durationMinutes < 1 ||
|
||||
sequence.durationMinutes > HOURS_PER_DAY * 60 ||
|
||||
Math.trunc(sequence.durationMinutes) !== sequence.durationMinutes
|
||||
) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-duration-range",
|
||||
"Project sequence duration must be an integer minute value between 1 and 1440.",
|
||||
`${path}.durationMinutes`
|
||||
)
|
||||
);
|
||||
}
|
||||
for (const [effectIndex, effect] of sequence.effects.entries()) {
|
||||
const effectPath = `${path}.effects.${effectIndex}`;
|
||||
|
||||
for (const [clipIndex, clip] of sequence.clips.entries()) {
|
||||
const clipPath = `${path}.clips.${clipIndex}`;
|
||||
|
||||
if (!isFiniteNumber(clip.startMinute)) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clip-start",
|
||||
"Sequence clip start must be a finite non-negative integer minute value.",
|
||||
`${clipPath}.startMinute`
|
||||
)
|
||||
);
|
||||
} else if (
|
||||
clip.startMinute < 0 ||
|
||||
Math.trunc(clip.startMinute) !== clip.startMinute
|
||||
) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clip-start-range",
|
||||
"Sequence clip start must be a non-negative integer minute value.",
|
||||
`${clipPath}.startMinute`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isFiniteNumber(clip.durationMinutes)) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clip-duration",
|
||||
"Sequence clip duration must be a finite positive integer minute value.",
|
||||
`${clipPath}.durationMinutes`
|
||||
)
|
||||
);
|
||||
} else if (
|
||||
clip.durationMinutes < 1 ||
|
||||
Math.trunc(clip.durationMinutes) !== clip.durationMinutes
|
||||
) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clip-duration-range",
|
||||
"Sequence clip duration must be a positive integer minute value.",
|
||||
`${clipPath}.durationMinutes`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isFiniteNumber(clip.lane)) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clip-lane",
|
||||
"Sequence clip lane must be a finite non-negative integer value.",
|
||||
`${clipPath}.lane`
|
||||
)
|
||||
);
|
||||
} else if (clip.lane < 0 || Math.trunc(clip.lane) !== clip.lane) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clip-lane-range",
|
||||
"Sequence clip lane must be a non-negative integer value.",
|
||||
`${clipPath}.lane`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
isFiniteNumber(sequence.durationMinutes) &&
|
||||
isFiniteNumber(clip.startMinute) &&
|
||||
isFiniteNumber(clip.durationMinutes) &&
|
||||
getSequenceClipEndMinute(clip) > sequence.durationMinutes
|
||||
) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"invalid-project-sequence-clip-overflow",
|
||||
"Sequence clips must fit within the authored sequence duration.",
|
||||
`${clipPath}.durationMinutes`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
switch (clip.type) {
|
||||
switch (effect.type) {
|
||||
case "controlEffect":
|
||||
validateProjectSchedulerEffect(
|
||||
clip.effect,
|
||||
`${clipPath}.effect`,
|
||||
effect.effect,
|
||||
`${effectPath}.effect`,
|
||||
context,
|
||||
diagnostics
|
||||
);
|
||||
break;
|
||||
case "startDialogue":
|
||||
if (
|
||||
projectResources.dialogues.dialogues[clip.dialogueId] === undefined
|
||||
projectResources.dialogues.dialogues[effect.dialogueId] === undefined
|
||||
) {
|
||||
diagnostics.push(
|
||||
createDiagnostic(
|
||||
"error",
|
||||
"missing-sequence-dialogue-resource",
|
||||
`Dialogue ${clip.dialogueId} does not exist in the project dialogue library.`,
|
||||
`${clipPath}.dialogueId`
|
||||
`Dialogue ${effect.dialogueId} does not exist in the project dialogue library.`,
|
||||
`${effectPath}.dialogueId`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user