allow to add flights as forced for AMAN to include them, if the neighboring controller is not using AMAN
This commit is contained in:
@@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
@@ -50,9 +53,8 @@ PlugIn::PlugIn() :
|
|||||||
m_screen(),
|
m_screen(),
|
||||||
m_updateQueueLock(),
|
m_updateQueueLock(),
|
||||||
m_updateQueue(),
|
m_updateQueue(),
|
||||||
m_compatible(false),
|
m_forcedToBackendCallsigns(),
|
||||||
m_airportsLock(),
|
m_compatible(false) {
|
||||||
m_airports() {
|
|
||||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||||
|
|
||||||
this->DisplayUserMessage(PLUGIN_NAME, "INFO", (std::string("Loaded ") + PLUGIN_NAME + " " + PLUGIN_VERSION).c_str(), true, true, false, false, false);
|
this->DisplayUserMessage(PLUGIN_NAME, "INFO", (std::string("Loaded ") + PLUGIN_NAME + " " + PLUGIN_VERSION).c_str(), true, true, false, false, false);
|
||||||
@@ -114,8 +116,6 @@ void PlugIn::validateBackendData() {
|
|||||||
__receivedAmanData.clear();
|
__receivedAmanData.clear();
|
||||||
|
|
||||||
result = curl_easy_perform(curl);
|
result = curl_easy_perform(curl);
|
||||||
std::lock_guard guard(this->m_airportsLock);
|
|
||||||
this->m_airports.clear();
|
|
||||||
this->m_compatible = false;
|
this->m_compatible = false;
|
||||||
|
|
||||||
if (CURLE_OK != result) {
|
if (CURLE_OK != result) {
|
||||||
@@ -142,7 +142,7 @@ void PlugIn::validateBackendData() {
|
|||||||
auto airportArray = *it;
|
auto airportArray = *it;
|
||||||
|
|
||||||
airports.reserve(airportArray.size());
|
airports.reserve(airportArray.size());
|
||||||
for (auto i = 0; i < airportArray.size(); ++i)
|
for (Json::Value::ArrayIndex i = 0; i < airportArray.size(); ++i)
|
||||||
airports.push_back(airportArray[i].asString());
|
airports.push_back(airportArray[i].asString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,10 @@ void PlugIn::validateBackendData() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->m_airports = airports;
|
std::lock_guard guard(this->m_updateQueueLock);
|
||||||
|
this->m_updateQueue.clear();
|
||||||
|
for (const auto& airport : std::as_const(airports))
|
||||||
|
this->m_updateQueue.insert({ airport, {} });
|
||||||
this->m_compatible = true;
|
this->m_compatible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,15 +357,67 @@ void PlugIn::generateAircraftReportMessage(const EuroScopePlugIn::CRadarTarget&
|
|||||||
report->set_reporttime(String::splitString(stream.str(), ".")[0]);
|
report->set_reporttime(String::splitString(stream.str(), ".")[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PlugIn::OnFunctionCall(int functionId, const char* itemString, POINT pt, RECT area) {
|
||||||
|
std::ignore = itemString;
|
||||||
|
std::ignore = pt;
|
||||||
|
std::ignore = area;
|
||||||
|
|
||||||
|
auto radarTarget = this->RadarTargetSelectASEL();
|
||||||
|
if (false == radarTarget.IsValid() || false == radarTarget.GetCorrelatedFlightPlan().IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string callsign(radarTarget.GetCallsign());
|
||||||
|
|
||||||
|
switch (static_cast<PlugIn::TagItemFunction>(functionId)) {
|
||||||
|
case PlugIn::TagItemFunction::ForceToBackend:
|
||||||
|
{
|
||||||
|
std::string destination(radarTarget.GetCorrelatedFlightPlan().GetFlightPlanData().GetDestination());
|
||||||
|
std::transform(destination.begin(), destination.end(), destination.begin(), ::toupper);
|
||||||
|
|
||||||
|
std::lock_guard guard(this->m_updateQueueLock);
|
||||||
|
auto it = this->m_updateQueue.find(destination);
|
||||||
|
if (this->m_updateQueue.end() != it) {
|
||||||
|
auto cIt = std::find(this->m_forcedToBackendCallsigns.cbegin(), this->m_forcedToBackendCallsigns.cend(), callsign);
|
||||||
|
if (this->m_forcedToBackendCallsigns.cend() == cIt)
|
||||||
|
this->m_forcedToBackendCallsigns.push_back(callsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PlugIn::OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarget) {
|
void PlugIn::OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarget) {
|
||||||
/* do nothing if the reporter is not initialized and ignore invalid targets */
|
/* do nothing if the reporter is not initialized and ignore invalid targets */
|
||||||
if (false == this->m_compatible || false == Backend::instance().initialized() || false == radarTarget.IsValid())
|
if (false == this->m_compatible || false == Backend::instance().initialized() || false == radarTarget.IsValid())
|
||||||
return;
|
return;
|
||||||
if (false == radarTarget.GetCorrelatedFlightPlan().GetTrackingControllerIsMe())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::lock_guard guard(this->m_updateQueueLock);
|
std::lock_guard guard(this->m_updateQueueLock);
|
||||||
this->m_updateQueue.push_back(radarTarget.GetCallsign());
|
|
||||||
|
auto forcedIt = std::find(this->m_forcedToBackendCallsigns.cbegin(), this->m_forcedToBackendCallsigns.cend(), radarTarget.GetCallsign());
|
||||||
|
if (false == radarTarget.GetCorrelatedFlightPlan().GetTrackingControllerIsMe() && this->m_forcedToBackendCallsigns.cend() == forcedIt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string destination(radarTarget.GetCorrelatedFlightPlan().GetFlightPlanData().GetDestination());
|
||||||
|
#pragma warning(disable: 4244)
|
||||||
|
std::transform(destination.begin(), destination.end(), destination.begin(), ::toupper);
|
||||||
|
#pragma warning(default: 4244)
|
||||||
|
|
||||||
|
auto it = this->m_updateQueue.find(destination);
|
||||||
|
if (this->m_updateQueue.end() != it)
|
||||||
|
it->second.push_back(radarTarget.GetCallsign());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlugIn::OnFlightPlanDisconnect(EuroScopePlugIn::CFlightPlan flightPlan) {
|
||||||
|
std::string callsign(flightPlan.GetCorrelatedRadarTarget().GetCallsign());
|
||||||
|
std::lock_guard guard(this->m_updateQueueLock);
|
||||||
|
|
||||||
|
auto it = std::find(this->m_forcedToBackendCallsigns.begin(), this->m_forcedToBackendCallsigns.end(), callsign);
|
||||||
|
if (this->m_forcedToBackendCallsigns.end() != it)
|
||||||
|
this->m_forcedToBackendCallsigns.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlugIn::OnTimer(int counter) {
|
void PlugIn::OnTimer(int counter) {
|
||||||
@@ -370,22 +425,28 @@ void PlugIn::OnTimer(int counter) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this->m_updateQueueLock.lock();
|
this->m_updateQueueLock.lock();
|
||||||
|
|
||||||
|
for (auto& airport : this->m_updateQueue) {
|
||||||
aman::AircraftUpdate update;
|
aman::AircraftUpdate update;
|
||||||
bool inserted = false;
|
bool inserted = false;
|
||||||
|
|
||||||
for (auto target = this->RadarTargetSelectFirst(); true == target.IsValid(); target = this->RadarTargetSelectNext(target)) {
|
for (auto target = this->RadarTargetSelectFirst(); true == target.IsValid(); target = this->RadarTargetSelectNext(target)) {
|
||||||
auto it = std::find(this->m_updateQueue.cbegin(), this->m_updateQueue.cend(), target.GetCallsign());
|
auto it = std::find(airport.second.begin(), airport.second.end(), target.GetCallsign());
|
||||||
if (this->m_updateQueue.cend() != it) {
|
if (airport.second.end() != it) {
|
||||||
auto report = update.add_reports();
|
auto report = update.add_reports();
|
||||||
this->generateAircraftReportMessage(target, report);
|
this->generateAircraftReportMessage(target, report);
|
||||||
inserted = true;
|
inserted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send the report */
|
||||||
|
auto sequence = Backend::instance().update(update);
|
||||||
|
if (true == inserted && nullptr != sequence)
|
||||||
|
this->DisplayUserMessage(PLUGIN_NAME, "ERROR", "Unable to send a new aircraft report update", true, true, true, true, true);
|
||||||
|
|
||||||
|
airport.second.clear();
|
||||||
|
}
|
||||||
|
|
||||||
this->m_updateQueue.clear();
|
this->m_updateQueue.clear();
|
||||||
this->m_updateQueueLock.unlock();
|
this->m_updateQueueLock.unlock();
|
||||||
|
|
||||||
/* send the report */
|
|
||||||
if (true == inserted && nullptr != Backend::instance().update(update))
|
|
||||||
this->DisplayUserMessage(PLUGIN_NAME, "ERROR", "Unable to send a new aircraft report update", true, true, true, true, true);
|
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/PlugIn.h
19
src/PlugIn.h
@@ -35,6 +35,7 @@ namespace aman {
|
|||||||
* @brief Defines the different internal and external tag functions
|
* @brief Defines the different internal and external tag functions
|
||||||
*/
|
*/
|
||||||
enum class TagItemFunction {
|
enum class TagItemFunction {
|
||||||
|
ForceToBackend = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -48,10 +49,9 @@ namespace aman {
|
|||||||
Communication m_configuration;
|
Communication m_configuration;
|
||||||
std::shared_ptr<RadarScreen> m_screen;
|
std::shared_ptr<RadarScreen> m_screen;
|
||||||
std::mutex m_updateQueueLock;
|
std::mutex m_updateQueueLock;
|
||||||
std::list<std::string> m_updateQueue;
|
std::map<std::string, std::list<std::string>> m_updateQueue;
|
||||||
|
std::list<std::string> m_forcedToBackendCallsigns;
|
||||||
bool m_compatible;
|
bool m_compatible;
|
||||||
std::mutex m_airportsLock;
|
|
||||||
std::vector<std::string> m_airports;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -79,6 +79,14 @@ namespace aman {
|
|||||||
*/
|
*/
|
||||||
EuroScopePlugIn::CRadarScreen* OnRadarScreenCreated(const char* displayName, bool needsRadarContent, bool geoReferenced,
|
EuroScopePlugIn::CRadarScreen* OnRadarScreenCreated(const char* displayName, bool needsRadarContent, bool geoReferenced,
|
||||||
bool canBeSaved, bool canBeCreated) override;
|
bool canBeSaved, bool canBeCreated) override;
|
||||||
|
/**
|
||||||
|
* @brief Called as soon as a function is triggered
|
||||||
|
* @param[in] functionId The triggered ID
|
||||||
|
* @param[in] itemString The content of the message
|
||||||
|
* @param[in] pt The click position
|
||||||
|
* @param[in] area The clicked area
|
||||||
|
*/
|
||||||
|
void OnFunctionCall(int functionId, const char* itemString, POINT pt, RECT area) override;
|
||||||
/**
|
/**
|
||||||
* @brief Called every second
|
* @brief Called every second
|
||||||
* @param[in] counter The counter that indicates the seconds
|
* @param[in] counter The counter that indicates the seconds
|
||||||
@@ -89,5 +97,10 @@ namespace aman {
|
|||||||
* @param[in] radarTarget The updated radar target
|
* @param[in] radarTarget The updated radar target
|
||||||
*/
|
*/
|
||||||
void OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarget) override;
|
void OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarget) override;
|
||||||
|
/**
|
||||||
|
* @brief Called as soon as a flight plan is offline
|
||||||
|
* @param[in] flightPlan The disconnected flight plan
|
||||||
|
*/
|
||||||
|
void OnFlightPlanDisconnect(EuroScopePlugIn::CFlightPlan flightPlan) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user