Skip to content

Commit

Permalink
fix: adjust reactive-var typings, and propogate current computation
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Nov 1, 2024
1 parent 519f254 commit 294c980
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 132 deletions.
12 changes: 7 additions & 5 deletions meteor/server/api/deviceTriggers/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Meteor.startup(() => {
const manager = new StudioDeviceTriggerManager(studioId)
const observer = new StudioObserver(studioId, (showStyleBaseId, cache) => {
workInQueue(async () => {
await manager.updateTriggers(cache, showStyleBaseId, null) // nocommit - confirm this
await manager.updateTriggers(cache, showStyleBaseId, null)
})

return () => {
Expand Down Expand Up @@ -117,10 +117,12 @@ export async function receiveInputDeviceTrigger(
if (!actionManager)
throw new Meteor.Error(500, `No Studio Action Manager available to handle trigger in Studio "${studioId}"`)

DeviceTriggerMountedActions.find({
const mountedActions = DeviceTriggerMountedActions.find({
deviceId,
deviceTriggerId: triggerId,
}).forEach((mountedAction) => {
}).fetch()

for (const mountedAction of mountedActions) {
if (values && !_.isMatch(values, mountedAction.values)) return
const executableAction = actionManager.getAction(mountedAction.actionId)
if (!executableAction)
Expand All @@ -132,6 +134,6 @@ export async function receiveInputDeviceTrigger(
const context = actionManager.getContext()
if (!context) throw new Meteor.Error(500, `Undefined Device Trigger context for studio "${studioId}"`)

executableAction.execute((t: ITranslatableMessage) => t.key ?? t, `${deviceId}: ${triggerId}`, context)
})
await executableAction.execute((t: ITranslatableMessage) => t.key ?? t, `${deviceId}: ${triggerId}`, context)
}
}
18 changes: 9 additions & 9 deletions meteor/server/api/deviceTriggers/triggersContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function hashSingleUseToken(token: string): string {
return getHash(SINGLE_USE_TOKEN_SALT + token)
}

class TriggersCollection2<DBInterface extends { _id: ProtectedString<any> }>
class MeteorTriggersCollectionWrapper<DBInterface extends { _id: ProtectedString<any> }>
implements TriggersAsyncCollection<DBInterface>
{
readonly #collection: AsyncOnlyReadOnlyMongoCollection<DBInterface>
Expand Down Expand Up @@ -75,14 +75,14 @@ export const MeteorTriggersContext: TriggersContext = {

isClient: false,

AdLibActions: new TriggersCollection2(AdLibActions),
AdLibPieces: new TriggersCollection2(AdLibPieces),
Parts: new TriggersCollection2(Parts),
RundownBaselineAdLibActions: new TriggersCollection2(RundownBaselineAdLibActions),
RundownBaselineAdLibPieces: new TriggersCollection2(RundownBaselineAdLibPieces),
RundownPlaylists: new TriggersCollection2(RundownPlaylists),
Rundowns: new TriggersCollection2(Rundowns),
Segments: new TriggersCollection2(Segments),
AdLibActions: new MeteorTriggersCollectionWrapper(AdLibActions),
AdLibPieces: new MeteorTriggersCollectionWrapper(AdLibPieces),
Parts: new MeteorTriggersCollectionWrapper(Parts),
RundownBaselineAdLibActions: new MeteorTriggersCollectionWrapper(RundownBaselineAdLibActions),
RundownBaselineAdLibPieces: new MeteorTriggersCollectionWrapper(RundownBaselineAdLibPieces),
RundownPlaylists: new MeteorTriggersCollectionWrapper(RundownPlaylists),
Rundowns: new MeteorTriggersCollectionWrapper(Rundowns),
Segments: new MeteorTriggersCollectionWrapper(Segments),

hashSingleUseToken,

Expand Down
80 changes: 46 additions & 34 deletions packages/meteor-lib/src/triggers/actionFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
import { DeviceActions } from '@sofie-automation/shared-lib/dist/core/model/ShowStyle'
import { UserError, UserErrorMessage } from '@sofie-automation/corelib/dist/error'
import { MountedAdLibTriggerType } from '../api/MountedTriggers'
import { DummyReactiveVar, ReactiveVar } from './reactive-var'
import { DummyReactiveVar, TriggerReactiveVar } from './reactive-var'
import { TriggersContext, TriggerTrackerComputation } from './triggersContext'
import { assertNever } from '@sofie-automation/corelib/dist/lib'

Expand All @@ -36,18 +36,18 @@ type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U

export interface ReactivePlaylistActionContext {
studioId: ReactiveVar<StudioId>
rundownPlaylistId: ReactiveVar<RundownPlaylistId>
rundownPlaylist: ReactiveVar<
studioId: TriggerReactiveVar<StudioId>
rundownPlaylistId: TriggerReactiveVar<RundownPlaylistId>
rundownPlaylist: TriggerReactiveVar<
Pick<DBRundownPlaylist, '_id' | 'name' | 'activationId' | 'nextPartInfo' | 'currentPartInfo'>
>

currentRundownId: ReactiveVar<RundownId | null>
currentSegmentPartIds: ReactiveVar<PartId[]>
nextSegmentPartIds: ReactiveVar<PartId[]>
currentPartInstanceId: ReactiveVar<PartInstanceId | null>
currentPartId: ReactiveVar<PartId | null>
nextPartId: ReactiveVar<PartId | null>
currentRundownId: TriggerReactiveVar<RundownId | null>
currentSegmentPartIds: TriggerReactiveVar<PartId[]>
nextSegmentPartIds: TriggerReactiveVar<PartId[]>
currentPartInstanceId: TriggerReactiveVar<PartInstanceId | null>
currentPartId: TriggerReactiveVar<PartId | null>
nextPartId: TriggerReactiveVar<PartId | null>
}

interface PlainPlaylistContext {
Expand Down Expand Up @@ -111,7 +111,6 @@ async function createRundownPlaylistContext(
if (filterChain.length < 1) {
return undefined
} else if (filterChain[0].object === 'view' && context.rundownPlaylistId) {
// nocommit - rewrap to track on this computation?
return context as ReactivePlaylistActionContext
} else if (filterChain[0].object === 'view' && context.rundownPlaylist) {
const playlistContext = context as PlainPlaylistContext
Expand Down Expand Up @@ -180,11 +179,11 @@ function createAdLibAction(
)
return
}
const currentPartInstanceId = innerCtx.rundownPlaylist.get().currentPartInfo?.partInstanceId
const currentPartInstanceId = innerCtx.rundownPlaylist.get(null).currentPartInfo?.partInstanceId

const sourceLayerIdsToClear: string[] = []

// nocommit - discard the withComputation?
// This withComputation is probably not needed, but is a nice safeguard
const wrappedAdLibs = await triggersContext.withComputation(null, async () =>
compiledAdLibFilter(innerCtx, null)
)
Expand All @@ -197,7 +196,7 @@ function createAdLibAction(
? triggersContext.MeteorCall.userAction.segmentAdLibPieceStart(
e,
ts,
innerCtx.rundownPlaylistId.get(),
innerCtx.rundownPlaylistId.get(null),
currentPartInstanceId,
wrappedAdLib.item._id,
false
Expand All @@ -211,7 +210,7 @@ function createAdLibAction(
? triggersContext.MeteorCall.userAction.baselineAdLibPieceStart(
e,
ts,
innerCtx.rundownPlaylistId.get(),
innerCtx.rundownPlaylistId.get(null),
currentPartInstanceId,
wrappedAdLib.item._id,
false
Expand All @@ -224,7 +223,7 @@ function createAdLibAction(
triggersContext.MeteorCall.userAction.executeAction(
e,
ts,
innerCtx.rundownPlaylistId.get(),
innerCtx.rundownPlaylistId.get(null),
wrappedAdLib._id,
wrappedAdLib.item.actionId,
wrappedAdLib.item.userData,
Expand All @@ -237,7 +236,7 @@ function createAdLibAction(
triggersContext.MeteorCall.userAction.executeAction(
e,
ts,
innerCtx.rundownPlaylistId.get(),
innerCtx.rundownPlaylistId.get(null),
wrappedAdLib._id,
wrappedAdLib.item.actionId,
wrappedAdLib.item.userData,
Expand All @@ -254,7 +253,7 @@ function createAdLibAction(
triggersContext.MeteorCall.userAction.sourceLayerStickyPieceStart(
e,
ts,
innerCtx.rundownPlaylistId.get(),
innerCtx.rundownPlaylistId.get(null),
wrappedAdLib.sourceLayerId //
)
)
Expand All @@ -270,7 +269,7 @@ function createAdLibAction(
triggersContext.MeteorCall.userAction.sourceLayerOnPartStop(
e,
ts,
innerCtx.rundownPlaylistId.get(),
innerCtx.rundownPlaylistId.get(null),
currentPartInstanceId,
sourceLayerIdsToClear
)
Expand Down Expand Up @@ -463,7 +462,7 @@ export function createAction(
triggersContext.MeteorCall.userAction.forceResetAndActivate(
e,
ts,
ctx.rundownPlaylistId.get(),
ctx.rundownPlaylistId.get(null),
!!action.rehearsal || false
)
)
Expand All @@ -482,7 +481,7 @@ export function createAction(
triggersContext.MeteorCall.userAction.activate(
e,
ts,
ctx.rundownPlaylistId.get(),
ctx.rundownPlaylistId.get(null),
!!action.rehearsal || false
)
)
Expand All @@ -497,20 +496,20 @@ export function createAction(
action,
UserAction.DEACTIVATE_RUNDOWN_PLAYLIST,
async (e, ts, ctx) =>
triggersContext.MeteorCall.userAction.deactivate(e, ts, ctx.rundownPlaylistId.get())
triggersContext.MeteorCall.userAction.deactivate(e, ts, ctx.rundownPlaylistId.get(null))
)
case PlayoutActions.activateAdlibTestingMode:
return createUserActionWithCtx(
triggersContext,
action,
UserAction.ACTIVATE_ADLIB_TESTING,
async (e, ts, ctx) => {
const rundownId = ctx.currentRundownId.get()
const rundownId = ctx.currentRundownId.get(null)
if (rundownId) {
return triggersContext.MeteorCall.userAction.activateAdlibTestingMode(
e,
ts,
ctx.rundownPlaylistId.get(),
ctx.rundownPlaylistId.get(null),
rundownId
)
} else {
Expand All @@ -526,21 +525,26 @@ export function createAction(
triggersContext.MeteorCall.userAction.take(
e,
ts,
ctx.rundownPlaylistId.get(),
ctx.currentPartInstanceId.get()
ctx.rundownPlaylistId.get(null),
ctx.currentPartInstanceId.get(null)
)
)
}
case PlayoutActions.hold:
return createUserActionWithCtx(triggersContext, action, UserAction.ACTIVATE_HOLD, async (e, ts, ctx) =>
triggersContext.MeteorCall.userAction.activateHold(e, ts, ctx.rundownPlaylistId.get(), !!action.undo)
triggersContext.MeteorCall.userAction.activateHold(
e,
ts,
ctx.rundownPlaylistId.get(null),
!!action.undo
)
)
case PlayoutActions.disableNextPiece:
return createUserActionWithCtx(triggersContext, action, UserAction.DISABLE_NEXT_PIECE, async (e, ts, ctx) =>
triggersContext.MeteorCall.userAction.disableNextPiece(
e,
ts,
ctx.rundownPlaylistId.get(),
ctx.rundownPlaylistId.get(null),
!!action.undo
)
)
Expand All @@ -559,7 +563,7 @@ export function createAction(
e,
ts,
triggersContext.hashSingleUseToken(tokenResult.result),
ctx.rundownPlaylistId.get(),
ctx.rundownPlaylistId.get(null),
`action`,
false
)
Expand All @@ -571,7 +575,7 @@ export function createAction(
triggersContext.MeteorCall.userAction.moveNext(
e,
ts,
ctx.rundownPlaylistId.get(),
ctx.rundownPlaylistId.get(null),
action.parts ?? 0,
action.segments ?? 0
)
Expand All @@ -587,7 +591,11 @@ export function createAction(
async (e, ts, ctx) =>
// TODO: Needs some handling of the response. Perhaps this should switch to
// an event on the RundownViewEventBus, if ran on the client?
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(e, ts, ctx.rundownPlaylistId.get())
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(
e,
ts,
ctx.rundownPlaylistId.get(null)
)
)
}
case PlayoutActions.resetRundownPlaylist:
Expand All @@ -599,7 +607,11 @@ export function createAction(
action,
UserAction.RESET_RUNDOWN_PLAYLIST,
async (e, ts, ctx) =>
triggersContext.MeteorCall.userAction.resetRundownPlaylist(e, ts, ctx.rundownPlaylistId.get())
triggersContext.MeteorCall.userAction.resetRundownPlaylist(
e,
ts,
ctx.rundownPlaylistId.get(null)
)
)
}
case PlayoutActions.resyncRundownPlaylist:
Expand All @@ -608,14 +620,14 @@ export function createAction(
action,
UserAction.RESYNC_RUNDOWN_PLAYLIST,
async (e, ts, ctx) =>
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(e, ts, ctx.rundownPlaylistId.get())
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(e, ts, ctx.rundownPlaylistId.get(null))
)
case PlayoutActions.switchRouteSet:
return createUserActionWithCtx(triggersContext, action, UserAction.SWITCH_ROUTE_SET, async (e, ts, ctx) =>
triggersContext.MeteorCall.userAction.switchRouteSet(
e,
ts,
ctx.studioId.get(),
ctx.studioId.get(null),
action.routeSetId,
action.state
)
Expand Down
14 changes: 7 additions & 7 deletions packages/meteor-lib/src/triggers/actionFilterChainCompilers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,16 +505,16 @@ export function compileAdLibFilter(
let adLibActions: IWrappedAdLib[] = []
const segmentPartIds =
adLibPieceTypeFilter.segment === 'current'
? context.currentSegmentPartIds.get()
? context.currentSegmentPartIds.get(computation)
: adLibPieceTypeFilter.segment === 'next'
? context.nextSegmentPartIds.get()
? context.nextSegmentPartIds.get(computation)
: undefined

const singlePartId =
adLibPieceTypeFilter.part === 'current'
? context.currentPartId.get()
? context.currentPartId.get(computation)
: adLibPieceTypeFilter.part === 'next'
? context.nextPartId.get()
? context.nextPartId.get(computation)
: undefined

/** Note: undefined means that all parts are to be considered */
Expand Down Expand Up @@ -554,7 +554,7 @@ export function compileAdLibFilter(
}
}

const currentRundownId = context.currentRundownId.get()
const currentRundownId = context.currentRundownId.get(computation)
if (!skip && currentRundownId) {
if (adLibPieceTypeFilter.global === undefined || adLibPieceTypeFilter.global === true)
rundownBaselineAdLibItems = (
Expand Down Expand Up @@ -597,7 +597,7 @@ export function compileAdLibFilter(
}
}

const currentRundownId = context.currentRundownId.get()
const currentRundownId = context.currentRundownId.get(computation)
if (!skip && currentRundownId) {
if (adLibActionTypeFilter.global === undefined || adLibActionTypeFilter.global === true)
rundownBaselineAdLibActions = (
Expand Down Expand Up @@ -636,7 +636,7 @@ export function compileAdLibFilter(
// Note: We need to return an array from within memoizedIsolatedAutorun,
// because _.isEqual (used in memoizedIsolatedAutorun) doesn't work with Maps..

const rundownPlaylistId = context.rundownPlaylistId.get()
const rundownPlaylistId = context.rundownPlaylistId.get(computation)
const rundownRanks = await triggersContext.memoizedIsolatedAutorun(
computation,
async (computation) => {
Expand Down
8 changes: 5 additions & 3 deletions packages/meteor-lib/src/triggers/reactive-var.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { TriggerTrackerComputation } from './triggersContext'

// Copied from Meteor
export interface ReactiveVar<T> {
export interface TriggerReactiveVar<T> {
/**
* Returns the current value of the ReactiveVar, establishing a reactive dependency.
*/
get(): T
get(computation: TriggerTrackerComputation | null): T
/**
* Sets the current value of the ReactiveVar, invalidating the Computations that called `get` if `newValue` is different from the old value.
*/
Expand All @@ -14,7 +16,7 @@ export interface ReactiveVar<T> {
* This just looks like a ReactiveVar, but is not reactive.
* It's used to use the same interface/typings, but when code is run on both client and server side.
* */
export class DummyReactiveVar<T> implements ReactiveVar<T> {
export class DummyReactiveVar<T> implements TriggerReactiveVar<T> {
constructor(private value: T) {}
public get(): T {
return this.value
Expand Down
Loading

0 comments on commit 294c980

Please sign in to comment.