Add support for scheduled control routines in project scheduler
This commit is contained in:
@@ -6,6 +6,9 @@ import {
|
|||||||
createDefaultResolvedControlSource,
|
createDefaultResolvedControlSource,
|
||||||
createSchedulerResolvedControlSource,
|
createSchedulerResolvedControlSource,
|
||||||
createSetActorPresenceControlEffect,
|
createSetActorPresenceControlEffect,
|
||||||
|
getControlEffectResolutionKey,
|
||||||
|
type ControlEffect,
|
||||||
|
type ControlTargetRef,
|
||||||
type RuntimeResolvedControlState,
|
type RuntimeResolvedControlState,
|
||||||
type SetActorPresenceControlEffect
|
type SetActorPresenceControlEffect
|
||||||
} from "../controls/control-surface";
|
} from "../controls/control-surface";
|
||||||
@@ -26,8 +29,17 @@ export interface RuntimeResolvedActorScheduleState {
|
|||||||
effect: SetActorPresenceControlEffect | null;
|
effect: SetActorPresenceControlEffect | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RuntimeResolvedScheduledControlRoutine {
|
||||||
|
routineId: string;
|
||||||
|
title: string;
|
||||||
|
target: ControlTargetRef;
|
||||||
|
effect: ControlEffect;
|
||||||
|
resolutionKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface RuntimeResolvedProjectScheduleState {
|
export interface RuntimeResolvedProjectScheduleState {
|
||||||
actors: RuntimeResolvedActorScheduleState[];
|
actors: RuntimeResolvedActorScheduleState[];
|
||||||
|
controls: RuntimeResolvedScheduledControlRoutine[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuntimeProjectSchedulerState {
|
export interface RuntimeProjectSchedulerState {
|
||||||
@@ -52,13 +64,21 @@ export function cloneRuntimeResolvedProjectScheduleState(
|
|||||||
state: RuntimeResolvedProjectScheduleState
|
state: RuntimeResolvedProjectScheduleState
|
||||||
): RuntimeResolvedProjectScheduleState {
|
): RuntimeResolvedProjectScheduleState {
|
||||||
return {
|
return {
|
||||||
actors: state.actors.map(cloneRuntimeResolvedActorScheduleState)
|
actors: state.actors.map(cloneRuntimeResolvedActorScheduleState),
|
||||||
|
controls: state.controls.map((routine) => ({
|
||||||
|
routineId: routine.routineId,
|
||||||
|
title: routine.title,
|
||||||
|
target: cloneControlEffect(routine.effect).target,
|
||||||
|
effect: cloneControlEffect(routine.effect),
|
||||||
|
resolutionKey: routine.resolutionKey
|
||||||
|
}))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createEmptyRuntimeResolvedProjectScheduleState(): RuntimeResolvedProjectScheduleState {
|
export function createEmptyRuntimeResolvedProjectScheduleState(): RuntimeResolvedProjectScheduleState {
|
||||||
return {
|
return {
|
||||||
actors: []
|
actors: [],
|
||||||
|
controls: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,17 +162,62 @@ export function resolveRuntimeProjectScheduleState(options: {
|
|||||||
dayNumber: options.dayNumber,
|
dayNumber: options.dayNumber,
|
||||||
timeOfDayHours: options.timeOfDayHours
|
timeOfDayHours: options.timeOfDayHours
|
||||||
})
|
})
|
||||||
)
|
),
|
||||||
|
controls: resolveRuntimeScheduledControlRoutines(options)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveRuntimeScheduledControlRoutines(options: {
|
||||||
|
scheduler: ProjectScheduler;
|
||||||
|
dayNumber: number;
|
||||||
|
timeOfDayHours: number;
|
||||||
|
}): RuntimeResolvedScheduledControlRoutine[] {
|
||||||
|
const activeRoutines = Object.values(options.scheduler.routines)
|
||||||
|
.filter((routine) =>
|
||||||
|
isProjectScheduleRoutineActiveAt(
|
||||||
|
routine,
|
||||||
|
options.dayNumber,
|
||||||
|
options.timeOfDayHours
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.sort(compareProjectScheduleRoutinePriority);
|
||||||
|
const seenResolutionKeys = new Set<string>();
|
||||||
|
const resolved: RuntimeResolvedScheduledControlRoutine[] = [];
|
||||||
|
|
||||||
|
for (const routine of activeRoutines) {
|
||||||
|
if (routine.effect.type === "setActorPresence") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolutionKey = getControlEffectResolutionKey(routine.effect);
|
||||||
|
|
||||||
|
if (seenResolutionKeys.has(resolutionKey)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
seenResolutionKeys.add(resolutionKey);
|
||||||
|
resolved.push({
|
||||||
|
routineId: routine.id,
|
||||||
|
title: routine.title,
|
||||||
|
target: cloneControlEffect(routine.effect).target,
|
||||||
|
effect: cloneControlEffect(routine.effect),
|
||||||
|
resolutionKey
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
export function applyRuntimeProjectScheduleToControlState(
|
export function applyRuntimeProjectScheduleToControlState(
|
||||||
resolved: RuntimeResolvedControlState,
|
resolved: RuntimeResolvedControlState,
|
||||||
schedule: RuntimeResolvedProjectScheduleState
|
schedule: RuntimeResolvedProjectScheduleState
|
||||||
): RuntimeResolvedControlState {
|
): RuntimeResolvedControlState {
|
||||||
let nextResolved = cloneRuntimeResolvedControlState(resolved);
|
let nextResolved = cloneRuntimeResolvedControlState(resolved);
|
||||||
nextResolved.discrete = nextResolved.discrete.filter(
|
nextResolved.discrete = nextResolved.discrete.filter(
|
||||||
(state) => state.type !== "actorPresence"
|
(state) => state.type !== "actorPresence" && state.source.kind !== "scheduler"
|
||||||
|
);
|
||||||
|
nextResolved.channels = nextResolved.channels.filter(
|
||||||
|
(channel) => channel.source.kind !== "scheduler"
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const actorState of schedule.actors) {
|
for (const actorState of schedule.actors) {
|
||||||
@@ -171,5 +236,13 @@ export function applyRuntimeProjectScheduleToControlState(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const controlRoutine of schedule.controls) {
|
||||||
|
nextResolved = applyControlEffectToResolvedState(
|
||||||
|
nextResolved,
|
||||||
|
controlRoutine.effect,
|
||||||
|
createSchedulerResolvedControlSource(controlRoutine.routineId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return nextResolved;
|
return nextResolved;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user