Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: button local variables #3314

Draft
wants to merge 22 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion companion/lib/Controls/ControlTypes/Button/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export abstract class ButtonControlBase<TJson, TOptions extends Record<string, a
{
controlId,
commitChange: this.commitChange.bind(this),
triggerRedraw: this.triggerRedraw.bind(this),
invalidateControl: this.triggerRedraw.bind(this),
localVariablesChanged: this.#onLocalVariablesChanged.bind(this),
instanceDefinitions: deps.instance.definitions,
internalModule: deps.internalModule,
moduleHost: deps.instance.moduleHost,
Expand Down Expand Up @@ -207,6 +208,12 @@ export abstract class ButtonControlBase<TJson, TOptions extends Record<string, a
return result
}

#onLocalVariablesChanged(allChangedVariables: Set<string>): void {
this.deps.variables.values.emit('local_variables_changed', allChangedVariables, this.controlId)
}

abstract onVariablesChanged(allChangedVariables: Set<string>): void

/**
* Update an option field of this control
*/
Expand Down
28 changes: 16 additions & 12 deletions companion/lib/Controls/ControlTypes/Button/Normal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import type { ButtonStyleProperties, DrawStyleButtonModel } from '@companion-app
import type { ControlDependencies } from '../../ControlDependencies.js'
import { EntityModelType } from '@companion-app/shared/Model/EntityModel.js'
import type { ControlActionSetAndStepsManager } from '../../Entities/ControlActionSetAndStepsManager.js'
import type { CompanionVariableValues } from '@companion-module/base'
import { GetButtonBitmapSize } from '../../../Resources/Util.js'
import { CompanionVariableValues } from '@companion-module/base'

