Skip to content

Commit

Permalink
feat(departure-release): Play sound on new request, accept and reject (
Browse files Browse the repository at this point in the history
…#301)

* Add Windows Api As Dependency Of Handler

* Start Adding Sounds

* feat(departure-releases): play sounds on release request, accept and reject

This is so that controllers know something is waiting for them, or has happened.

fix #300

* docs(departure-releases): update the docs
  • Loading branch information
AndyTWF committed Jul 13, 2021
1 parent a537053 commit dd594c2
Show file tree
Hide file tree
Showing 14 changed files with 257 additions and 9 deletions.
5 changes: 4 additions & 1 deletion docs/UserGuide/Features/DepartureReleases.md
Expand Up @@ -49,12 +49,15 @@ The controller callsign indicates the status of the release:
- Blue = Acknowledged
- White = Pending

In addition, there are two audible cues for when a release is accepted or rejected.

## 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_*.
If there is a pending release request for you, the header bar of the list will flash *_Red_*. You will also receive
an audible ping to let you know that something has come in.

To make a decision in the aforementioned list, left click on the aircrafts callsign and select your decision from the menu.

Expand Down
3 changes: 3 additions & 0 deletions msvc/UKControllerPlugin/UKControllerPlugin.vcxproj
Expand Up @@ -12,6 +12,9 @@
<ItemGroup>
<Media Include="..\..\..\resource\sound\beep.wav" />
<Media Include="..\..\resource\sound\beep.wav" />
<Media Include="..\..\resource\sound\departure_release_accepted.wav" />
<Media Include="..\..\resource\sound\departure_release_rejected.wav" />
<Media Include="..\..\resource\sound\departure_release_requested.wav" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\resource\resource.h" />
Expand Down
9 changes: 9 additions & 0 deletions msvc/UKControllerPlugin/UKControllerPlugin.vcxproj.filters
Expand Up @@ -1093,6 +1093,15 @@
<Filter>resource\sound</Filter>
</Media>
<Media Include="..\..\..\resource\sound\beep.wav" />
<Media Include="..\..\resource\sound\departure_release_requested.wav">
<Filter>resource\sound</Filter>
</Media>
<Media Include="..\..\resource\sound\departure_release_accepted.wav">
<Filter>resource\sound</Filter>
</Media>
<Media Include="..\..\resource\sound\departure_release_rejected.wav">
<Filter>resource\sound</Filter>
</Media>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\airfield\AirfieldCollection.cpp">
Expand Down
Binary file modified resource/UKControllerPlugin.rc
Binary file not shown.
5 changes: 4 additions & 1 deletion resource/resource.h
Expand Up @@ -18,6 +18,9 @@
#define IDD_OCEANIC_CLEARANCE 125
#define IDD_DEPARTURE_RELEASE_REQUEST 127
#define IDD_DEPARTURE_RELEASE_APPROVE 129
#define WAVE_DEP_RLS_ACCEPT 131
#define WAVE_DEP_RLS_REJ 132
#define WAVE_DEP_RLS_REQ 133
#define IDC_CHECK_DEGRADING 1001
#define IDC_CHECK_FADING 1002
#define IDC_CHECK_AA 1003
Expand Down Expand Up @@ -159,7 +162,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_RESOURCE_VALUE 134
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1118
#define _APS_NEXT_SYMED_VALUE 101
Expand Down
Binary file added resource/sound/departure_release_accepted.wav
Binary file not shown.
Binary file added resource/sound/departure_release_rejected.wav
Binary file not shown.
Binary file added resource/sound/departure_release_requested.wav
Binary file not shown.
42 changes: 36 additions & 6 deletions src/releases/DepartureReleaseEventHandler.cpp
Expand Up @@ -16,6 +16,7 @@
#include "releases/DepartureReleaseColours.h"
#include "timer/TimerDisplay.h"
#include "releases/DepartureReleaseRequestView.h"
#include "windows/WinApiInterface.h"

namespace UKControllerPlugin {
namespace Releases {
Expand All @@ -27,6 +28,7 @@ namespace UKControllerPlugin {
const Controller::ControllerPositionCollection& controllers,
const Controller::ActiveCallsignCollection& activeCallsigns,
const Dialog::DialogManager& dialogManager,
Windows::WinApiInterface& windows,
const int triggerRequestDialogFunctionId,
const int triggerDecisionMenuFunctionId,
const int releaseDecisionCallbackId,
Expand All @@ -35,7 +37,8 @@ namespace UKControllerPlugin {
triggerDecisionMenuFunctionId(triggerDecisionMenuFunctionId),
releaseDecisionCallbackId(releaseDecisionCallbackId),
controllers(controllers), plugin(plugin), dialogManager(dialogManager), api(api), taskRunner(taskRunner),
activeCallsigns(activeCallsigns), releaseCancellationCallbackId(releaseCancellationCallbackId)
activeCallsigns(activeCallsigns), windows(windows),
releaseCancellationCallbackId(releaseCancellationCallbackId)
{ }

void DepartureReleaseEventHandler::ProcessPushEvent(const Push::PushEvent& message)
Expand Down Expand Up @@ -564,6 +567,15 @@ namespace UKControllerPlugin {
);
}

bool DepartureReleaseEventHandler::UserRequestedRelease(
const std::shared_ptr<DepartureReleaseRequest>& request
) const
{
return this->activeCallsigns.UserHasCallsign() &&
this->activeCallsigns.GetUserCallsign().GetNormalisedPosition().GetId()
== request->RequestingController();
}

/**
* Create a new departure release request.
*/
Expand Down Expand Up @@ -602,6 +614,14 @@ namespace UKControllerPlugin {
++releaseRequest;
}
}

// Play a sound to alert the controller if we are the target
if (
this->activeCallsigns.UserHasCallsign() &&
this->activeCallsigns.GetUserCallsign().GetNormalisedPosition().GetId() == targetController
) {
this->windows.PlayWave(MAKEINTRESOURCE(WAVE_DEP_RLS_REQ));
}
}

/**
Expand Down Expand Up @@ -629,7 +649,13 @@ namespace UKControllerPlugin {
return;
}

this->releaseRequests.find(data.at("id").get<int>())->second->Reject();
auto release = this->releaseRequests.find(data.at("id").get<int>())->second;
release->Reject();

// Play a sound to alert the controller if we requested it
if (this->UserRequestedRelease(release)) {
this->windows.PlayWave(MAKEINTRESOURCE(WAVE_DEP_RLS_REJ));
}
}

/**
Expand All @@ -643,16 +669,20 @@ namespace UKControllerPlugin {
return;
}

auto release = this->releaseRequests.find(data.at("id").get<int>())->second;
if (data.at("expires_at").is_null()) {
this->releaseRequests.find(data.at("id").get<int>())->second->Approve(
Time::ParseTimeString(data.at("released_at").get<std::string>())
);
release->Approve(Time::ParseTimeString(data.at("released_at").get<std::string>()));
} else {
this->releaseRequests.find(data.at("id").get<int>())->second->Approve(
release->Approve(
Time::ParseTimeString(data.at("released_at").get<std::string>()),
Time::ParseTimeString(data.at("expires_at").get<std::string>())
);
}

// Play a sound to alert the controller if we requested it
if (this->UserRequestedRelease(release)) {
this->windows.PlayWave(MAKEINTRESOURCE(WAVE_DEP_RLS_ACCEPT));
}
}

/**
Expand Down
9 changes: 8 additions & 1 deletion src/releases/DepartureReleaseEventHandler.h
Expand Up @@ -24,6 +24,9 @@ namespace UKControllerPlugin {
namespace Api {
class ApiInterface;
} // namespace Api
namespace Windows {
class WinApiInterface;
} // namespace Windows

namespace Releases {

Expand All @@ -44,6 +47,7 @@ namespace UKControllerPlugin {
const Controller::ControllerPositionCollection& controllers,
const Controller::ActiveCallsignCollection& activeCallsigns,
const Dialog::DialogManager& dialogManager,
Windows::WinApiInterface& windows,
int triggerRequestDialogFunctionId,
int triggerDecisionMenuFunctionId,
int releaseDecisionCallbackId,
Expand Down Expand Up @@ -116,8 +120,8 @@ namespace UKControllerPlugin {
void SetReleaseStatusIndicatorTagData(Tag::TagData& tagData);
void SetReleaseCountdownTagData(Tag::TagData& tagData);
void SetRequestingControllerTagData(Tag::TagData& tagData);
bool UserRequestedRelease(const std::shared_ptr<DepartureReleaseRequest>& request) const;

private:
// A guard on the map to allow async operations
std::mutex releaseMapGuard;

Expand Down Expand Up @@ -156,6 +160,9 @@ namespace UKControllerPlugin {

// A set of releases to display in the view
std::set<std::shared_ptr<DepartureReleaseRequest>> releasesToDisplay;

// Windows api interface for playing sounds
Windows::WinApiInterface& windows;
};
} // namespace Releases
} // namespace UKControllerPlugin
1 change: 1 addition & 0 deletions src/releases/ReleaseModule.cpp
Expand Up @@ -145,6 +145,7 @@ namespace UKControllerPlugin {
*container.controllerPositions,
*container.activeCallsigns,
*container.dialogManager,
*container.windows,
departureReleaseRequestDialogTriggerFunctionId,
departureReleaseDecisionMenuTriggerFunctionId,
releaseDecisionCallbackId,
Expand Down
3 changes: 3 additions & 0 deletions test/test/releases/DepartureReleaseDecisionListTest.cpp
Expand Up @@ -16,6 +16,7 @@
#include "mock/MockUserSettingProviderInterface.h"
#include "releases/DepartureReleaseEventHandler.h"
#include "releases/DepartureReleaseRequest.h"
#include "mock/MockWinApi.h"

using testing::Test;

Expand All @@ -33,6 +34,7 @@ namespace UKControllerPluginTest {
controllers,
activeCallsigns,
dialogManager,
windows,
101,
102,
103,
Expand Down Expand Up @@ -95,6 +97,7 @@ namespace UKControllerPluginTest {
UKControllerPlugin::Controller::ActiveCallsignCollection activeCallsigns;
testing::NiceMock<Dialog::MockDialogProvider> dialogProvider;
testing::NiceMock<Api::MockApiInterface> api;
testing::NiceMock<Windows::MockWinApi> windows;
UKControllerPlugin::Dialog::DialogManager dialogManager;
UKControllerPlugin::Controller::ControllerPositionCollection controllers;
testing::NiceMock<Euroscope::MockEuroscopePluginLoopbackInterface> mockPlugin;
Expand Down

0 comments on commit dd594c2

Please sign in to comment.