Skip to content

Commit 8acf4da

Browse files
committed
fix: avoid some conversions of received variables, to minimise cpu cost #3257
1 parent 76003c6 commit 8acf4da

File tree

6 files changed

+40
-39
lines changed

6 files changed

+40
-39
lines changed

companion/lib/Graphics/Controller.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import LogController from '../Log/Controller.js'
3434
import type { DataUserConfig } from '../Data/UserConfig.js'
3535
import type { PageController } from '../Page/Controller.js'
3636
import type { ControlsController } from '../Controls/Controller.js'
37-
import type { VariablesValues } from '../Variables/Values.js'
37+
import type { VariablesValues, VariableValueEntry } from '../Variables/Values.js'
3838

3939
const CRASHED_WORKER_RETRY_COUNT = 10
4040

@@ -117,7 +117,14 @@ export class GraphicsController extends EventEmitter<GraphicsControllerEvents> {
117117
const values = this.#pendingVariables
118118
if (values) {
119119
this.#pendingVariables = null
120-
this.#variableValuesController.setVariableValues('internal', values)
120+
121+
// This isn't ideal, but ensures we don't report duplicate changes
122+
const valuesArr: VariableValueEntry[] = Object.entries(values).map(([id, value]) => ({
123+
id,
124+
value,
125+
}))
126+
127+
this.#variableValuesController.setVariableValues('internal', valuesArr)
121128
}
122129
},
123130
{

companion/lib/Instance/Wrapper.ts

+2-13
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import {
3535
type CompanionHTTPRequest,
3636
type CompanionInputFieldBase,
3737
type CompanionOptionValues,
38-
type CompanionVariableValue,
3938
type LogLevel,
4039
} from '@companion-module/base'
4140
import type { ControlLocation } from '@companion-app/shared/Model/Common.js'
@@ -702,12 +701,7 @@ export class SocketEventsHandler {
702701
async #handleSetVariableValues(msg: SetVariableValuesMessage): Promise<void> {
703702
if (!this.#label) throw new Error(`Got call to handleSetVariableValues before init was called`)
704703

705-
const variables: Record<string, CompanionVariableValue | undefined> = {}
706-
for (const variable of msg.newValues) {
707-
variables[variable.id] = variable.value
708-
}
709-
710-
this.#deps.variables.values.setVariableValues(this.#label, variables)
704+
this.#deps.variables.values.setVariableValues(this.#label, msg.newValues)
711705
}
712706

713707
/**
@@ -738,12 +732,7 @@ export class SocketEventsHandler {
738732
this.#deps.variables.definitions.setVariableDefinitions(this.#label, newVariables)
739733

740734
if (msg.newValues) {
741-
const variables: Record<string, CompanionVariableValue | undefined> = {}
742-
for (const variable of msg.newValues) {
743-
variables[variable.id] = variable.value
744-
}
745-
746-
this.#deps.variables.values.setVariableValues(this.#label, variables)
735+
this.#deps.variables.values.setVariableValues(this.#label, msg.newValues)
747736
}
748737

749738
if (invalidIds.length > 0) {

companion/lib/Internal/Controller.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { assertNever } from '@companion-app/shared/Util.js'
4646
import { ClientEntityDefinition } from '@companion-app/shared/Model/EntityDefinitionModel.js'
4747
import { Complete } from '@companion-module/base/dist/util.js'
4848
import { InternalSystem } from './System.js'
49+
import type { VariableValueEntry } from '../Variables/Values.js'
4950

5051
export class InternalController {
5152
readonly #logger = LogController.createLogger('Internal/Controller')
@@ -388,7 +389,13 @@ export class InternalController {
388389
setVariables(variables: Record<string, CompanionVariableValue | undefined>): void {
389390
if (!this.#initialized) throw new Error(`InternalController is not initialized`)
390391

391-
this.#variablesController.values.setVariableValues('internal', variables)
392+
// This isn't ideal, but it's cheap enough and avoids updating the calling code
393+
const valuesArr: VariableValueEntry[] = Object.entries(variables).map(([id, value]) => ({
394+
id,
395+
value,
396+
}))
397+
398+
this.#variablesController.values.setVariableValues('internal', valuesArr)
392399
}
393400
/**
394401
* Recheck all feedbacks of specified types

companion/lib/Surface/Handler.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -575,9 +575,7 @@ export class SurfaceHandler extends EventEmitter<SurfaceHandlerEvents> {
575575
* Set the value of a variable
576576
*/
577577
#onSetVariable(name: string, value: CompanionVariableValue): void {
578-
this.#variables.values.setVariableValues('internal', {
579-
[name]: value,
580-
})
578+
this.#variables.values.setVariableValues('internal', [{ id: name, value: value }])
581579
}
582580

