diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index 21500f98021..10fd1dcdbe9 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -11,6 +11,7 @@ 1. [EFB] Fixed the main page and landing calculator to use the selected METAR source - @tracernz (Mike) 1. [FMS] Improve layout of PERF CLB, PERF CRZ and PERF DES pages according to H3 - @BlueberryKing (BlueberryKing) 1. [FMS] Implement CHECK SPEED MODE message - @BlueberryKing (BlueberryKing) +1. [PFD] The ILS frequency is now visible even when a LOC is not received - @tracernz (Mike) ## 0.11.0 diff --git a/fbw-a32nx/src/systems/instruments/src/PFD/LandingSystemIndicator.tsx b/fbw-a32nx/src/systems/instruments/src/PFD/LandingSystemIndicator.tsx index 7e8fa3a766e..18c57578511 100644 --- a/fbw-a32nx/src/systems/instruments/src/PFD/LandingSystemIndicator.tsx +++ b/fbw-a32nx/src/systems/instruments/src/PFD/LandingSystemIndicator.tsx @@ -2,92 +2,71 @@ // // SPDX-License-Identifier: GPL-3.0 -import { DisplayComponent, FSComponent, HEvent, Subject, VNode } from '@microsoft/msfs-sdk'; +import { ConsumerSubject, DisplayComponent, FSComponent, HEvent, MappedSubject, MathUtils, Subject, Subscribable, SubscribableMapFunctions, Subscription, VNode } from '@microsoft/msfs-sdk'; import { getDisplayIndex } from 'instruments/src/PFD/PFD'; -import { Arinc429Register, Arinc429Word } from '@flybywiresim/fbw-sdk'; +import { Arinc429RegisterSubject } from 'instruments/src/MsfsAvionicsCommon/Arinc429RegisterSubject'; import { Arinc429Values } from './shared/ArincValueProvider'; import { PFDSimvars } from './shared/PFDSimvarPublisher'; import { LagFilter } from './PFDUtils'; import { ArincEventBus } from '../MsfsAvionicsCommon/ArincEventBus'; -// TODO true ref +// FIXME true ref export class LandingSystem extends DisplayComponent<{ bus: ArincEventBus, instrument: BaseInstrument }> { - private lsButtonPressedVisibility = false; + private readonly lsVisible = ConsumerSubject.create(null, false); - private xtkValid = Subject.create(false); + private readonly lsHidden = this.lsVisible.map(SubscribableMapFunctions.not()); - private ldevRequest = false; + private readonly xtk = ConsumerSubject.create(null, 0); - private lsGroupRef = FSComponent.createRef(); + // FIXME this seems like a dubious test... + private readonly xtkValid = this.xtk.map((v) => Math.abs(v) > 0); - private gsReferenceLine = FSComponent.createRef(); + private readonly ldevRequest = ConsumerSubject.create(null, false); - private deviationGroup = FSComponent.createRef(); + private readonly altitude2 = Arinc429RegisterSubject.createEmpty(); - private ldevRef = FSComponent.createRef(); + private readonly isGsReferenceLineHidden = MappedSubject.create( + ([lsVisible, altitude]) => !lsVisible && !altitude.isNormalOperation(), + this.lsVisible, + this.altitude2, + ); - private vdevRef = FSComponent.createRef(); + private readonly isLDevHidden = MappedSubject.create( + ([request, xtkValid]) => !request || !xtkValid, + this.ldevRequest, + this.xtkValid, + ); - private altitude = Arinc429Word.empty(); - - private handleGsReferenceLine() { - if (this.lsButtonPressedVisibility || (this.altitude.isNormalOperation())) { - this.gsReferenceLine.instance.style.display = 'inline'; - } else if (!this.lsButtonPressedVisibility) { - this.gsReferenceLine.instance.style.display = 'none'; - } - } + private readonly isVDevHidden = Subject.create(true); onAfterRender(node: VNode): void { super.onAfterRender(node); const sub = this.props.bus.getSubscriber(); + // FIXME clean this up.. should be handled by an IE in the XML sub.on('hEvent').handle((eventName) => { if (eventName === `A320_Neo_PFD_BTN_LS_${getDisplayIndex()}`) { - this.lsButtonPressedVisibility = !this.lsButtonPressedVisibility; - SimVar.SetSimVarValue(`L:BTN_LS_${getDisplayIndex()}_FILTER_ACTIVE`, 'Bool', this.lsButtonPressedVisibility); - - this.lsGroupRef.instance.style.display = this.lsButtonPressedVisibility ? 'inline' : 'none'; - this.handleGsReferenceLine(); + SimVar.SetSimVarValue(`L:BTN_LS_${getDisplayIndex()}_FILTER_ACTIVE`, 'Bool', !this.lsVisible.get()); } }); - sub.on(getDisplayIndex() === 1 ? 'ls1Button' : 'ls2Button').whenChanged().handle((lsButton) => { - this.lsButtonPressedVisibility = lsButton; - this.lsGroupRef.instance.style.display = this.lsButtonPressedVisibility ? 'inline' : 'none'; - this.deviationGroup.instance.style.display = this.lsButtonPressedVisibility ? 'none' : 'inline'; - this.handleGsReferenceLine(); - }); + this.lsVisible.setConsumer(sub.on(getDisplayIndex() === 1 ? 'ls1Button' : 'ls2Button')); - sub.on('altitudeAr').handle((altitude) => { - this.altitude = altitude; - this.handleGsReferenceLine(); + sub.on('baroCorrectedAltitude').handle((altitude) => { + this.altitude2.setWord(altitude); }); - sub.on(getDisplayIndex() === 1 ? 'ldevRequestLeft' : 'ldevRequestRight').whenChanged().handle((ldevRequest) => { - this.ldevRequest = ldevRequest; - this.updateLdevVisibility(); - }); + this.ldevRequest.setConsumer(sub.on(getDisplayIndex() === 1 ? 'ldevRequestLeft' : 'ldevRequestRight')); - sub.on('xtk').whenChanged().handle((xtk) => { - this.xtkValid.set(Math.abs(xtk) > 0); - }); - - this.xtkValid.sub(() => { - this.updateLdevVisibility(); - }); - } - - updateLdevVisibility() { - this.ldevRef.instance.style.display = this.ldevRequest && this.xtkValid ? 'inline' : 'none'; + this.xtk.setConsumer(sub.on('xtk')); } render(): VNode { return ( <> -