From 9754ad540e39de0164bd1de13a7628287e16be56 Mon Sep 17 00:00:00 2001 From: Andy Ford Date: Fri, 2 Jul 2021 14:55:32 +0100 Subject: [PATCH] feat(releases): Add electronic departure releases (#272) * feat(curl): Include User Agent In cURL * feat(graphics): Add standard graphics components (#267) * feat(graphics): Add standard graphics components * Add system clock and timer displays * Add To Project * Move To Right Project * Add Missing Matchers * feat(controllers): Implement controller positions V2 dependency (#268) * feat(controllers): Implement controller positions V2 dependency * Add Missing Change * test(misc): Bring across changes from more tests * feat(releases): Add API calls for departure releases (#269) * feat(euroscope): Add additional EuroScope interfaces (#271) * feat(euroscope): Add additional EuroScope interfaces * Update Base Plugin * Departure release features (#281) * Add departure release docs * Departure release resources * Update Release Module Bootstrap * Merge in release bits * Add Missing Override * Add Missing Solution Items * Fix linting * Change Wording --- docs/TAG_FUNCTIONS.md | 8 +- docs/TAG_ITEMS.md | 3 + docs/UserGuide/Features/DepartureReleases.md | 111 + docs/UserGuide/Features/Features.md | 1 + .../UKControllerPlugin.vcxproj | 33 + .../UKControllerPlugin.vcxproj.filters | 115 +- .../UKControllerPluginTest.vcxproj | 13 + .../UKControllerPluginTest.vcxproj.filters | 47 +- .../UKControllerPluginUtils.vcxproj | 2 + .../UKControllerPluginUtils.vcxproj.filters | 9 + resource/UKControllerPlugin.rc | Bin 31984 -> 36382 bytes resource/resource.h | 17 +- src/api/ApiHelper.cpp | 53 + src/api/ApiHelper.h | 15 + src/api/ApiInterface.h | 15 + src/api/ApiRequestBuilder.cpp | 88 + src/api/ApiRequestBuilder.h | 16 + src/bootstrap/InitialisePlugin.cpp | 2 +- src/components/BrushSwitcher.cpp | 52 + src/components/BrushSwitcher.h | 51 + src/components/Button.cpp | 55 + src/components/Button.h | 49 + src/components/ClickableArea.cpp | 58 + src/components/ClickableArea.h | 47 + src/components/StandardButtons.cpp | 120 + src/components/StandardButtons.h | 24 + src/components/TitleBar.cpp | 87 + src/components/TitleBar.h | 44 + src/controller/ControllerPosition.cpp | 49 +- src/controller/ControllerPosition.h | 41 +- .../ControllerPositionCollection.cpp | 17 +- src/controller/ControllerPositionCollection.h | 24 +- .../ControllerPositionCollectionFactory.cpp | 83 +- .../ControllerPositionCollectionFactory.h | 3 +- src/curl/CurlApi.cpp | 4 + src/curl/CurlRequest.cpp | 4 +- src/curl/CurlRequest.h | 1 + src/euroscope/EuroScopeCFlightPlanInterface.h | 1 + src/euroscope/EuroScopeCFlightPlanWrapper.cpp | 5 + src/euroscope/EuroScopeCFlightPlanWrapper.h | 1 + .../EuroscopeFlightplanListInterface.h | 40 + .../EuroscopeFlightplanListWrapper.cpp | 76 + .../EuroscopeFlightplanListWrapper.h | 35 + .../EuroscopePluginLoopbackInterface.h | 21 +- src/graphics/GdiGraphicsInterface.h | 9 + src/graphics/GdiGraphicsWrapper.cpp | 120 +- src/graphics/GdiGraphicsWrapper.h | 9 + src/ownership/AirfieldOwnershipManager.cpp | 2 +- src/plugin/UKPlugin.cpp | 36 +- src/plugin/UKPlugin.h | 79 +- src/radarscreen/RadarRenderableInterface.h | 1 + src/radarscreen/RadarScreenFactory.cpp | 2 + .../ApproveDepartureReleaseDialog.cpp | 247 ++ src/releases/ApproveDepartureReleaseDialog.h | 43 + src/releases/CompareDepartureReleases.cpp | 30 + src/releases/CompareDepartureReleases.h | 27 + src/releases/DepartureReleaseColours.h | 17 + .../DepartureReleaseCountdownColours.cpp | 30 + .../DepartureReleaseCountdownColours.h | 15 + src/releases/DepartureReleaseDecisionList.cpp | 301 +++ src/releases/DepartureReleaseDecisionList.h | 105 + src/releases/DepartureReleaseEventHandler.cpp | 909 +++++++ src/releases/DepartureReleaseEventHandler.h | 161 ++ src/releases/DepartureReleaseRequest.cpp | 129 + src/releases/DepartureReleaseRequest.h | 84 + src/releases/DepartureReleaseRequestView.cpp | 204 ++ src/releases/DepartureReleaseRequestView.h | 72 + src/releases/ReleaseModule.cpp | 232 +- src/releases/ReleaseModule.h | 21 +- .../RequestDepartureReleaseDialog.cpp | 184 ++ src/releases/RequestDepartureReleaseDialog.h | 48 + .../ToggleDepartureReleaseDecisionList.cpp | 33 + .../ToggleDepartureReleaseDecisionList.h | 34 + src/time/SystemClock.cpp | 22 + src/time/SystemClock.h | 8 + src/timer/TimerDisplay.cpp | 33 + src/timer/TimerDisplay.h | 8 + test/helper/Matchers.h | 6 + test/mock/MockApiInterface.h | 21 + test/mock/MockEuroScopeCFlightplanInterface.h | 1 + test/mock/MockEuroscopeFlightplanList.h | 26 + .../MockEuroscopePluginLoopbackInterface.h | 37 +- test/mock/MockGraphicsInterface.h | 89 +- test/test/api/ApiHelperTest.cpp | 125 + test/test/api/ApiRequestBuilderTest.cpp | 131 + test/test/components/BrushSwitcherTest.cpp | 54 + test/test/components/ButtonTest.cpp | 75 + test/test/components/ClickableAreaTest.cpp | 60 + test/test/components/TitleBarTest.cpp | 109 + .../ActiveCallsignCollectionTest.cpp | 16 +- .../controller/ActiveCallsignMonitorTest.cpp | 28 +- test/test/controller/ActiveCallsignTest.cpp | 57 +- ...ontrollerPositionCollectionFactoryTest.cpp | 351 ++- .../ControllerPositionCollectionTest.cpp | 226 +- ...ControllerPositionHierarchyFactoryTest.cpp | 4 +- .../ControllerPositionHierarchyTest.cpp | 65 +- .../controller/ControllerPositionTest.cpp | 107 +- .../handoff/HandoffCollectionFactoryTest.cpp | 4 +- test/test/handoff/HandoffCollectionTest.cpp | 2 +- test/test/handoff/HandoffEventHandlerTest.cpp | 25 +- .../InitialAltitudeEventHandlerTest.cpp | 61 +- .../InitialHeadingEventHandlerTest.cpp | 62 +- test/test/metar/PressureMonitorTest.cpp | 2 +- test/test/notifications/NotificationTest.cpp | 4 +- .../NotificationsEventHandlerTest.cpp | 12 +- .../NotificationsRepositoryFactoryTest.cpp | 18 +- .../AirfieldOwnershipHandlerTest.cpp | 26 +- .../AirfieldOwnershipManagerTest.cpp | 53 +- test/test/prenote/AbstractPrenoteTest.cpp | 6 +- test/test/prenote/PrenoteFactoryTest.cpp | 4 +- test/test/prenote/PrenoteMessageTest.cpp | 2 +- test/test/prenote/PrenoteModuleTest.cpp | 4 +- .../prenote/PrenoteServiceFactoryTest.cpp | 4 +- test/test/prenote/PrenoteServiceTest.cpp | 6 +- .../releases/CompareDepartureReleasesTest.cpp | 51 + .../DepartureReleaseCountdownColoursTest.cpp | 100 + .../DepartureReleaseDecisionListTest.cpp | 352 +++ .../DepartureReleaseEventHandlerTest.cpp | 2194 +++++++++++++++++ .../releases/DepartureReleaseRequestTest.cpp | 178 ++ test/test/releases/ReleaseModuleTest.cpp | 122 +- ...ToggleDepartureReleaseDecisionListTest.cpp | 115 + test/test/squawk/SquawkAssignmentTest.cpp | 10 +- test/test/squawk/SquawkEventHandlerTest.cpp | 2 +- test/test/squawk/SquawkGeneratorTest.cpp | 2 +- test/test/time/SystemClockTest.cpp | 30 + test/test/timer/TimerDisplayTest.cpp | 51 + 126 files changed, 9217 insertions(+), 668 deletions(-) create mode 100644 docs/UserGuide/Features/DepartureReleases.md create mode 100644 src/components/BrushSwitcher.cpp create mode 100644 src/components/BrushSwitcher.h create mode 100644 src/components/Button.cpp create mode 100644 src/components/Button.h create mode 100644 src/components/ClickableArea.cpp create mode 100644 src/components/ClickableArea.h create mode 100644 src/components/StandardButtons.cpp create mode 100644 src/components/StandardButtons.h create mode 100644 src/components/TitleBar.cpp create mode 100644 src/components/TitleBar.h create mode 100644 src/euroscope/EuroscopeFlightplanListInterface.h create mode 100644 src/euroscope/EuroscopeFlightplanListWrapper.cpp create mode 100644 src/euroscope/EuroscopeFlightplanListWrapper.h create mode 100644 src/releases/ApproveDepartureReleaseDialog.cpp create mode 100644 src/releases/ApproveDepartureReleaseDialog.h create mode 100644 src/releases/CompareDepartureReleases.cpp create mode 100644 src/releases/CompareDepartureReleases.h create mode 100644 src/releases/DepartureReleaseColours.h create mode 100644 src/releases/DepartureReleaseCountdownColours.cpp create mode 100644 src/releases/DepartureReleaseCountdownColours.h create mode 100644 src/releases/DepartureReleaseDecisionList.cpp create mode 100644 src/releases/DepartureReleaseDecisionList.h create mode 100644 src/releases/DepartureReleaseEventHandler.cpp create mode 100644 src/releases/DepartureReleaseEventHandler.h create mode 100644 src/releases/DepartureReleaseRequest.cpp create mode 100644 src/releases/DepartureReleaseRequest.h create mode 100644 src/releases/DepartureReleaseRequestView.cpp create mode 100644 src/releases/DepartureReleaseRequestView.h create mode 100644 src/releases/RequestDepartureReleaseDialog.cpp create mode 100644 src/releases/RequestDepartureReleaseDialog.h create mode 100644 src/releases/ToggleDepartureReleaseDecisionList.cpp create mode 100644 src/releases/ToggleDepartureReleaseDecisionList.h create mode 100644 src/time/SystemClock.cpp create mode 100644 src/time/SystemClock.h create mode 100644 src/timer/TimerDisplay.cpp create mode 100644 src/timer/TimerDisplay.h create mode 100644 test/mock/MockEuroscopeFlightplanList.h create mode 100644 test/test/components/BrushSwitcherTest.cpp create mode 100644 test/test/components/ButtonTest.cpp create mode 100644 test/test/components/ClickableAreaTest.cpp create mode 100644 test/test/components/TitleBarTest.cpp create mode 100644 test/test/releases/CompareDepartureReleasesTest.cpp create mode 100644 test/test/releases/DepartureReleaseCountdownColoursTest.cpp create mode 100644 test/test/releases/DepartureReleaseDecisionListTest.cpp create mode 100644 test/test/releases/DepartureReleaseEventHandlerTest.cpp create mode 100644 test/test/releases/DepartureReleaseRequestTest.cpp create mode 100644 test/test/releases/ToggleDepartureReleaseDecisionListTest.cpp create mode 100644 test/test/time/SystemClockTest.cpp create mode 100644 test/test/timer/TimerDisplayTest.cpp diff --git a/docs/TAG_FUNCTIONS.md b/docs/TAG_FUNCTIONS.md index e8a736e5f..ba8a11c09 100644 --- a/docs/TAG_FUNCTIONS.md +++ b/docs/TAG_FUNCTIONS.md @@ -10,5 +10,9 @@ 9007 - Open Stand Assignment Selection Menu 9008 - Open Stand Assignment Edit Box 9009 - Open UK Flight Information Services Menu -9010 - Open Oceanic Clearance Diaog -9011 - Recycle Initial Heading \ No newline at end of file +9010 - Open Oceanic Clearance Dialog +9011 - Recycle Initial Heading +9012 - Open Request Departure Release Dialog +9013 - Open Departure Release Decision Menu +9014 - Open Departure Release Request Status View +9015 - Open Departure Release Cancellation Menu \ No newline at end of file diff --git a/docs/TAG_ITEMS.md b/docs/TAG_ITEMS.md index a977c1155..9c4ea8a85 100644 --- a/docs/TAG_ITEMS.md +++ b/docs/TAG_ITEMS.md @@ -23,3 +23,6 @@ 121 - Nattrak Oceanic Clearance Entry Point 122 - Nattrak Oceanic Clearance Track Identifier 123 - Nattrak Oceanic Clearance Entry Estimate +124 - Departure Release Status Indicator +125 - Departure Release Countdown +126 - Departure Release Requesting Controller \ No newline at end of file diff --git a/docs/UserGuide/Features/DepartureReleases.md b/docs/UserGuide/Features/DepartureReleases.md new file mode 100644 index 000000000..3dd88ba1b --- /dev/null +++ b/docs/UserGuide/Features/DepartureReleases.md @@ -0,0 +1,111 @@ +# Departure Releases + +Part of controlling Tower positions at most if not all UK airports is requesting a release for departure, that is, asking +the above controller such an Radar or Area Control unit for permission to depart an aircraft. Some airfields do this for every +departure, whereas others have a "free flow" agreement, whereby normally a release would not be required except under +special circumstances such as after a missed approach. + +As an alternative to coordinating this via TeamSpeak, the UK Controller Plugin provides a way to achieve this electronically. + +## Who Can Request Releases? + +Only positions of TWR and above can request departure releases. Ground and Delivery positions will not be able to open +the request release dialog. To be able to request a release, you must be recognised by the plugin as an active controller. + +## Who Can Be Targeted For A Release Request? + +Only positions of APP and above can be selected as a target controller for a departure release. Tower, Ground and Delivery +will not appear in the target list. + +## How Do I Request A Release? + +A release for a given aircraft can be requested using the `Open Request Departure Release Dialog` TAG function (see below). +Activate this using the aircrafts TAG or a EuroScope list, select the controller you wish to target from the dropdown and +click request. + +Release requests are active for five minutes, before automatically expiring. + +## Can I Have Multiple Requests At Once? + +For a given aircraft, there may be one "active" release request for a single controller position at any given time. +In this context, "active" is defined to mean not rejected or request expired. It is therefore possible to request a release +from several controller positions at once. + +## How Can I Check The Status Of My Release Requests? + +There are two options for viewing the status of releases that you have requested. You may either use the Status Indicator +and Countdown TAG items described below, or you can use the `Open Departure Release Status View` TAG function to popup +a temporary display for a given aircrafts releases. + +## How Do I Respond To A Release Request? + +If you are the target of a release request, you can use the `Departure Release Decision List` to make decisions on individual +releases. This may be toggled on a per-ASR basis using the `OP` menu. + +If there is a pending release request for you, the header bar of the list will flash *_Red_*. + +To make a decision in the aforementioned list, left click on the aircrafts callsign and select your decision from the menu. + +If you click "Approve", you will be presented with another dialog that allows you to specify additional constraints, such +as the "released at" time, as well as an approval expiry time. + +Alternatively, you can use the `Open Departure Release Decision Menu` TAG function in aircraft TAGs or EuroScope lists. + +## TAG Items + +Several TAG items are provided for Departure Releases. + +### Departure Release Status Indicator + +This TAG item displays the current status of any releases that are in progress for a given aircraft. It does this by +displaying in the format of `X/Y` where `X` is the number of approved releases and `Y` is the total number of active release +requests. + +The indicator will show as *_Green_* if all active release requests have been approved and not subject to any "released at" +conditions. If all active release requests have been approved but are subject to a "released at" condition, the indicator +will display in *_Pink_*. + +The indicator will show as *_Red_* if any active release requests have been rejected. + +The indicator will show as *_Orange_* if any active release requests have been approved but since expired. + +### Departure Release Countdown + +This TAG item displays two types of countdown. + +The first type of countdown is the time until release expiry when all release requests are approved. +This indicates how long it will be before the first active release request expires (if applicable). This timer will start +in *_White_*, transitioning to *_Yellow_* and finally *_Red_* as it gets closer to zero. + +If the timer displays in *_Pink_*, it is indicating how long it will be until all the active release requests have met +their "released at" conditions, which give you an indicator of how long it will be until the aircraft can depart. + +### Departure Release Requesting Controller + +This can be used by controllers that are able to approve departure releases. It will display the callsign of the controller +requesting the release. + +## TAG Functions + +Several TAG functions are available for departure releases. + +### Open Request Departure Release Dialog + +This TAG function triggers the request release dialog, through which you can select a controller to ask for +a release. + +### Open Departure Release Decision Menu + +This TAG function opens up the departure release decision menu. Controllers who are the target of a departure release +can use this to make a decision on the release request. + +### Open Departure Release Status View + +This TAG function toggles (for a brief period) a small view of the outstanding departure release requests for a given +aircraft. It displays the target controller, a countdown until any "released at" times, as well as a countdown until +any release expiry times. + +### Open Departure Release Cancellation Menu + +This TAG function opens a menu that allows you to select a target controller for whom to cancel a release request. Use +this if you want to withdraw your request at any time. diff --git a/docs/UserGuide/Features/Features.md b/docs/UserGuide/Features/Features.md index 38aa30ff0..d801b56b1 100644 --- a/docs/UserGuide/Features/Features.md +++ b/docs/UserGuide/Features/Features.md @@ -25,3 +25,4 @@ dynamically to the plugin. - Stand assignment - RECAT-EU Wake Categories - [VATSIM Nattrak Integration](Nattrak.md) +- [Electronic Departure Releases](DepartureReleases.md) diff --git a/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj b/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj index 247454cf1..d7415cbc8 100644 --- a/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj +++ b/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj @@ -30,6 +30,11 @@ + + + + + @@ -70,6 +75,8 @@ + + @@ -263,12 +270,21 @@ + + + + + + + + + @@ -304,6 +320,7 @@ + @@ -329,6 +346,11 @@ + + + + + @@ -360,6 +382,7 @@ + @@ -520,10 +543,19 @@ + + + + + + + + + @@ -555,6 +587,7 @@ + diff --git a/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj.filters b/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj.filters index b094e35c8..c545c8237 100644 --- a/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj.filters +++ b/msvc/UKControllerPlugin/UKControllerPlugin.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -94,6 +94,9 @@ {93c29766-c3d5-47e0-8cfd-5d71d115cd0e} + + {ae5b89fa-f548-48d4-9a2a-f651295aeeb4} + {61c300dc-1834-4381-b018-2c7380756930} @@ -142,8 +145,11 @@ {a732eccf-1336-457a-8597-2f558558027c} - - {ae5b89fa-f548-48d4-9a2a-f651295aeeb4} + + {bb7c490c-3f8f-4f8f-b927-0c6fd6683ffd} + + + {6450b077-67f8-46e3-a43d-2fbe69517379} @@ -1001,7 +1007,31 @@ src\plugin - + + src\euroscope + + + src\euroscope + + + src\components + + + src\components + + + src\components + + + src\components + + + src\components + + + src\timer + + src\push @@ -1036,6 +1066,33 @@ src\push + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases @@ -1752,6 +1809,27 @@ src\plugin + + src\euroscope + + + src\components + + + src\components + + + src\components + + + src\components + + + src\components + + + src\timer + src\push @@ -1778,6 +1856,33 @@ src\push + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases + + + src\releases - \ No newline at end of file + diff --git a/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj b/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj index f7feea242..db79eddae 100644 --- a/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj +++ b/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj @@ -43,6 +43,10 @@ + + + + @@ -211,10 +215,16 @@ + + + + + + @@ -245,7 +255,9 @@ + + @@ -270,6 +282,7 @@ + diff --git a/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj.filters b/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj.filters index ee9366d57..59e588eae 100644 --- a/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj.filters +++ b/msvc/UKControllerPluginTest/UKControllerPluginTest.vcxproj.filters @@ -133,6 +133,12 @@ {1f6bc603-4f77-4a4d-8364-2b8e739fce7e} + + {f1bcb9fd-718e-4080-8b9e-faee181caa40} + + + {ca735e2e-aae4-42c9-88af-8c82006b8942} + {83e0dc64-52da-4353-9dc2-375e76d00366} @@ -796,6 +802,42 @@ test\plugin + + test\components + + + test\components + + + test\components + + + test\components + + + test\time + + + test\timer + + + test\releases + + + test\releases + + + test\releases + + + test\releases + + + test\releases + + + test\releases + test\push @@ -931,8 +973,11 @@ mock + + mock + - \ No newline at end of file + diff --git a/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj b/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj index 505ca5baa..a29b94933 100644 --- a/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj +++ b/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj @@ -52,6 +52,7 @@ + @@ -85,6 +86,7 @@ + diff --git a/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj.filters b/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj.filters index 54da5ec0a..32bf77595 100644 --- a/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj.filters +++ b/msvc/UKControllerPluginUtils/UKControllerPluginUtils.vcxproj.filters @@ -40,6 +40,9 @@ {2e91c81e-5b35-4bf3-9430-b2dc6020d6c5} + + {e4bbf668-1c32-4538-ac99-c46b8f2d2124} + @@ -162,6 +165,9 @@ duplicate + + time + @@ -245,5 +251,8 @@ duplicate + + time + \ No newline at end of file diff --git a/resource/UKControllerPlugin.rc b/resource/UKControllerPlugin.rc index ff5690568f978c245affc17e87fb8b440d3394d5..2397a538c721c88b13fb3f30dbf3d548da7323ae 100644 GIT binary patch delta 1824 zcmbVN(QA@X6hF3NS#uMn#gM=j!Uo&)Q$L+Wg?yiGE8EQJ0!>89No*^1QyK)ThaQ5U z#(C)>g8c)L`5e9V6odK?_77CAMGyV%Rp*poDj(mu=YIFzbIh9a@31RKlzbnZq}+XB}@Advd&&c)@S<;jwX8TfqJ$x(Q7sAEY9z^G{pa zBs8V<#c_qrk(2!O?$FidISpR-9*H46${#h0Q6WF9yGdoICC~>VhO~9W-|$d{rCAE_ zw65^Wc{6`EyLJQudBiL*(dZF9gjT}1E|DlvuTjKhzUGjRIO5iT+9I?V#t5Dew2a6U zcEy3J#-FvpK`*)Bnaa>+JF$vMUHK6(nvI$)v8>7VZ_|VPu=5v^Q=9l z7SBXnz3{Blj&;P>@X;-i_8sBbOm+oTwN4M{KClaeU%fM{?LM$*1ssaV$_#^DF|KOX z0pyx5q|XZ$rMh9!F*XrLJtmK=dVfPI;Ls%hQ7`lU$jm}N_lREB>S8*gK|OHwnvzaUiyVF^cgXt%1vKS&=$cmT@YE_~&R|)|0?u4%KF-CwQAX5;!Y**Bx5q zi$gX?ebq&e(FvN-HS^|bqX6H^@HSz&|U7tCxgo~ixV V{Bo+#|I}V3MakeApiRequest( + this->requestBuilder.BuildAcknowledgeDepartureReleaseRequest(releaseId, controllerPositionId) + ); + } + + void ApiHelper::RejectDepartureReleaseRequest(int releaseId, int controllerPositionId) const + { + this->MakeApiRequest( + this->requestBuilder.BuildRejectDepartureReleaseRequest(releaseId, controllerPositionId) + ); + } + + void ApiHelper::ApproveDepartureReleaseRequest( + int releaseId, + int controllerPositionId, + std::chrono::system_clock::time_point releasedAt, + int expiresInSeconds + ) const + { + this->MakeApiRequest( + this->requestBuilder.BuildApproveDepartureReleaseRequest( + releaseId, + controllerPositionId, + releasedAt, + expiresInSeconds + ) + ); + } + + nlohmann::json ApiHelper::RequestDepartureRelease( + std::string callsign, + int requestingControllerId, + int targetControllerId, + int expiresInSeconds + ) const + { + return this->MakeApiRequest( + this->requestBuilder.BuildDepartureReleaseRequest( + callsign, + requestingControllerId, + targetControllerId, + expiresInSeconds + ) + ).GetRawData(); + } + + void ApiHelper::CancelDepartureReleaseRequest(int releaseId) const + { + this->MakeApiRequest(this->requestBuilder.BuildCancelReleaseRequest(releaseId)); + } + void ApiHelper::ReadNotification(int id) const { this->MakeApiRequest(this->requestBuilder.BuildReadNotificationRequest(id)); diff --git a/src/api/ApiHelper.h b/src/api/ApiHelper.h index 2bc874bf0..f20d0ed3b 100644 --- a/src/api/ApiHelper.h +++ b/src/api/ApiHelper.h @@ -73,6 +73,21 @@ namespace UKControllerPlugin { nlohmann::json GetUnreadNotifications() const override; nlohmann::json SyncPluginEvents() const override; nlohmann::json GetLatestPluginEvents(int lastEventId) const override; + void AcknowledgeDepartureReleaseRequest(int releaseId, int controllerPositionId) const override; + void RejectDepartureReleaseRequest(int releaseId, int controllerPositionId) const override; + void ApproveDepartureReleaseRequest( + int releaseId, + int controllerPositionId, + std::chrono::system_clock::time_point releasedAt, + int expiresInSeconds + ) const override; + nlohmann::json RequestDepartureRelease( + std::string callsign, + int requestingControllerId, + int targetControllerId, + int expiresInSeconds + ) const override; + void CancelDepartureReleaseRequest(int releaseId) const override; void ReadNotification(int id) const override; int UpdateCheck(std::string version) const override; void SetApiKey(std::string key) override; diff --git a/src/api/ApiInterface.h b/src/api/ApiInterface.h index 1b10b3f06..99490bacc 100644 --- a/src/api/ApiInterface.h +++ b/src/api/ApiInterface.h @@ -60,6 +60,21 @@ namespace UKControllerPlugin { virtual nlohmann::json GetUnreadNotifications() const = 0; virtual nlohmann::json SyncPluginEvents() const = 0; virtual nlohmann::json GetLatestPluginEvents(int lastEventId) const = 0; + virtual void AcknowledgeDepartureReleaseRequest(int releaseId, int controllerPositionId) const = 0; + virtual void RejectDepartureReleaseRequest(int releaseId, int controllerPositionId) const = 0; + virtual void ApproveDepartureReleaseRequest( + int releaseId, + int controllerPositionId, + std::chrono::system_clock::time_point releasedAt, + int expiresInSeconds + ) const = 0; + virtual nlohmann::json RequestDepartureRelease( + std::string callsign, + int requestingControllerId, + int targetControllerId, + int expiresInSeconds + ) const = 0; + virtual void CancelDepartureReleaseRequest(int releaseId) const = 0; virtual void ReadNotification(int id) const = 0; virtual int UpdateCheck(std::string version) const = 0; virtual nlohmann::json GetUpdateDetails() const = 0; diff --git a/src/api/ApiRequestBuilder.cpp b/src/api/ApiRequestBuilder.cpp index 00de91056..e1a4812d2 100644 --- a/src/api/ApiRequestBuilder.cpp +++ b/src/api/ApiRequestBuilder.cpp @@ -306,6 +306,94 @@ namespace UKControllerPlugin { ); } + CurlRequest ApiRequestBuilder::BuildAcknowledgeDepartureReleaseRequest( + int releaseId, + int controllerPositionId + ) const + { + nlohmann::json body; + body["controller_position_id"] = controllerPositionId; + + CurlRequest request( + this->apiDomain + "/departure/release/request/" + std::to_string(releaseId) + "/acknowledge", + CurlRequest::METHOD_PATCH + ); + request.SetBody(body.dump()); + return this->AddCommonHeaders(request); + } + + CurlRequest ApiRequestBuilder::BuildRejectDepartureReleaseRequest( + int releaseId, + int controllerPositionId + ) const + { + nlohmann::json body; + body["controller_position_id"] = controllerPositionId; + + CurlRequest request( + this->apiDomain + "/departure/release/request/" + std::to_string(releaseId) + "/reject", + CurlRequest::METHOD_PATCH + ); + request.SetBody(body.dump()); + return this->AddCommonHeaders(request); + } + + /* + * Build an approve departure release request, pass -1 seconds for never expires. + */ + CurlRequest ApiRequestBuilder::BuildApproveDepartureReleaseRequest( + int releaseId, + int controllerPositionId, + std::chrono::system_clock::time_point releasedAt, + int expiresInSeconds + ) const + { + nlohmann::json body; + body["controller_position_id"] = controllerPositionId; + body["released_at"] = date::format("%Y-%m-%d %H:%M:%S", date::floor(releasedAt)); + if (expiresInSeconds == -1) { + body["expires_in_seconds"] = nlohmann::json::value_t::null; + } else { + body["expires_in_seconds"] = expiresInSeconds; + } + + CurlRequest request( + this->apiDomain + "/departure/release/request/" + std::to_string(releaseId) + "/approve", + CurlRequest::METHOD_PATCH + ); + request.SetBody(body.dump()); + return this->AddCommonHeaders(request); + } + + CurlRequest ApiRequestBuilder::BuildDepartureReleaseRequest( + std::string callsign, + int requestingControllerId, + int targetController, + int expiresInSeconds + ) const + { + CurlRequest request(this->apiDomain + "/departure/release/request", CurlRequest::METHOD_POST); + + nlohmann::json body; + body["callsign"] = callsign; + body["requesting_controller_id"] = requestingControllerId; + body["target_controller_id"] = targetController; + body["expires_in_seconds"] = expiresInSeconds; + request.SetBody(body.dump()); + + return this->AddCommonHeaders(request); + } + + CurlRequest ApiRequestBuilder::BuildCancelReleaseRequest(int releaseId) const + { + return this->AddCommonHeaders( + CurlRequest( + this->apiDomain + "/departure/release/request/" + std::to_string(releaseId), + CurlRequest::METHOD_DELETE + ) + ); + } + CurlRequest ApiRequestBuilder::BuildEnrouteReleaseRequest( std::string aircraftCallsign, std::string sendingController, diff --git a/src/api/ApiRequestBuilder.h b/src/api/ApiRequestBuilder.h index 575cd4165..f3f86399f 100644 --- a/src/api/ApiRequestBuilder.h +++ b/src/api/ApiRequestBuilder.h @@ -72,6 +72,22 @@ namespace UKControllerPlugin { Curl::CurlRequest BuildLatestGithubVersionRequest() const; Curl::CurlRequest BuildPluginEventSyncRequest() const; Curl::CurlRequest BuildGetLatestPluginEventsRequest(int lastEventId) const; + Curl::CurlRequest + BuildAcknowledgeDepartureReleaseRequest(int releaseId, int controllerPositionId) const; + Curl::CurlRequest BuildRejectDepartureReleaseRequest(int releaseId, int controllerPositionId) const; + Curl::CurlRequest BuildApproveDepartureReleaseRequest( + int releaseId, + int controllerPositionId, + std::chrono::system_clock::time_point releasedAt, + int expiresInSeconds + ) const; + Curl::CurlRequest BuildDepartureReleaseRequest( + std::string callsign, + int requestingControllerId, + int targetControllerId, + int expiresInSeconds + ) const; + Curl::CurlRequest BuildCancelReleaseRequest(int releaseId) const; std::string GetApiDomain(void) const; std::string GetApiKey(void) const; void SetApiDomain(std::string domain); diff --git a/src/bootstrap/InitialisePlugin.cpp b/src/bootstrap/InitialisePlugin.cpp index 938b91dee..390cf1b19 100644 --- a/src/bootstrap/InitialisePlugin.cpp +++ b/src/bootstrap/InitialisePlugin.cpp @@ -199,7 +199,7 @@ namespace UKControllerPlugin { AirfieldOwnershipModule::BootstrapPlugin(*this->container, loader); Sid::BootstrapPlugin(*this->container, loader); Navaids::BootstrapPlugin(*this->container, loader); - Releases::BootstrapPlugin(*this->container, loader); + Releases::BootstrapPlugin(*this->container, *this->container->plugin, loader); Stands::BootstrapPlugin(*this->container, loader); Notifications::BootstrapPlugin(*this->container); FlightInformationService::BootstrapPlugin(*this->container); diff --git a/src/components/BrushSwitcher.cpp b/src/components/BrushSwitcher.cpp new file mode 100644 index 000000000..e3e403405 --- /dev/null +++ b/src/components/BrushSwitcher.cpp @@ -0,0 +1,52 @@ +#include "pch/stdafx.h" +#include "components/BrushSwitcher.h" +#include "time/SystemClock.h" + +namespace UKControllerPlugin::Components { + + std::shared_ptr BrushSwitcher::Create( + std::shared_ptr baseBrush, + const std::chrono::seconds phase + ) + { + return std::shared_ptr(new BrushSwitcher(baseBrush, phase)); + } + + std::shared_ptr BrushSwitcher::AdditionalBrush(std::shared_ptr brush) + { + this->brushes.push_back(brush); + return shared_from_this(); + } + + std::shared_ptr BrushSwitcher::Base() const + { + return this->baseBrush; + } + + std::shared_ptr BrushSwitcher::Next() + { + if (this->brushes.empty()) { + return this->Base(); + } + + if (this->nextSwitch < Time::TimeNow()) { + this->nextSwitch = Time::TimeNow() + this->phase; + + if (this->brushIndex == this->brushes.size() - 1) { + this->brushIndex = 0; + } else { + this->brushIndex++; + } + } + + return this->brushes.at(this->brushIndex); + } + + BrushSwitcher::BrushSwitcher( + std::shared_ptr baseBrush, + const std::chrono::seconds phase) + : baseBrush(std::move(baseBrush)), phase(phase) + { + this->brushes.push_back(this->baseBrush); + } +} // namespace UKControllerPlugin::Components diff --git a/src/components/BrushSwitcher.h b/src/components/BrushSwitcher.h new file mode 100644 index 000000000..74867ab14 --- /dev/null +++ b/src/components/BrushSwitcher.h @@ -0,0 +1,51 @@ +#pragma once + +namespace UKControllerPlugin { + namespace Euroscope { + class EuroscopeRadarLoopbackInterface; + } // namespace Euroscope + namespace Windows { + class GdiGraphicsInterface; + } // namespace Windows +} // namespace UKControllerPlugin + +namespace UKControllerPlugin::Components { + + /* + * A class that switches brushes on each tick, used to implement + * flashing colours. + */ + class BrushSwitcher : public std::enable_shared_from_this + { + public: + static std::shared_ptr Create( + std::shared_ptr baseBrush, + std::chrono::seconds phase + ); + std::shared_ptr AdditionalBrush(std::shared_ptr baseBrush); + std::shared_ptr Base() const; + std::shared_ptr Next(); + + protected: + explicit BrushSwitcher( + std::shared_ptr baseBrush, + std::chrono::seconds phase + ); + + private: + // The base colour + std::shared_ptr baseBrush; + + // The colours to cycle + std::vector> brushes; + + // The current colour index + int brushIndex = 0; + + // Last time colours were switched + std::chrono::system_clock::time_point nextSwitch = (std::chrono::system_clock::time_point::min)(); + + // How often to switch colours + const std::chrono::seconds phase; + }; +} // namespace UKControllerPlugin::Components diff --git a/src/components/Button.cpp b/src/components/Button.cpp new file mode 100644 index 000000000..55a6096e1 --- /dev/null +++ b/src/components/Button.cpp @@ -0,0 +1,55 @@ +#include "pch/stdafx.h" +#include "components/Button.h" +#include "components/ClickableArea.h" +#include "euroscope/EuroscopeRadarLoopbackInterface.h" +#include "graphics/GdiGraphicsInterface.h" + +namespace UKControllerPlugin::Components { + + std::shared_ptr