583581
/**

companion/lib/Variables/CustomVariable.ts

+7-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
import LogController from '../Log/Controller.js'
1919
import { isCustomVariableValid } from '@companion-app/shared/CustomVariable.js'
20-
import type { VariablesValues } from './Values.js'
20+
import type { VariablesValues, VariableValueEntry } from './Values.js'
2121
import type {
2222
CustomVariablesModel,
2323
CustomVariableUpdate,
@@ -174,9 +174,9 @@ export class VariablesCustomVariable {
174174
init(): void {
175175
// Load the startup values of custom variables
176176
if (Object.keys(this.#custom_variables).length > 0) {
177-
const newValues: Record<string, CompanionVariableValue> = {}
177+
const newValues: VariableValueEntry[] = []
178178
for (const [name, info] of Object.entries(this.#custom_variables)) {
179-
newValues[name] = info.defaultValue || ''
179+
newValues.push({ id: name, value: info.defaultValue || '' })
180180
}
181181
this.#variableValues.setVariableValues(CUSTOM_LABEL, newValues)
182182
}
@@ -186,14 +186,14 @@ export class VariablesCustomVariable {
186186
* Replace all of the current custom variables with new ones
187187
*/
188188
replaceDefinitions(custom_variables: CustomVariablesModel): void {
189-
const newValues: Record<string, CompanionVariableValue | undefined> = {}
189+
const newValues: VariableValueEntry[] = []
190190
// Mark the current variables as to be deleted
191191
for (const name of Object.keys(this.#custom_variables || {})) {
192-
newValues[name] = undefined
192+
newValues.push({ id: name, value: undefined })
193193
}
194194
// Determine the initial values of the variables
195195
for (const [name, info] of Object.entries(custom_variables || {})) {
196-
newValues[name] = info.defaultValue || ''
196+
newValues.push({ id: name, value: info.defaultValue || '' })
197197
}
198198

199199
const namesBefore = Object.keys(this.#custom_variables)
@@ -358,9 +358,7 @@ export class VariablesCustomVariable {
358358
* Helper for setting the value of a custom variable
359359
*/
360360
#setValueInner(name: string, value: CompanionVariableValue | undefined): void {
361-
this.#variableValues.setVariableValues(CUSTOM_LABEL, {
362-
[name]: value,
363-
})
361+
this.#variableValues.setVariableValues(CUSTOM_LABEL, [{ id: name, value: value }])
364362

365363
this.#persistCustomVariableValue(name, value)
366364
}

companion/lib/Variables/Values.ts

+13-11
Original file line numberDiff line numberDiff line change
@@ -140,25 +140,22 @@ export class VariablesValues extends EventEmitter<VariablesValuesEvents> {
140140
})
141141
}
142142

143-
setVariableValues(label: string, variables: Record<string, CompanionVariableValue | undefined>): void {
143+
setVariableValues(label: string, variables: VariableValueEntry[]): void {
144144
const moduleValues = this.#variableValues[label] ?? {}
145145
this.#variableValues[label] = moduleValues
146146

147147
const all_changed_variables_set = new Set<string>()
148-
for (const variable in variables) {
149-
// Note: explicitly using for-in here, as Object.entries is slow
150-
const value = variables[variable]
148+
for (const variable of variables) {
149+
if (moduleValues[variable.id] !== variable.value) {
150+
moduleValues[variable.id] = variable.value
151151

152-
if (moduleValues[variable] !== value) {
153-
moduleValues[variable] = value
154-
155-
all_changed_variables_set.add(`${label}:${variable}`)
152+
all_changed_variables_set.add(`${label}:${variable.id}`)
156153
// Also report the old custom variable names as having changed
157-
if (label === 'custom') all_changed_variables_set.add(`internal:custom_${variable}`)
154+
if (label === 'custom') all_changed_variables_set.add(`internal:custom_${variable.id}`)
158155

159156
// Skip debug if it's just internal:time_* spamming.
160-
if (this.#logger.isSillyEnabled() && !(label === 'internal' && variable.startsWith('time_'))) {
161-
this.#logger.silly('Variable $(' + label + ':' + variable + ') is "' + value + '"')
157+
if (this.#logger.isSillyEnabled() && !(label === 'internal' && variable.id.startsWith('time_'))) {
158+
this.#logger.silly('Variable $(' + label + ':' + variable.id + ') is "' + variable.value + '"')
162159
}
163160
}
164161
}
@@ -192,3 +189,8 @@ export class VariablesValues extends EventEmitter<VariablesValuesEvents> {
192189
}
193190
}
194191
}
192+
193+
export interface VariableValueEntry {
194+
id: string
195+
value: CompanionVariableValue | undefined
196+
}

0 commit comments

Comments
 (0)