Skip to content

Commit

Permalink
Merge branch 'main' into feat/rework-control-entities
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Jan 13, 2025
2 parents 0bc47e5 + b7394ac commit d2c7f04
Show file tree
Hide file tree
Showing 71 changed files with 674 additions and 235 deletions.
34 changes: 23 additions & 11 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
yarn --immutable
yarn zx tools/build/complete.mjs linux-x64
yarn tsx tools/build/complete.mts linux-x64
# manually tar it, to preserve the symlinks
cd electron-output
Expand Down Expand Up @@ -151,7 +151,7 @@ jobs:
yarn --immutable
yarn zx tools/build/complete.mjs linux-arm64
yarn tsx tools/build/complete.mts linux-arm64
# manually tar it, to preserve the symlinks
cd electron-output
Expand Down Expand Up @@ -227,7 +227,7 @@ jobs:
yarn --immutable
yarn zx tools/build/complete.mjs darwin-x64
yarn tsx tools/build/complete.mts darwin-x64
env:
CI: 1
CSC_LINK: ${{ secrets.OSX_CSC_LINK }}
Expand Down Expand Up @@ -305,7 +305,7 @@ jobs:
CI: 1
- name: build & package
run: |
yarn zx tools/build/complete.mjs darwin-arm64
yarn tsx tools/build/complete.mts darwin-arm64
env:
CI: 1
CSC_LINK: ${{ secrets.OSX_CSC_LINK }}
Expand Down Expand Up @@ -352,9 +352,9 @@ jobs:
api-secret: ${{ secrets.BITFOCUS_API_PROJECT_SECRET }}

win32-x64:
runs-on: windows-2019
runs-on: ${{ startsWith(github.ref, 'refs/tags/') && fromJSON('["self-hosted", "Windows", "codecert", "X64"]') || 'windows-2019'}}
needs: check-types
timeout-minutes: 30
timeout-minutes: 45

steps:
- uses: actions/checkout@v4
Expand All @@ -381,15 +381,27 @@ jobs:
yarn config set httpTimeout 100000
yarn --immutable
env:
CI: 1

yarn zx tools/build/complete.mjs win32-x64
- name: build & package (unsigned)
if: ${{ runner.environment != 'self-hosted' }}
run: |
yarn tsx tools/build/complete.mts win32-x64
env:
CI: 1
# HACK: temporarily disable signing
# CSC_LINK: ${{ secrets.CSC_LINK }}
# CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}

- name: build & package (signed)
if: ${{ runner.environment == 'self-hosted' }}
run: |
yarn tsx tools/build/complete.mts win32-x64
env:
CI: 1
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
CSC_LINK: c:\\actions-runner-bitfocusas\\codesign.cer
BF_CODECERT_KEY: ${{ secrets.BF_CODECERT_KEY }}

- name: Determine files to upload
id: filenames
shell: bash
Expand Down Expand Up @@ -426,7 +438,7 @@ jobs:

docker-image:
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 20

needs:
- linux-x64
Expand Down
2 changes: 1 addition & 1 deletion bundled-modules
Submodule bundled-modules updated 153 files
2 changes: 2 additions & 0 deletions companion/lib/Controls/ActionRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export class ActionRunner extends CoreBase {
})
}

if (extras.abortDelayed.aborted) break

