77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
import {
|
|
SEQUENCER_MEDIA_REVISION_SCHEMA,
|
|
gateSequencerMediaRevision,
|
|
parseSequencerMediaRevisionRequest,
|
|
parseSequencerMediaRevisionState,
|
|
SequencerMediaRevisionValidationError,
|
|
type SequencerMediaOperation,
|
|
type SequencerMediaRevisionDecisionIR,
|
|
type SequencerMediaRevisionRequestIR,
|
|
type SequencerMediaRevisionResultIR,
|
|
type SequencerMediaRevisionStateIR,
|
|
} from "../../../protocol/sequencer-media-revision";
|
|
|
|
export class SequencerMediaRevisionGate {
|
|
private stateValue: SequencerMediaRevisionStateIR;
|
|
|
|
constructor(timelineId: string, timelineRevision: number) {
|
|
this.stateValue = parseSequencerMediaRevisionState({
|
|
schemaVersion: SEQUENCER_MEDIA_REVISION_SCHEMA,
|
|
timelineId,
|
|
timelineRevision,
|
|
latestRequestRevision: 0,
|
|
});
|
|
}
|
|
|
|
state(): SequencerMediaRevisionStateIR {
|
|
return { ...this.stateValue };
|
|
}
|
|
|
|
begin(operation: SequencerMediaOperation, frame: number): SequencerMediaRevisionRequestIR {
|
|
this.stateValue = {
|
|
...this.stateValue,
|
|
latestRequestRevision: this.stateValue.latestRequestRevision + 1,
|
|
};
|
|
return parseSequencerMediaRevisionRequest({
|
|
schemaVersion: SEQUENCER_MEDIA_REVISION_SCHEMA,
|
|
requestId: `media:${this.stateValue.latestRequestRevision}`,
|
|
timelineId: this.stateValue.timelineId,
|
|
timelineRevision: this.stateValue.timelineRevision,
|
|
requestRevision: this.stateValue.latestRequestRevision,
|
|
operation,
|
|
frame,
|
|
});
|
|
}
|
|
|
|
replaceTimeline(timelineId: string, timelineRevision: number): SequencerMediaRevisionStateIR {
|
|
if (timelineId === this.stateValue.timelineId && timelineRevision <= this.stateValue.timelineRevision) {
|
|
throw new SequencerMediaRevisionValidationError("REVISION_CONFLICT", "Sequencer timeline revision must advance monotonically");
|
|
}
|
|
this.stateValue = parseSequencerMediaRevisionState({
|
|
schemaVersion: SEQUENCER_MEDIA_REVISION_SCHEMA,
|
|
timelineId,
|
|
timelineRevision,
|
|
latestRequestRevision: this.stateValue.latestRequestRevision + 1,
|
|
});
|
|
return this.state();
|
|
}
|
|
|
|
resolve(
|
|
request: SequencerMediaRevisionRequestIR,
|
|
result: SequencerMediaRevisionResultIR,
|
|
publish: (result: SequencerMediaRevisionResultIR) => void,
|
|
): SequencerMediaRevisionDecisionIR {
|
|
const decision = gateSequencerMediaRevision(request, this.stateValue, result);
|
|
if (decision.status === "PUBLISH") publish(result);
|
|
return decision;
|
|
}
|
|
}
|
|
|
|
export type {
|
|
SequencerMediaOperation,
|
|
SequencerMediaRevisionDecisionIR,
|
|
SequencerMediaRevisionRequestIR,
|
|
SequencerMediaRevisionResultIR,
|
|
SequencerMediaRevisionStateIR,
|
|
};
|