Skip to content

Commit

Permalink
feat: sisyfos retrigger mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
mint-dewit authored and eol-account committed Mar 23, 2021
1 parent 78a3ecd commit 26033cd
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 7 deletions.
200 changes: 198 additions & 2 deletions src/devices/__tests__/sisyfos.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,8 @@ describe('Sisyfos', () => {
duration: 2000
},
layer: 'sisyfos_channel_1',
// @ts-ignore: for backwards compatibility
content: {
deviceType: DeviceType.SISYFOS,
// @ts-ignore: for backwards compatibility
type: 'sisyfos',

isPgm: 1
Expand Down Expand Up @@ -791,6 +789,204 @@ describe('Sisyfos', () => {
commandReceiver0.mockClear()
})

test('Sisyfos: using triggerValue', async () => {

const commandReceiver0: any = jest.fn(() => {
return Promise.resolve()
})
let myChannelMapping0: MappingSisyfos = {
device: DeviceType.SISYFOS,
mappingType: MappingSisyfosType.CHANNELS,
deviceId: 'mySisyfos'
}
let myChannelMapping1: MappingSisyfos = {
device: DeviceType.SISYFOS,
mappingType: MappingSisyfosType.CHANNEL,
deviceId: 'mySisyfos',
channel: 1
}
let myChannelMapping2: MappingSisyfos = {
device: DeviceType.SISYFOS,
mappingType: MappingSisyfosType.CHANNEL,
deviceId: 'mySisyfos',
channel: 2
}
let myChannelMapping3: MappingSisyfos = {
device: DeviceType.SISYFOS,
mappingType: MappingSisyfosType.CHANNELS,
deviceId: 'mySisyfos'
}
let myChannelMapping: Mappings = {
'sisyfos_channels_base': myChannelMapping0,
'sisyfos_channel_1': myChannelMapping1,
'sisyfos_channel_2': myChannelMapping2,
'sisyfos_channels': myChannelMapping3
}

let myConductor = new Conductor({
initializeAsClear: true,
getCurrentTime: mockTime.getCurrentTime
})
myConductor.setTimelineAndMappings([], myChannelMapping)
await myConductor.init() // we cannot do an await, because setTimeout will never call without jest moving on.
await myConductor.addDevice('mySisyfos', {
type: DeviceType.SISYFOS,
options: {
commandReceiver: commandReceiver0,
host: '192.168.0.10',
port: 8900
}
})
await mockTime.advanceTimeToTicks(10100)

let deviceContainer = myConductor.getDevice('mySisyfos')
let device = deviceContainer.device as ThreadedClass<SisyfosMessageDevice>

// Check that no commands has been scheduled:
expect(await device.queue).toHaveLength(0)

myConductor.setTimelineAndMappings([
{
id: 'baseline',
enable: {
while: 1
},
layer: 'sisyfos_channels_base',
content: {
deviceType: DeviceType.SISYFOS,
type: TimelineContentTypeSisyfos.CHANNELS,

channels: [
{
mappedLayer: 'sisyfos_channel_1',
faderLevel: 0.1,
isPgm: 0
},
{
mappedLayer: 'sisyfos_channel_2',
faderLevel: 0.2,
isPgm: 0
}
],
triggerValue: 'a',
overridePriority: -999
}
},
{
id: 'obj1',
enable: {
start: mockTime.now + 1000, // 1 seconds in the future
duration: 10000
},
layer: 'sisyfos_channel_1',
content: {
deviceType: DeviceType.SISYFOS,
type: TimelineContentTypeSisyfos.TRIGGERVALUE,
triggerValue: 'b'
}
},
{
id: 'obj2',
enable: {
start: mockTime.now + 1000, // 1 seconds in the future
duration: 10000
},
layer: 'sisyfos_channel_2',
content: {
deviceType: DeviceType.SISYFOS,
type: TimelineContentTypeSisyfos.CHANNEL,

isPgm: 1
}
}
])

// baseline:
await mockTime.advanceTimeTicks(100) // 100
expect(commandReceiver0.mock.calls.length).toEqual(3)
expect(getMockCall(commandReceiver0, 0, 1)).toMatchObject({
type: 'setChannel',
channel: 0,
values: {
faderLevel: 0.75
}
})
expect(getMockCall(commandReceiver0, 1, 1)).toMatchObject({
type: 'setChannel',
channel: 1,
values: {
faderLevel: 0.1,
pgmOn: 0
}
})
expect(getMockCall(commandReceiver0, 2, 1)).toMatchObject({
type: 'setChannel',
channel: 2,
values: {
faderLevel: 0.2,
pgmOn: 0
}
})
commandReceiver0.mockClear()

// obj1 has started
await mockTime.advanceTimeTicks(1000) // 1100
expect(commandReceiver0.mock.calls.length).toEqual(3)
expect(getMockCall(commandReceiver0, 0, 1)).toMatchObject({
type: 'setChannel',
channel: 0,
values: {
faderLevel: 0.75
}
})
expect(getMockCall(commandReceiver0, 1, 1)).toMatchObject({
type: 'setChannel',
channel: 1,
values: {
faderLevel: 0.1,
pgmOn: 0
}
})
expect(getMockCall(commandReceiver0, 2, 1)).toMatchObject({
type: 'setChannel',
channel: 2,
values: {
faderLevel: 0.2,
pgmOn: 1
}
})
commandReceiver0.mockClear()

// back to baseline
await mockTime.advanceTimeTicks(10000) // 11100
expect(commandReceiver0.mock.calls.length).toEqual(3)
expect(getMockCall(commandReceiver0, 0, 1)).toMatchObject({
type: 'setChannel',
channel: 0,
values: {
faderLevel: 0.75
}
})
expect(getMockCall(commandReceiver0, 1, 1)).toMatchObject({
type: 'setChannel',
channel: 1,
values: {
faderLevel: 0.1,
pgmOn: 0
}
})
expect(getMockCall(commandReceiver0, 2, 1)).toMatchObject({
type: 'setChannel',
channel: 2,
values: {
faderLevel: 0.2,
pgmOn: 0
}
})

commandReceiver0.mockClear()
})

test('Connection status', async () => {
const commandReceiver0: any = jest.fn(() => {
return Promise.resolve()
Expand Down
22 changes: 21 additions & 1 deletion src/devices/sisyfos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ export class SisyfosMessageDevice extends DeviceWithState<SisyfosState> implemen
deviceState.resync = deviceState.resync || layer.content.resync
}

// Allow retrigger without valid channel mapping
if (layer.content.triggerValue !== undefined) {
deviceState.triggerValue = layer.content.triggerValue
}

// if the tlObj is specifies to load to PST the original Layer is used to resolve the mapping
if (!foundMapping && layer.isLookahead && layer.lookaheadForLayer) {
foundMapping = mappings[layer.lookaheadForLayer] as MappingSisyfos | undefined
Expand All @@ -312,6 +317,7 @@ export class SisyfosMessageDevice extends DeviceWithState<SisyfosState> implemen
isLookahead: layer.isLookahead || false,
tlObjId: layer.id
})
deviceState.resync = deviceState.resync || content.resync || false
} else if (
foundMapping.mappingType === MappingSisyfosType.CHANNELS &&
content.type === TimelineContentTypeSisyfos.CHANNELS
Expand All @@ -329,8 +335,8 @@ export class SisyfosMessageDevice extends DeviceWithState<SisyfosState> implemen
})
}
})
deviceState.resync = deviceState.resync || content.resync || false
}
deviceState.resync = deviceState.resync || content.resync || false
}

})
Expand Down Expand Up @@ -403,6 +409,20 @@ export class SisyfosMessageDevice extends DeviceWithState<SisyfosState> implemen
_.each(newOscSendState.channels, (newChannel: SisyfosChannel, index) => {
const oldChannel = oldOscSendState.channels[index]

if ((newOscSendState.triggerValue && newOscSendState.triggerValue !== oldOscSendState.triggerValue)) { // || (!oldChannel && Number(index) >= 0)) {
// push commands for everything
commands.push({
context: `Channel ${index} reset`,
content: {
type: SisyfosCommandType.SET_CHANNEL,
channel: Number(index),
values: newChannel
},
timelineObjId: newChannel.tlObjIds[0] || ''
})
return
}

if (oldChannel && oldChannel.pgmOn !== newChannel.pgmOn) {
commands.push({
context: `Channel ${index} pgm goes from "${oldChannel.pgmOn}" to "${newChannel.pgmOn}"`,
Expand Down
43 changes: 41 additions & 2 deletions src/devices/sisyfosAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,37 @@ export class SisyfosApi extends EventEmitter {
type: 'i',
value: (command as ValueCommand).value
}] })
} else if (command.type === SisyfosCommandType.SET_CHANNEL) {
if ((command as SetChannelCommand).values.label) {
this._oscClient.send({ address: `/ch/${(command as StringCommand).channel + 1}/label`, args: [{
type: 's',
value: (command as SetChannelCommand).values.label as string
}] })
}
if ((command as SetChannelCommand).values.pgmOn !== undefined) {
this._oscClient.send({ address: `/ch/${(command as ValueCommand).channel + 1}/pgm`, args: [{
type: 'i',
value: (command as SetChannelCommand).values.pgmOn as number
}] })
}
if ((command as SetChannelCommand).values.pstOn !== undefined) {
this._oscClient.send({ address: `/ch/${(command as ValueCommand).channel + 1}/pst`, args: [{
type: 'i',
value: (command as SetChannelCommand).values.pstOn as number
}] })
}
if ((command as SetChannelCommand).values.faderLevel !== undefined) {
this._oscClient.send({ address: `/ch/${(command as ValueCommand).channel + 1}/faderlevel`, args: [{
type: 'f',
value: (command as SetChannelCommand).values.faderLevel as number
}] })
}
if ((command as SetChannelCommand).values.visible !== undefined) {
this._oscClient.send({ address: `/ch/${(command as ValueCommand).channel + 1}/visible`, args: [{
type: 'i',
value: (command as SetChannelCommand).values.visible as unknown as number
}] })
}
}
}