/**
* Class for the stepped button control.
Expand Down Expand Up @@ -132,21 +132,23 @@ export class ControlButtonNormal

if (style.text) {
// Block out the button text
const injectedVariableValues: CompanionVariableValues = {}
const overrideVariableValues: CompanionVariableValues = {}

const location = this.deps.page.getLocationOfControlId(this.controlId)
if (location) {
// Ensure we don't enter into an infinite loop
// TODO - legacy location variables?
injectedVariableValues[`$(internal:b_text_${location.pageNumber}_${location.row}_${location.column})`] = '$RE'
overrideVariableValues[`$(internal:b_text_${location.pageNumber}_${location.row}_${location.column})`] = '$RE'
}

// Setup the parser
const parser = this.deps.variables.values.createVariablesAndExpressionParser(
location,
this.entities.getLocalVariableEntities(),
overrideVariableValues
)

if (style.textExpression) {
const parseResult = this.deps.variables.values.executeExpression(
style.text,
location,
undefined,
injectedVariableValues
)
const parseResult = parser.executeExpression(style.text, undefined)
if (parseResult.ok) {
style.text = parseResult.value + ''
} else {
Expand All @@ -155,9 +157,9 @@ export class ControlButtonNormal
}
this.#last_draw_variables = parseResult.variableIds.size > 0 ? parseResult.variableIds : null
} else {
const parseResult = this.deps.variables.values.parseVariables(style.text, location, injectedVariableValues)
const parseResult = parser.parseVariables(style.text)
style.text = parseResult.text
this.#last_draw_variables = parseResult.variableIds.length > 0 ? new Set(parseResult.variableIds) : null
this.#last_draw_variables = parseResult.variableIds.size > 0 ? parseResult.variableIds : null
}
}

Expand Down Expand Up @@ -218,6 +220,7 @@ export class ControlButtonNormal
* @param allChangedVariables - variables with changes
*/
onVariablesChanged(allChangedVariables: Set<string>): void {
// console.log('change', allChangedVariables)
if (this.#last_draw_variables) {
for (const variable of allChangedVariables.values()) {
if (this.#last_draw_variables.has(variable)) {
Expand Down Expand Up @@ -276,6 +279,7 @@ export class ControlButtonNormal
options: this.options,
feedbacks: this.entities.getFeedbackEntities(),
steps: this.entities.asNormalButtonSteps(),
localVariables: this.entities.getLocalVariableEntities().map((ent) => ent.asEntityModel(true)),
}

return clone ? cloneDeep(obj) : obj
Expand Down
11 changes: 10 additions & 1 deletion companion/lib/Controls/ControlTypes/Triggers/Events/Variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ export class TriggersEventVariables {
*/
readonly #eventBus: TriggerEvents

/**
* The control id of the parent trigger
*/
readonly #controlId: string

/**
* Execute the actions of the parent trigger
*/
Expand All @@ -62,6 +67,7 @@ export class TriggersEventVariables {
this.#logger = LogController.createLogger(`Controls/Triggers/Events/Timer/${controlId}`)

this.#eventBus = eventBus
this.#controlId = controlId
this.#executeActions = executeActions

this.#eventBus.on('variables_changed', this.#onVariablesChanged)
Expand All @@ -85,7 +91,10 @@ export class TriggersEventVariables {
* Handler for the variable_changed event
* @param allChangedVariables Set of all the variables that have changed
*/
#onVariablesChanged = (allChangedVariables: Set<string>): void => {
#onVariablesChanged = (allChangedVariables: Set<string>, fromControlId: string | null): void => {
// If the event is from a control, but not the same control, ignore it
if (fromControlId && fromControlId !== this.#controlId) return

if (this.#enabled) {
let execute = false

Expand Down
3 changes: 2 additions & 1 deletion companion/lib/Controls/ControlTypes/Triggers/Trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ export class ControlTrigger
this.entities = new ControlEntityListPoolTrigger({
controlId,
commitChange: this.commitChange.bind(this),
triggerRedraw: this.triggerRedraw.bind(this),
invalidateControl: this.triggerRedraw.bind(this),
localVariablesChanged: null,
instanceDefinitions: deps.instance.definitions,
internalModule: deps.internalModule,
moduleHost: deps.instance.moduleHost,
Expand Down
25 changes: 23 additions & 2 deletions companion/lib/Controls/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import type { ControlLocation } from '@companion-app/shared/Model/Common.js'
import { EventEmitter } from 'events'
import type { ControlCommonEvents, ControlDependencies } from './ControlDependencies.js'
import { TriggerExecutionSource } from './ControlTypes/Triggers/TriggerExecutionSource.js'
import { CompanionVariableValues } from '@companion-module/base'
import { VariablesAndExpressionParser } from '../Variables/VariablesAndExpressionParser.js'

export const TriggersListRoom = 'triggers:list'
const ActiveLearnRoom = 'learn:active'
Expand Down Expand Up @@ -955,12 +957,15 @@ export class ControlsController extends CoreBase {
/**
* Propagate variable changes to the controls
*/
onVariablesChanged(allChangedVariablesSet: Set<string>): void {
onVariablesChanged(allChangedVariablesSet: Set<string>, fromControlId: string | null): void {
// Inform triggers of the change
this.triggers.emit('variables_changed', allChangedVariablesSet)
this.triggers.emit('variables_changed', allChangedVariablesSet, fromControlId)

if (allChangedVariablesSet.size > 0) {
for (const control of this.#controls.values()) {
// If the changes are local variables and from another control, ignore them
if (fromControlId && fromControlId !== control.controlId) continue

if (control.supportsStyle) {
control.onVariablesChanged(allChangedVariablesSet)
}
Expand Down Expand Up @@ -1137,6 +1142,22 @@ export class ControlsController extends CoreBase {
control.entities.verifyConnectionIds(knownConnectionIds)
}
}

createVariablesAndExpressionParser(
controlLocation: ControlLocation | null | undefined,
overrideVariableValues: CompanionVariableValues | null
): VariablesAndExpressionParser {
const controlId = controlLocation && this.page.getControlIdAt(controlLocation)
const control = controlId && this.getControl(controlId)

const variableEntities = control && control.supportsEntities ? control.entities.getLocalVariableEntities() : []

return this.variablesController.values.createVariablesAndExpressionParser(
controlLocation,
variableEntities,
overrideVariableValues
)
}
}

export interface NewFeedbackValue {
Expand Down
11 changes: 8 additions & 3 deletions companion/lib/Controls/Entities/EntityInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ export class ControlEntityInstance {
* Set whether this entity is enabled
*/
setEnabled(enabled: boolean): void {
if (this.type === EntityModelType.LocalVariable) return

this.#data.disabled = !enabled

// Remove from cached feedback values
Expand All @@ -246,6 +248,8 @@ export class ControlEntityInstance {
* Set the connection of this entity
*/
setConnectionId(connectionId: string | number): void {
if (this.type === EntityModelType.LocalVariable) return

// TODO - why can this be a number?
connectionId = String(connectionId)

Expand Down Expand Up @@ -434,11 +438,12 @@ export class ControlEntityInstance {
/**
* Remove a child entity
*/
removeChild(id: string): boolean {
removeChild(id: string): ControlEntityInstance | undefined {
for (const childGroup of this.#children.values()) {
if (childGroup.removeEntity(id)) return true
const removed = childGroup.removeEntity(id)
if (removed) return removed
}
return false
return undefined
}

/**
Expand Down
15 changes: 10 additions & 5 deletions companion/lib/Controls/Entities/EntityList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export class ControlEntityList {
return this.#ownerId
}

get listDefinition(): ControlEntityListDefinition {
return this.#listDefinition
}

constructor(
instanceDefinitions: InstanceDefinitionsForEntity,
internalModule: InternalControllerForEntity,
Expand Down Expand Up @@ -75,7 +79,7 @@ export class ControlEntityList {
// TODO - validate that the entities are of the correct type

this.#entities =
entities?.map(
entities?.map?.(
(entity) =>
new ControlEntityInstance(
this.#instanceDefinitions,
Expand Down Expand Up @@ -173,22 +177,23 @@ export class ControlEntityList {
/**
* Remove a child entity
*/
removeEntity(id: string): boolean {
removeEntity(id: string): ControlEntityInstance | undefined {
const index = this.#entities.findIndex((entity) => entity.id === id)
if (index !== -1) {
const entity = this.#entities[index]
this.#entities.splice(index, 1)

entity.cleanup()

return true
return entity
}

for (const entity of this.#entities) {
if (entity.removeChild(id)) return true
const removed = entity.removeChild(id)
if (removed) return removed
}

return false
return undefined
}

/**
Expand Down
Loading