Skip to content

Commit

Permalink
fix: scaling is not being setup correctly, when devices are added bef…
Browse files Browse the repository at this point in the history
…ore the connection is fully open
  • Loading branch information
Julusian committed Oct 30, 2023
1 parent ed56920 commit 4a2a30a
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 43 deletions.
30 changes: 13 additions & 17 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EventEmitter } from 'eventemitter3'
import { Socket } from 'net'
import { DeviceDrawProps, DeviceRegisterProps } from './device-types/api'
import { ClientCapabilities, DeviceDrawProps, DeviceRegisterProps } from './device-types/api'
import { DEFAULT_PORT } from './lib'
import * as semver from 'semver'

Expand Down Expand Up @@ -116,19 +116,11 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
return this._connected
}

/**
* Until 2.4 of Companion it does not support rotary encoders.
* For these, we can 'simulate' them by use the press/release actions of a button.
*/
public get useCombinedEncoders(): boolean {
return !this.forceSplitEncoders && this._supportsCombinedEncoders
}

/**
* Until 3.x of Companion it only supports providing 72x72px bitmaps for buttons.
*/
public get useCustomBitmapResolution(): boolean {
return this._supportsBitmapResolution
public get capabilities(): ClientCapabilities {
return {
useCombinedEncoders: !this.forceSplitEncoders && this._supportsCombinedEncoders,
useCustomBitmapResolution: this._supportsBitmapResolution,
}
}

constructor(options: CompanionSatelliteClientOptions = {}) {
Expand Down Expand Up @@ -189,9 +181,8 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
this.disconnect()
return
}
setImmediate(() => {
this.emit('connected')
})

// 'connected' gets emitted once we receive 'Begin'
})

if (this._host) {
Expand Down Expand Up @@ -330,6 +321,11 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
console.log('Companion supports bitmap resolution')
}
}

// report the connection as ready
setImmediate(() => {
this.emit('connected')
})
}