Expand Down Expand Up @@ -242,13 +273,20 @@ export enum SisyfosCommandType {
LABEL = 'label',
TAKE = 'take',
VISIBLE = 'visible',
RESYNC = 'resync'
RESYNC = 'resync',
SET_CHANNEL = 'setChannel'
}

export interface BaseCommand {
type: SisyfosCommandType
}

export interface SetChannelCommand {
type: SisyfosCommandType.SET_CHANNEL
channel: number
values: Partial<SisyfosAPIChannel>
}

export interface ChannelCommand {
type: SisyfosCommandType.SET_FADER | SisyfosCommandType.TOGGLE_PGM | SisyfosCommandType.TOGGLE_PST | SisyfosCommandType.LABEL | SisyfosCommandType.VISIBLE
channel: number
Expand All @@ -273,14 +311,15 @@ export interface ResyncCommand extends BaseCommand {
type: SisyfosCommandType.RESYNC
}

export type SisyfosCommand = BaseCommand | ValueCommand | BoolCommand | StringCommand | ResyncCommand
export type SisyfosCommand = BaseCommand | ValueCommand | BoolCommand | StringCommand | ResyncCommand | SetChannelCommand

export interface SisyfosChannel extends SisyfosAPIChannel {
tlObjIds: string[]
}
export interface SisyfosState {
channels: { [index: string]: SisyfosChannel }
resync: boolean
triggerValue?: string
}

// ------------------------------------------------------
Expand Down
14 changes: 12 additions & 2 deletions src/types/src/sisyfos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ export enum TimelineContentTypeSisyfos {
/** @deprecated use CHANNEL instead */
SISYFOS = 'sisyfos',
CHANNEL = 'channel',
CHANNELS = 'channels'
CHANNELS = 'channels',
TRIGGERVALUE = 'triggerValue'
}

export type TimelineObjSisyfosAny = TimelineObjSisyfosChannel | TimelineObjSisyfosChannels
export type TimelineObjSisyfosAny = TimelineObjSisyfosChannel | TimelineObjSisyfosChannels | TimelineObjSisyfosTriggerValue

export interface TimelineObjSisyfos extends TSRTimelineObjBase {
content: {
Expand All @@ -46,6 +47,14 @@ export interface SisyfosChannelOptions {
visible?: boolean
}

export interface TimelineObjSisyfosTriggerValue extends TimelineObjSisyfos {
content: {
deviceType: DeviceType.SISYFOS
type: TimelineContentTypeSisyfos.TRIGGERVALUE

triggerValue: string
}
}
export interface TimelineObjSisyfosChannel extends TimelineObjSisyfos {
content: {
deviceType: DeviceType.SISYFOS
Expand All @@ -66,6 +75,7 @@ export interface TimelineObjSisyfosChannels extends TimelineObjSisyfos {
)[],
resync?: boolean
overridePriority?: number // defaults to 0
triggerValue?: string
}
}
// Backwards compatibility:
Expand Down

0 comments on commit 26033cd

Please sign in to comment.