if (actions.length > 0) {
// Run all the actions in parallel
await Promise.all(
Expand Down
13 changes: 9 additions & 4 deletions companion/lib/Controls/ControlTypes/Triggers/Events/Misc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ParseControlId } from '@companion-app/shared/ControlId.js'
import LogController, { Logger } from '../../../../Log/Controller.js'
import type { TriggerEvents } from '../../../../Controls/TriggerEvents.js'
import { TriggerExecutionSource } from '../TriggerExecutionSource.js'

interface ConnectEvent {
id: string
Expand Down Expand Up @@ -70,7 +71,7 @@ export class TriggersEventMisc {
/**
* Execute the actions of the parent trigger
*/
readonly #executeActions: (nowTime: number) => void
readonly #executeActions: (nowTime: number, source: TriggerExecutionSource) => void

/**
* The logger for this class
Expand All @@ -82,7 +83,11 @@ export class TriggersEventMisc {
*/
#startupEvents: StartupEvent[] = []

constructor(eventBus: TriggerEvents, controlId: string, executeActions: (nowTime: number) => void) {
constructor(
eventBus: TriggerEvents,
controlId: string,
executeActions: (nowTime: number, source: TriggerExecutionSource) => void
) {
this.#logger = LogController.createLogger(`Controls/Triggers/Events/Misc/${controlId}`)

this.#eventBus = eventBus
Expand Down Expand Up @@ -132,7 +137,7 @@ export class TriggersEventMisc {

setImmediate(() => {
try {
this.#executeActions(nowTime)
this.#executeActions(nowTime, TriggerExecutionSource.Other)
} catch (e: any) {
this.#logger.warn(`Execute actions failed: ${e?.toString?.() ?? e?.message ?? e}`)
}
Expand Down Expand Up @@ -168,7 +173,7 @@ export class TriggersEventMisc {
for (const event of events) {
setTimeout(() => {
try {
this.#executeActions(nowTime)
this.#executeActions(nowTime, TriggerExecutionSource.Other)
} catch (e: any) {
this.#logger.warn(`Execute actions failed: ${e?.toString?.() ?? e?.message ?? e}`)
}
Expand Down
11 changes: 8 additions & 3 deletions companion/lib/Controls/ControlTypes/Triggers/Events/Timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import dayjs from 'dayjs'
import LogController, { Logger } from '../../../../Log/Controller.js'
import type { TriggerEvents } from '../../../../Controls/TriggerEvents.js'
import type { EventInstance } from '@companion-app/shared/Model/EventModel.js'
import { TriggerExecutionSource } from '../TriggerExecutionSource.js'

interface IntervalEvent {
id: string
Expand Down Expand Up @@ -69,7 +70,7 @@ export class TriggersEventTimer {
/**
* Execute the actions of the parent trigger
*/
readonly #executeActions: (nowTime: number) => void
readonly #executeActions: (nowTime: number, source: TriggerExecutionSource) => void

/**
* Enabled time interval events
Expand Down Expand Up @@ -101,7 +102,11 @@ export class TriggersEventTimer {
*/
#sunEvents: SunEvent[] = []

constructor(eventBus: TriggerEvents, controlId: string, executeActions: (nowTime: number) => void) {
constructor(
eventBus: TriggerEvents,
controlId: string,
executeActions: (nowTime: number, source: TriggerExecutionSource) => void
) {
this.#logger = LogController.createLogger(`Controls/Triggers/Events/Timer/${controlId}`)

this.#eventBus = eventBus
Expand Down Expand Up @@ -407,7 +412,7 @@ export class TriggersEventTimer {
if (this.#enabled && execute) {
setImmediate(() => {
try {
this.#executeActions(nowTime)
this.#executeActions(nowTime, TriggerExecutionSource.Other)
} catch (e: any) {
this.#logger.warn(`Execute actions failed: ${e?.toString?.() ?? e?.message ?? e}`)
}
Expand Down
11 changes: 8 additions & 3 deletions companion/lib/Controls/ControlTypes/Triggers/Events/Variable.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import LogController, { Logger } from '../../../../Log/Controller.js'
import type { TriggerEvents } from '../../../../Controls/TriggerEvents.js'
import type { EventInstance } from '@companion-app/shared/Model/EventModel.js'
import { TriggerExecutionSource } from '../TriggerExecutionSource.js'

interface VariableChangeEvent {
id: string
Expand Down Expand Up @@ -41,7 +42,7 @@ export class TriggersEventVariables {
/**
* Execute the actions of the parent trigger
*/
readonly #executeActions: (nowTime: number) => void
readonly #executeActions: (nowTime: number, source: TriggerExecutionSource) => void

/**
* The logger for this class
Expand All @@ -53,7 +54,11 @@ export class TriggersEventVariables {
*/
#variableChangeEvents: VariableChangeEvent[] = []

constructor(eventBus: TriggerEvents, controlId: string, executeActions: (nowTime: number) => void) {
constructor(
eventBus: TriggerEvents,
controlId: string,
executeActions: (nowTime: number, source: TriggerExecutionSource) => void
) {
this.#logger = LogController.createLogger(`Controls/Triggers/Events/Timer/${controlId}`)

this.#eventBus = eventBus
Expand Down Expand Up @@ -95,7 +100,7 @@ export class TriggersEventVariables {

setImmediate(() => {
try {
this.#executeActions(nowTime)
this.#executeActions(nowTime, TriggerExecutionSource.Other)
} catch (e: any) {
this.#logger.warn(`Execute actions failed: ${e?.toString?.() ?? e?.message ?? e}`)
}
Expand Down
11 changes: 6 additions & 5 deletions companion/lib/Controls/ControlTypes/Triggers/Trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type { ControlDependencies } from '../../ControlDependencies.js'
import { ControlActionRunner } from '../../ActionRunner.js'
import { ControlEntityListPoolTrigger } from '../../Entities/EntityListPoolTrigger.js'
import { EntityModelType } from '@companion-app/shared/Model/EntityModel.js'
import { TriggerExecutionSource } from './TriggerExecutionSource.js'

/**
* Class for an interval trigger.
Expand Down Expand Up @@ -201,16 +202,16 @@ export class ControlTrigger
/**
* Execute the actions of this trigger
* @param nowTime
* @param isTest Whether this is a 'test' execution from the ui and should skip condition checks
* @param source The source of this execution
*/
executeActions(nowTime: number, isTest = false): void {
if (isTest) {
executeActions(nowTime: number, source: TriggerExecutionSource): void {
if (source === TriggerExecutionSource.Test) {
this.logger.debug(`Test Execute ${this.options.name}`)
} else {
if (!this.options.enabled) return

// Ensure the condition passes when it is not part of the event
if (!this.events.some((event) => event.type.startsWith('condition_'))) {
if (source !== TriggerExecutionSource.ConditionChange) {
const conditionPasses = this.entities.checkConditionValue()
if (!conditionPasses) return
}
Expand Down Expand Up @@ -595,7 +596,7 @@ export class ControlTrigger
(runOnFalse && !newStatus && this.#conditionCheckLastValue))
) {
setImmediate(() => {
this.executeActions(Date.now(), false)
this.executeActions(Date.now(), TriggerExecutionSource.ConditionChange)
})
}
this.#conditionCheckLastValue = newStatus
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum TriggerExecutionSource {
Test = 'test',
ConditionChange = 'condition-change',
Other = 'other',
}
3 changes: 2 additions & 1 deletion companion/lib/Controls/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { EventEmitter } from 'events'
import type { ControlCommonEvents, ControlDependencies } from './ControlDependencies.js'
import { EntityModelType, SomeEntityModel } from '@companion-app/shared/Model/EntityModel.js'
import { assertNever } from '@companion-app/shared/Util.js'
import { TriggerExecutionSource } from './ControlTypes/Triggers/TriggerExecutionSource.js'

export const TriggersListRoom = 'triggers:list'
const ActiveLearnRoom = 'learn:active'
Expand Down Expand Up @@ -681,7 +682,7 @@ export class ControlsController extends CoreBase {

const control = this.getControl(controlId)
if (control && control instanceof ControlTrigger) {
control.executeActions(Date.now(), true)
control.executeActions(Date.now(), TriggerExecutionSource.Test)
}

return false
Expand Down
2 changes: 1 addition & 1 deletion companion/lib/Controls/Entities/EntityInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class ControlEntityInstance {
}

/**
* Inform the instance of a removed entity
* Inform the instance of a removed/disabled entity
*/
cleanup() {
// Inform relevant module
Expand Down
3 changes: 1 addition & 2 deletions companion/lib/Controls/Entities/EntityList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,13 @@ export class ControlEntityList {
}

/**
* Inform the instance of any removed entities
* Inform the instance of any removed/disabled entities
* @access public
*/
cleanup() {
for (const entity of this.#entities) {
entity.cleanup()
}
this.#entities = []
}

/**
Expand Down
6 changes: 5 additions & 1 deletion companion/lib/Internal/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,11 @@ export class InternalController {
for (const fragment of this.#fragments) {
if ('executeAction' in fragment && typeof fragment.executeAction === 'function') {
try {
if (await fragment.executeAction(action, extras)) {
let value = fragment.executeAction(action, extras)
// Only await if it is a promise, to avoid unnecessary async pauses
value = value instanceof Promise ? await value : value

if (value) {
// It was handled, so break
return
}
Expand Down
2 changes: 1 addition & 1 deletion companion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"private": true,
"scripts": {
"dev": "run dev:inner --admin-address 127.0.0.1 --log-level debug",
"dev:inner": "run -TB zx ../tools/dev.mjs --extra-module-path=../module-local-dev",
"dev:inner": "run -TB tsx ../tools/dev.mts --extra-module-path=../module-local-dev",
"dev:debug": "run dev:inner --admin-address 127.0.0.1 --log-level silly",
"build:watch": "tsc --watch",
"build": "tsc && webpack",
Expand Down
Binary file modified docs/1_gettingstarted/images/admingui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/2_sidebar/images/emulator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/2_sidebar/images/webbuttons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/2_sidebar/images/webbuttons_settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/2_sidebar/web_buttons.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
**Web buttons** is a way of viewing all your buttons across all pages on a single screen, which may be useful if you want to use a web browser on a tablet to control Companion. It is an alternative approach to the **Emulator**, allowing for better viewing on larger screens.
**Web buttons** is a way of viewing all your buttons across all pages on a single screen, which may be useful if you want to use a web browser on a tablet to control Companion.

![Web Buttons](images/webbuttons.png?raw=true 'Web Buttons')

Expand Down
19 changes: 11 additions & 8 deletions docs/3_config/buttons.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
In the Buttons tab, you can configure the buttons for your Stream Deck.
In the Buttons tab, you can configure the buttons for your Stream Deck. The number of buttons in the grid can be changed in the settings, it can be grown in all 4 directions.

![Buttons Page](images/buttons.png?raw=true 'Buttons Page')

The Buttons layout has numerous pages that can be navigated using the grey left/right arrows, or the dropdown box. You can give your pages a unique name by replacing the word _PAGE_ right next to the page number.
The Buttons layout has numerous pages that can be navigated using the grey left/right arrows, or the dropdown box. Each of these pages is also listed in the **Pages** tab in the right panel, which is where you can manage the pages you have. In this panel you can give your pages names

If you hold down the SHIFT key on your keyboard, you can trigger a button directly by clicking on it.

Also above the buttons, you can:

Several actions exist for rearranging your buttons, **Copy**, **Move**,
**Swap**, or **Delete**. First click on the desired action, then click on the
- **View Scale** Adjust the view scale of the grid
- **Home position** When scrolling around a large grid, this will snap the view back to viewing 0/0 in the top left corner
- **Edit page** adjust various settings for the current page
- **Export page** exports just this page's buttons to a download which can later be imported to another page or a different Companion config. See the [Import / Export](#header-import--export) section below.

Several actions exist below for rearranging your buttons, **Copy**, **Move**,
**Swap**, or **Delete**. First click on the desired action, then click on the
button you want to apply that action to. Finally (in the case of the `Copy`,
`Swap` and `Move` actions) click on the destination button. Alternatively, use
`Swap` and `Move` actions) click on the destination button. Alternatively, use
the standard keyboard shortcuts to perform these operations.


There are also two buttons for resetting the page:

- **Wipe page**: Erases all buttons on the page and adds the navigation buttons.
- **Reset page buttons**: Leaves the buttons intact, but adds the default navigation buttons.

**Export page** exports just this page's buttons to a download which can later be imported to another page or a different Companion config. See the [Import / Export](#header-import--export) section below.
Loading

0 comments on commit d2c7f04

Please sign in to comment.