private handleState(params: Record<string, string | boolean>): void {
Expand Down
19 changes: 19 additions & 0 deletions src/device-types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export interface WrappedDevice {

initDevice(client: CompanionSatelliteClient, status: string): Promise<void>

updateCapabilities(capabilities: ClientCapabilities): void

deviceAdded(): Promise<void>

setBrightness(percent: number): Promise<void>
Expand All @@ -37,3 +39,20 @@ export interface WrappedDevice {

showStatus(hostname: string, status: string): void
}

export interface ClientCapabilities {
/**
* Until 2.4 of Companion it does not support rotary encoders.
* For these, we can 'simulate' them by use the press/release actions of a button.
*/
readonly useCombinedEncoders: boolean

/**
* Until 3.x of Companion it only supports providing 72x72px bitmaps for buttons.
*/
readonly useCustomBitmapResolution: boolean
}

// export interface CompanionClient {

// }
6 changes: 5 additions & 1 deletion src/device-types/infinitton.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CompanionSatelliteClient } from '../client'
import { CardGenerator } from '../cards'
import { DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'
import { ClientCapabilities, DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'
import Infinitton = require('infinitton-idisplay')
import * as imageRs from '@julusian/image-rs'

Expand Down Expand Up @@ -48,6 +48,10 @@ export class InfinittonWrapper implements WrappedDevice {
this.showStatus(client.host, status)
}

updateCapabilities(_capabilities: ClientCapabilities): void {
// Nothing to do
}

async deviceAdded(): Promise<void> {
this.#currentStatus = null
}
Expand Down
14 changes: 9 additions & 5 deletions src/device-types/loupedeck-live-s.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as imageRs from '@julusian/image-rs'
import { CompanionSatelliteClient } from '../client'
import { CardGenerator } from '../cards'
import { ImageWriteQueue } from '../writeQueue'
import { DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'
import { ClientCapabilities, DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'

export class LoupedeckLiveSWrapper implements WrappedDevice {
readonly #cardGenerator: CardGenerator
Expand All @@ -15,6 +15,7 @@ export class LoupedeckLiveSWrapper implements WrappedDevice {
#queue: ImageWriteQueue

#companionSupportsScaling = false
#companionSupportsCombinedEncoders = false

public get deviceId(): string {
return this.#deviceId
Expand Down Expand Up @@ -87,8 +88,6 @@ export class LoupedeckLiveSWrapper implements WrappedDevice {
await this.#deck.close()
}
async initDevice(client: CompanionSatelliteClient, status: string): Promise<void> {
this.#companionSupportsScaling = client.useCustomBitmapResolution

const convertButtonId = (type: 'button' | 'rotary', id: number): number => {
if (type === 'button') {
// return 24 + id
Expand Down Expand Up @@ -123,13 +122,13 @@ export class LoupedeckLiveSWrapper implements WrappedDevice {
const id2 = convertButtonId(info.type, info.index)
if (id2 < 90) {
if (delta < 0) {
if (client.useCombinedEncoders) {
if (this.#companionSupportsCombinedEncoders) {
client.rotateLeft(this.deviceId, id2)
} else {
client.keyUp(this.deviceId, id2)
}
} else if (delta > 0) {
if (client.useCombinedEncoders) {
if (this.#companionSupportsCombinedEncoders) {
client.rotateRight(this.deviceId, id2)
} else {
client.keyDown(this.deviceId, id2)
Expand Down Expand Up @@ -163,6 +162,11 @@ export class LoupedeckLiveSWrapper implements WrappedDevice {
this.showStatus(client.host, status)
}

updateCapabilities(capabilities: ClientCapabilities): void {
this.#companionSupportsScaling = capabilities.useCustomBitmapResolution
this.#companionSupportsCombinedEncoders = capabilities.useCombinedEncoders
}

async deviceAdded(): Promise<void> {
this.#queueOutputId++
}
Expand Down
16 changes: 10 additions & 6 deletions src/device-types/loupedeck-live.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as imageRs from '@julusian/image-rs'
import { CompanionSatelliteClient } from '../client'
import { CardGenerator } from '../cards'
import { ImageWriteQueue } from '../writeQueue'
import { DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'
import { ClientCapabilities, DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'

export class LoupedeckLiveWrapper implements WrappedDevice {
readonly #cardGenerator: CardGenerator
Expand All @@ -15,6 +15,7 @@ export class LoupedeckLiveWrapper implements WrappedDevice {
#queue: ImageWriteQueue

#companionSupportsScaling = false
#companionSupportsCombinedEncoders = true

public get deviceId(): string {
return this.#deviceId
Expand Down Expand Up @@ -91,13 +92,11 @@ export class LoupedeckLiveWrapper implements WrappedDevice {
await this.#deck.close()
}
async initDevice(client: CompanionSatelliteClient, status: string): Promise<void> {
this.#companionSupportsScaling = client.useCustomBitmapResolution

const convertButtonId = (type: 'button' | 'rotary', id: number, rotarySecondary: boolean): number => {
if (type === 'button' && id >= 0 && id < 8) {
return 24 + id
} else if (type === 'rotary') {
if (!client.useCombinedEncoders && rotarySecondary) {
if (!this.#companionSupportsCombinedEncoders && rotarySecondary) {
switch (id) {
case 0:
return 1
Expand Down Expand Up @@ -142,13 +141,13 @@ export class LoupedeckLiveWrapper implements WrappedDevice {
const id2 = convertButtonId(info.type, info.index, false)
if (id2 < 90) {
if (delta < 0) {
if (client.useCombinedEncoders) {
if (this.#companionSupportsCombinedEncoders) {
client.rotateLeft(this.deviceId, id2)
} else {
client.keyUp(this.deviceId, id2)
}
} else if (delta > 0) {
if (client.useCombinedEncoders) {
if (this.#companionSupportsCombinedEncoders) {
client.rotateRight(this.deviceId, id2)
} else {
client.keyDown(this.deviceId, id2)
Expand Down Expand Up @@ -182,6 +181,11 @@ export class LoupedeckLiveWrapper implements WrappedDevice {
this.showStatus(client.host, status)
}

updateCapabilities(capabilities: ClientCapabilities): void {
this.#companionSupportsScaling = capabilities.useCustomBitmapResolution
this.#companionSupportsCombinedEncoders = capabilities.useCombinedEncoders
}

async deviceAdded(): Promise<void> {
this.#queueOutputId++
}
Expand Down
8 changes: 5 additions & 3 deletions src/device-types/razer-stream-controller-x.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as imageRs from '@julusian/image-rs'
import { CompanionSatelliteClient } from '../client'
import { CardGenerator } from '../cards'
import { ImageWriteQueue } from '../writeQueue'
import { DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'
import { ClientCapabilities, DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'

export class RazerStreamControllerXWrapper implements WrappedDevice {
readonly #cardGenerator: CardGenerator
Expand Down Expand Up @@ -88,8 +88,6 @@ export class RazerStreamControllerXWrapper implements WrappedDevice {
await this.#deck.close()
}
async initDevice(client: CompanionSatelliteClient, status: string): Promise<void> {
this.#companionSupportsScaling = client.useCustomBitmapResolution

const convertButtonId = (type: 'button' | 'rotary', id: number): number => {
if (type === 'button') {
return id
Expand All @@ -108,6 +106,10 @@ export class RazerStreamControllerXWrapper implements WrappedDevice {
this.showStatus(client.host, status)
}

updateCapabilities(capabilities: ClientCapabilities): void {
this.#companionSupportsScaling = capabilities.useCustomBitmapResolution
}

async deviceAdded(): Promise<void> {
this.#queueOutputId++
}
Expand Down
8 changes: 5 additions & 3 deletions src/device-types/streamdeck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as imageRs from '@julusian/image-rs'
import { CompanionSatelliteClient } from '../client'
import { CardGenerator } from '../cards'
import { ImageWriteQueue } from '../writeQueue'
import { DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'
import { ClientCapabilities, DeviceDrawProps, DeviceRegisterProps, WrappedDevice } from './api'

export class StreamDeckWrapper implements WrappedDevice {
readonly #cardGenerator: CardGenerator
Expand Down Expand Up @@ -125,8 +125,6 @@ export class StreamDeckWrapper implements WrappedDevice {
this.#deck.on('down', (key) => client.keyDown(this.deviceId, key))
this.#deck.on('up', (key) => client.keyUp(this.deviceId, key))

this.#companionSupportsScaling = client.useCustomBitmapResolution

if (this.#deck.MODEL === DeviceModelId.PLUS) {
this.#deck.on('encoderDown', (encoder) => {
const index = this.#deck.NUM_KEYS + this.#deck.NUM_ENCODERS + encoder
Expand Down Expand Up @@ -171,6 +169,10 @@ export class StreamDeckWrapper implements WrappedDevice {
this.showStatus(client.host, status)
}

updateCapabilities(capabilities: ClientCapabilities): void {
this.#companionSupportsScaling = capabilities.useCustomBitmapResolution
}

async deviceAdded(): Promise<void> {
this.#queueOutputId++
}
Expand Down
16 changes: 10 additions & 6 deletions src/device-types/xencelabs-quick-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
WheelEvent,
} from '@xencelabs-quick-keys/node'
import { CompanionSatelliteClient } from '../client'
import { WrappedDevice, DeviceRegisterProps, DeviceDrawProps } from './api'
import { WrappedDevice, DeviceRegisterProps, DeviceDrawProps, ClientCapabilities } from './api'

function keyToCompanion(k: number): number | null {
if (k >= 0 && k < 4) return k + 1
Expand All @@ -16,10 +16,11 @@ function keyToCompanion(k: number): number | null {
return null
}
export class QuickKeysWrapper implements WrappedDevice {
#client: CompanionSatelliteClient | undefined
readonly #surface: XencelabsQuickKeys
readonly #deviceId: string

#companionSupportsCombinedEncoders = true

#statusTimer: NodeJS.Timeout | undefined
#unsub: (() => void) | undefined

Expand Down Expand Up @@ -52,7 +53,6 @@ export class QuickKeysWrapper implements WrappedDevice {
await this.#surface.stopData()
}
async initDevice(client: CompanionSatelliteClient, status: string): Promise<void> {
this.#client = client
console.log('Registering key events for ' + this.deviceId)

const handleDown = (key: number) => {
Expand All @@ -70,14 +70,14 @@ export class QuickKeysWrapper implements WrappedDevice {
const handleWheel = (ev: WheelEvent) => {
switch (ev) {
case WheelEvent.Left:
if (client.useCombinedEncoders) {
if (this.#companionSupportsCombinedEncoders) {
client.rotateLeft(this.deviceId, 5)
} else {
client.keyUp(this.deviceId, 11)
}
break
case WheelEvent.Right:
if (client.useCombinedEncoders) {
if (this.#companionSupportsCombinedEncoders) {
client.rotateRight(this.deviceId, 5)
} else {
client.keyDown(this.deviceId, 11)
Expand Down Expand Up @@ -107,6 +107,10 @@ export class QuickKeysWrapper implements WrappedDevice {
this.showStatus(client.host, status)
}

updateCapabilities(capabilities: ClientCapabilities): void {
this.#companionSupportsCombinedEncoders = capabilities.useCustomBitmapResolution
}

async deviceAdded(): Promise<void> {
await this.clearStatus()
}
Expand Down Expand Up @@ -144,7 +148,7 @@ export class QuickKeysWrapper implements WrappedDevice {
}
}

const wheelIndex = this.#client?.useCombinedEncoders ? 5 : 11
const wheelIndex = this.#companionSupportsCombinedEncoders ? 5 : 11
if (data.color && data.keyIndex === wheelIndex) {
const r = parseInt(data.color.substr(1, 2), 16)
const g = parseInt(data.color.substr(3, 2), 16)
Expand Down
12 changes: 10 additions & 2 deletions src/devices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class DeviceManager {

this.showStatusCard('Connected', false)

this.registerAll()
this.syncCapabilitiesAndRegisterAllDevices()
})
client.on('disconnected', () => {
console.log('disconnected')
Expand Down Expand Up @@ -178,6 +178,9 @@ export class DeviceManager {
setTimeout(() => {
const dev = this.devices.get(deviceId)
if (dev) {
// Make sure device knows what the client is capable of
dev.updateCapabilities(this.client.capabilities)

this.client.addDevice(deviceId, dev.productName, dev.getRegisterProps())
}
}, 1000)
Expand Down Expand Up @@ -227,7 +230,7 @@ export class DeviceManager {
}
}

public registerAll(): void {
public syncCapabilitiesAndRegisterAllDevices(): void {
console.log('registerAll', Array.from(this.devices.keys()))
for (const device of this.devices.values()) {
// If it is already in the process of initialising, core will give us back the same id twice, so we dont need to track it
Expand All @@ -236,6 +239,9 @@ export class DeviceManager {
// Indicate on device
device.showStatus(this.client.host, this.statusString)

// Make sure device knows what the client is capable of
device.updateCapabilities(this.client.capabilities)

// Re-init device
this.client.addDevice(device.deviceId, device.productName, device.getRegisterProps())

Expand Down Expand Up @@ -404,6 +410,8 @@ export class DeviceManager {
try {
await devInfo.initDevice(this.client, this.statusString)

devInfo.updateCapabilities(this.client.capabilities)

this.client.addDevice(deviceId, devInfo.productName, devInfo.getRegisterProps())
} catch (e) {
// Remove the failed device
Expand Down

0 comments on commit 4a2a30a

Please sign in to comment.