-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(A380X): Added systems-host and extras-host to A380X (#8418)
* Initial add of extras-host to A380X * Move setting of A32NX_IS_READY to extras-host * Added systems-host from A32NX to A380X * Removed commented part in build script
- Loading branch information
Showing
22 changed files
with
792 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
...re-aircraft-a380-842/html_ui/Pages/VCockpit/Instruments/A380X/ExtrasHost/extras-host.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<!-- Copyright (c) 2022 FlyByWire Simulations --> | ||
<!-- SPDX-License-Identifier: GPL-3.0 --> | ||
|
||
<script type="text/html" id="A380X_EXTRASHOST"></script> | ||
|
||
<script type="text/html" import-script="/JS/dataStorage.js" import-async="false"></script> | ||
<script type="text/html" import-script="/Pages/VCockpit/Instruments/A380X/ExtrasHost/index.js" import-async="false"></script> |
4 changes: 4 additions & 0 deletions
4
...-aircraft-a380-842/html_ui/Pages/VCockpit/Instruments/A380X/SystemsHost/systems-host.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<script type="text/html" id="A380X_SYSTEMSHOST"></script> | ||
|
||
<script type="text/html" import-script="/JS/dataStorage.js" import-async="false"></script> | ||
<script type="text/html" import-script="/Pages/VCockpit/Instruments/A380X/SystemsHost/index.js" import-async="false"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# FBW Extras Host | ||
|
||
The ExtrasHost instrument is used to provide non-aircraft and non-wasm related functionality an | ||
environment to run as single instrument without rendering or connection to the MCDU, or the EFB, | ||
where some of these functionalities have been hosted in the past. | ||
|
||
The ExtrasHost inherits from the BaseInstruments class that is managed by the simulator. | ||
|
||
It uses the msfssdk library for using the EventBus and HEventPublisher and pot. other classes. | ||
|
||
## System interfaces | ||
|
||
Every module class has to implement the following functions: | ||
|
||
- `constructor` to get access to the system-wide EventBus | ||
- `connectedCallback` which is called after the simulator set up everything. These functions will also add the subscribtion to special events. | ||
- `startPublish` which is called as soon as the simulator starts running. It will also start publishing the simulator variables onto the EventBus | ||
- `update` is called in every update call of the simulator, but only after `startPublish` is called | ||
|
||
## Examples | ||
|
||
See the modules folder for examples on how to implement a module. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) 2021-2023 FlyByWire Simulations | ||
// | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
'use strict'; | ||
|
||
const esbuild = require('esbuild'); | ||
const path = require('path'); | ||
const { createModuleBuild } = require('#build-utils'); | ||
|
||
const outFile = 'fbw-a380x/out/flybywire-aircraft-a380-842/html_ui/Pages/VCockpit/Instruments/A380X/ExtrasHost/index.js'; | ||
|
||
esbuild.build(createModuleBuild('fbw-a380x', undefined, path.join(__dirname, './index.ts'), outFile, __dirname)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright (c) 2022 FlyByWire Simulations | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
import { EventBus, HEventPublisher } from '@microsoft/msfs-sdk'; | ||
import { NotificationManager } from '@flybywiresim/fbw-sdk'; | ||
import { ExtrasSimVarPublisher } from 'extras-host/modules/common/ExtrasSimVarPublisher'; | ||
import { PushbuttonCheck } from 'extras-host/modules/pushbutton_check/PushbuttonCheck'; | ||
import { KeyInterceptor } from './modules/key_interceptor/KeyInterceptor'; | ||
import { VersionCheck } from './modules/version_check/VersionCheck'; | ||
|
||
/** | ||
* This is the main class for the extras-host instrument. | ||
* | ||
* It provides an environment for non-aircraft non-wasm systems/modules to run in. | ||
* | ||
* Usage: | ||
* - Add new modules as private readonly members of this class. | ||
* - Add the modules to the constructor. | ||
* - Add the modules to the connectedCallback() method. | ||
* - Add the modules to the Update() method. | ||
* | ||
* Each module must implement the following methods: | ||
* - `constructor` to get access to the system-wide EventBus | ||
* - `connectedCallback` which is called after the simulator set up everything. These functions will also add the subscribtion to special events. | ||
* - `startPublish` which is called as soon as the simulator starts running. It will also start publishing the simulator variables onto the EventBus | ||
* - `update` is called in every update call of the simulator, but only after `startPublish` is called | ||
*/ | ||
class ExtrasHost extends BaseInstrument { | ||
private readonly bus: EventBus; | ||
|
||
private readonly notificationManager: NotificationManager; | ||
|
||
private readonly hEventPublisher: HEventPublisher; | ||
|
||
private readonly simVarPublisher: ExtrasSimVarPublisher; | ||
|
||
private readonly pushbuttonCheck: PushbuttonCheck; | ||
|
||
private readonly versionCheck: VersionCheck; | ||
|
||
private readonly keyInterceptor: KeyInterceptor; | ||
|
||
/** | ||
* "mainmenu" = 0 | ||
* "loading" = 1 | ||
* "briefing" = 2 | ||
* "ingame" = 3 | ||
*/ | ||
private gameState = 0; | ||
|
||
constructor() { | ||
super(); | ||
|
||
this.bus = new EventBus(); | ||
this.hEventPublisher = new HEventPublisher(this.bus); | ||
this.simVarPublisher = new ExtrasSimVarPublisher(this.bus); | ||
|
||
this.notificationManager = new NotificationManager(); | ||
|
||
this.pushbuttonCheck = new PushbuttonCheck(this.bus, this.notificationManager); | ||
this.versionCheck = new VersionCheck(this.bus); | ||
this.keyInterceptor = new KeyInterceptor(this.bus, this.notificationManager); | ||
|
||
console.log('A380X_EXTRASHOST: Created'); | ||
} | ||
|
||
get templateID(): string { | ||
return 'A380X_EXTRASHOST'; | ||
} | ||
|
||
public getDeltaTime() { | ||
return this.deltaTime; | ||
} | ||
|
||
public onInteractionEvent(args: string[]): void { | ||
this.hEventPublisher.dispatchHEvent(args[0]); | ||
} | ||
|
||
public connectedCallback(): void { | ||
super.connectedCallback(); | ||
|
||
this.pushbuttonCheck.connectedCallback(); | ||
} | ||
|
||
public Update(): void { | ||
super.Update(); | ||
|
||
if (this.gameState !== GameState.ingame) { | ||
const gs = this.getGameState(); | ||
if (gs === GameState.ingame) { | ||
// Start the modules | ||
this.hEventPublisher.startPublish(); | ||
this.versionCheck.startPublish(); | ||
this.keyInterceptor.startPublish(); | ||
this.simVarPublisher.startPublish(); | ||
|
||
// Signal that the aircraft is ready via L:A32NX_IS_READY | ||
SimVar.SetSimVarValue('L:A32NX_IS_READY', 'number', 1); | ||
console.log('A380X_EXTRASHOST: Aircraft is ready'); | ||
} | ||
this.gameState = gs; | ||
} else { | ||
this.simVarPublisher.onUpdate(); | ||
} | ||
|
||
// Call module update() methods here if they have one | ||
} | ||
} | ||
|
||
registerInstrument('extras-host', ExtrasHost); |
25 changes: 25 additions & 0 deletions
25
fbw-a380x/src/systems/extras-host/modules/common/AircraftPresetsList.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Copyright (c) 2023-2024 FlyByWire Simulations | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
/** | ||
* The AircraftPresetsList class is used to get the name of a preset from the preset ID. | ||
* These need to align with the IDs in the Presets C++ WASM and the AircraftPresets.tsx in the EFB. | ||
* WASM: src/presets/src/Aircraft/AircraftProcedures.h | ||
*/ | ||
export class AircraftPresetsList { | ||
private static list: { index: number, name: string }[] = [ | ||
{ index: 1, name: 'Cold & Dark' }, | ||
{ index: 2, name: 'Powered' }, | ||
{ index: 3, name: 'Ready for Pushback' }, | ||
{ index: 4, name: 'Ready for Taxi' }, | ||
{ index: 5, name: 'Ready for Takeoff' }, | ||
]; | ||
|
||
public static getPresetName(presetID: number): string { | ||
const index = presetID - 1; | ||
if (index < 0 || index > AircraftPresetsList.list.length) { | ||
return ''; | ||
} | ||
return AircraftPresetsList.list[index].name; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
fbw-a380x/src/systems/extras-host/modules/common/ExtrasSimVarPublisher.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright (c) 2023 FlyByWire Simulations | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
import { EventBus, PublishPacer, SimVarDefinition, SimVarPublisher, SimVarValueType } from '@microsoft/msfs-sdk'; | ||
|
||
/* eslint-disable camelcase */ | ||
|
||
export interface ExtrasSimVarEvents { | ||
/** ECP TO CONF pushbutton state */ | ||
ecp_to_config_pushbutton: boolean, | ||
/** FWC flight phase from 1 - 10 */ | ||
fwc_flight_phase: number, | ||
} | ||
|
||
export class ExtrasSimVarPublisher extends SimVarPublisher<ExtrasSimVarEvents> { | ||
private static readonly simVars = new Map<keyof ExtrasSimVarEvents, SimVarDefinition>([ | ||
['ecp_to_config_pushbutton', { name: 'L:A32NX_BTN_TOCONFIG', type: SimVarValueType.Bool }], | ||
['fwc_flight_phase', { name: 'L:A32NX_FWC_FLIGHT_PHASE', type: SimVarValueType.Number }], | ||
]); | ||
|
||
constructor(bus: EventBus, pacer?: PublishPacer<ExtrasSimVarEvents>) { | ||
super(ExtrasSimVarPublisher.simVars, bus, pacer); | ||
} | ||
} |
124 changes: 124 additions & 0 deletions
124
fbw-a380x/src/systems/extras-host/modules/key_interceptor/KeyInterceptor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
// Copyright (c) 2022 FlyByWire Simulations | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
import { EventBus, KeyEvents, KeyEventManager } from '@microsoft/msfs-sdk'; | ||
import { NotificationManager, NotificationType, PopUpDialog } from '@flybywiresim/fbw-sdk'; | ||
import { AircraftPresetsList } from '../common/AircraftPresetsList'; | ||
|
||
/** | ||
* This class is used to intercept the key events for the engine auto start and engine auto shutdown. | ||
* | ||
* Additional key events can be added in the registerIntercepts() method. | ||
*/ | ||
export class KeyInterceptor { | ||
private eventBus: EventBus; | ||
|
||
private keyInterceptManager: KeyEventManager; | ||
|
||
private dialogVisible = false; | ||
|
||
constructor(private readonly bus: EventBus, private readonly notification: NotificationManager) { | ||
this.eventBus = bus; | ||
KeyEventManager.getManager(this.eventBus).then((manager) => { | ||
this.keyInterceptManager = manager; | ||
this.registerIntercepts(); | ||
}); | ||
console.log('KeyInterceptor: Created'); | ||
} | ||
|
||
public startPublish(): void { | ||
console.log('KeyInterceptor: startPublish()'); | ||
} | ||
|
||
private registerIntercepts() { | ||
this.keyInterceptManager.interceptKey('ENGINE_AUTO_START', false); | ||
this.keyInterceptManager.interceptKey('ENGINE_AUTO_SHUTDOWN', false); | ||
|
||
const subscriber = this.eventBus.getSubscriber<KeyEvents>(); | ||
subscriber.on('key_intercept').handle((keyData) => { | ||
switch (keyData.key) { | ||
case 'ENGINE_AUTO_START': | ||
console.log('KeyInterceptor: ENGINE_AUTO_START'); | ||
this.engineAutoStartAction(); | ||
break; | ||
case 'ENGINE_AUTO_SHUTDOWN': | ||
console.log('KeyInterceptor: ENGINE_AUTO_SHUTDOWN'); | ||
this.engineAutoStopAction(); | ||
break; | ||
default: | ||
break; | ||
} | ||
}); | ||
} | ||
|
||
private engineAutoStartAction() { | ||
if (!this.dialogVisible) { | ||
// If loading already in progress show a notification and return | ||
if (this.isAlreadyLoading()) return; | ||
// Show a dialog to ask user to load a preset or cancel | ||
this.dialogVisible = true; | ||
const dialog = new PopUpDialog(); | ||
const presetID = 4; // "Ready for Taxi" | ||
dialog.showPopUp( | ||
'Ctrl+E Not supported', | ||
`<div style="font-size: 120%; text-align: left;"> | ||
Engine Auto Start is not supported by the A380X.<br/> | ||
<br/> | ||
Do you want to you use the flyPad's Aircraft Presets to set the aircraft to | ||
<strong>"${AircraftPresetsList.getPresetName(presetID)}"</strong>? | ||
</div>`, | ||
'small', | ||
() => this.loadPreset(presetID), | ||
() => this.dialogVisible = false, | ||
); | ||
} | ||
} | ||
|
||
private engineAutoStopAction() { | ||
if (this.isAlreadyLoading()) return; | ||
// If engines are running show a dialog to ask user to load a preset or cancel | ||
if (!this.dialogVisible && this.isOneEngineRunning()) { | ||
this.dialogVisible = true; | ||
const dialog = new PopUpDialog(); | ||
const presetID = 2; | ||
dialog.showPopUp( | ||
'Shift+Ctrl+E Not supported', | ||
`<div style="font-size: 120%; text-align: left;"> | ||
Engine Auto Shutdown is not supported by the A380X.<br/> | ||
<br/> | ||
Do you want to you use the flyPad's Aircraft Presets to set the aircraft to | ||
<strong>"${AircraftPresetsList.getPresetName(presetID)}"</strong>? | ||
</div>`, | ||
'small', | ||
() => this.loadPreset(presetID), | ||
() => this.dialogVisible = false, | ||
); | ||
} | ||
} | ||
|
||
private isAlreadyLoading() { | ||
const loadingInProgress = SimVar.GetSimVarValue('L:A32NX_AIRCRAFT_PRESET_LOAD', 'Number'); | ||
if (loadingInProgress > 0) { | ||
this.notification.showNotification({ | ||
title: 'Aircraft Presets', | ||
message: `Loading Preset is already in progress "${(AircraftPresetsList.getPresetName(loadingInProgress))}"`, | ||
type: NotificationType.Message, | ||
timeout: 1500, | ||
}); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
private isOneEngineRunning() { | ||
const engine1N1 = SimVar.GetSimVarValue('L:A32NX_ENGINE_N1:1', 'Number'); | ||
const engine2N1 = SimVar.GetSimVarValue('L:A32NX_ENGINE_N1:2', 'Number'); | ||
return engine1N1 > 0.1 || engine2N1 > 0.1; | ||
} | ||
|
||
private loadPreset(presetID: number) { | ||
console.log(`Setting aircraft preset to ${AircraftPresetsList.getPresetName(presetID)}`); | ||
SimVar.SetSimVarValue('L:A32NX_AIRCRAFT_PRESET_LOAD', 'Number', presetID); | ||
this.dialogVisible = false; | ||
} | ||
} |
Oops, something went wrong.