Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.3.0 #43

Merged
merged 37 commits into from
Apr 16, 2024
Merged
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ea1285f
move src files for refactor
LeoKle Mar 18, 2024
41e80f3
add workflows
LeoKle Mar 18, 2024
77652be
init plugin for refactor
LeoKle Mar 18, 2024
f26d0ef
add types
LeoKle Mar 18, 2024
812c60b
add async Logger
LeoKle Mar 23, 2024
4f99d13
init DataManager
LeoKle Mar 23, 2024
8fca326
add utils
LeoKle Mar 23, 2024
1479ac9
handle OnAirportRunwayActivityChanged event
LeoKle Mar 23, 2024
d8f6c83
subscribe to flightplan data update events
LeoKle Mar 24, 2024
e619f18
init Server.cpp
LeoKle Mar 24, 2024
eef4d00
add backend pilot data fetching and consolidation
LeoKle Mar 24, 2024
482dde9
add pilot posting and patching
LeoKle Mar 24, 2024
72b33c6
add TagItemFunctions using asynchronous messages
LeoKle Mar 27, 2024
c332980
improve responsiveness of tag functions
LeoKle Mar 29, 2024
f22658f
fix TOBT entry string to time point conversion
LeoKle Mar 29, 2024
45cba63
add config parsing
LeoKle Mar 29, 2024
aa17c08
add TagItems
LeoKle Mar 29, 2024
6f8ce73
fix TOBT patch messages
LeoKle Mar 29, 2024
5be5f29
move handling of tag items and functions to separate file
LeoKle Mar 29, 2024
7f115db
add CompileCommands
LeoKle Mar 30, 2024
39c2b29
fix EXOT display and parsing
LeoKle Mar 30, 2024
69b01e5
only handle tag functions if client is master
LeoKle Mar 30, 2024
4613d27
add reset TagItem functions
LeoKle Mar 30, 2024
372a1fb
add update rate to config
LeoKle Mar 31, 2024
b57ac0f
add config file and to build & workflow releases
LeoKle Mar 31, 2024
1cb9fba
exclude sqlite3 from clang format
LeoKle Mar 31, 2024
a4dbbab
remove old src files
LeoKle Mar 31, 2024
594ffb7
set build-develop workflow to build config release
LeoKle Mar 31, 2024
0b7d2f2
set default URL to prod URL
LeoKle Apr 1, 2024
a4ee66c
fix temporary EXOT reset on EXOT update
LeoKle Apr 4, 2024
3c66599
fix AORT update sending AOBT update
LeoKle Apr 4, 2024
4e53922
v1.3.1
LeoKle Apr 5, 2024
cf672d8
set new prod URL
LeoKle Apr 8, 2024
1701450
amend workflow build and versioning
LeoKle Apr 6, 2024
c91928e
add compile commands for logging
LeoKle Apr 9, 2024
f4d1e8e
fix access violation error
LeoKle Apr 14, 2024
20d0e7a
set main release to create draft
LeoKle Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add TagItemFunctions using asynchronous messages
  • Loading branch information
LeoKle committed Mar 27, 2024
commit 72b33c63f90bec4ec6689025bca8ab339a859491
121 changes: 121 additions & 0 deletions src/core/DataManager.cpp
Original file line number Diff line number Diff line change
@@ -25,6 +25,18 @@ DataManager& DataManager::instance() {
return __instance;
}

bool DataManager::checkPilotExists(std::string& callsign) {
if (true == this->m_pause) return false;

std::lock_guard guard(this->m_pilotLock);
return this->m_pilots.cend() != this->m_pilots.find(callsign);
}

const types::Pilot DataManager::getPilot(const std::string& callsign) {
std::lock_guard guard(this->m_pilotLock);
return this->m_pilots.find(callsign)->second[ConsolidatedData];
}

void DataManager::run() {
std::size_t counter = 1;
while (true) {
@@ -40,6 +52,8 @@ void DataManager::run() {
auto pilots = this->m_pilots;
this->m_pilotLock.unlock();

this->processAsynchronousMessages(pilots);

this->processEuroScopeUpdates(pilots);

this->consolidateWithBackend(pilots);
@@ -69,6 +83,113 @@ void DataManager::run() {
}
}

void DataManager::processAsynchronousMessages(std::map<std::string, std::array<types::Pilot, 3U>>& pilots) {
this->m_asyncMessagesLock.lock();
auto messages = this->m_asynchronousMessages;
this->m_asynchronousMessages.clear();
this->m_asyncMessagesLock.unlock();

for (auto& message : messages) {
// find pilot in list
for (auto& [callsign, data] : pilots) {
if (callsign == message.callsign) {
Logger::instance().log(Logger::LogSender::DataManager, "Updated data of " + callsign,
Logger::LogLevel::Info);

switch (message.type) {
case MessageType::UpdateEXOT:
Server::instance().updateExot(message.callsign, message.value);

data[ConsolidatedData].exot = message.value;
data[ConsolidatedData].tsat = types::defaultTime;
data[ConsolidatedData].ttot = types::defaultTime;
data[ConsolidatedData].exot = types::defaultTime;
data[ConsolidatedData].asat = types::defaultTime;
data[ConsolidatedData].aobt = types::defaultTime;
data[ConsolidatedData].atot = types::defaultTime;

Logger::instance().log(
Logger::LogSender::DataManager,
"Updating EXOT: " + callsign + ", " + utils::Date::timestampToIsoString(message.value),
Logger::LogLevel::Info);
break;
case MessageType::UpdateTOBT: {
Server::instance().updateTobt(data[ConsolidatedData], message.value, false);

bool resetTsat = message.value >= data[ConsolidatedData].tsat;

data[EuroscopeData].lastUpdate = std::chrono::utc_clock::now();
data[ConsolidatedData].tobt = message.value;
if (true == resetTsat) data[ConsolidatedData].tsat = types::defaultTime;
data[ConsolidatedData].ttot = types::defaultTime;
data[ConsolidatedData].exot = types::defaultTime;
data[ConsolidatedData].asat = types::defaultTime;
data[ConsolidatedData].aobt = types::defaultTime;
data[ConsolidatedData].atot = types::defaultTime;

break;
}
case MessageType::UpdateTOBTConfirmed: {
Server::instance().updateTobt(data[ConsolidatedData], message.value, true);

bool resetTsat =
message.value == types::defaultTime || message.value >= data[ConsolidatedData].tsat;

data[EuroscopeData].lastUpdate = std::chrono::utc_clock::now();
data[ConsolidatedData].tobt = message.value;
if (true == resetTsat) data[ConsolidatedData].tsat = types::defaultTime;
data[ConsolidatedData].ttot = types::defaultTime;
data[ConsolidatedData].exot = types::defaultTime;
data[ConsolidatedData].asat = types::defaultTime;
data[ConsolidatedData].aobt = types::defaultTime;
data[ConsolidatedData].atot = types::defaultTime;

break;
}
case MessageType::UpdateASAT:
Server::instance().updateAsat(message.callsign, message.value);

data[EuroscopeData].lastUpdate = std::chrono::utc_clock::now();
data[ConsolidatedData].asat = message.value;

break;
case MessageType::UpdateASRT:
Server::instance().updateAsrt(message.callsign, message.value);

data[EuroscopeData].lastUpdate = std::chrono::utc_clock::now();
data[ConsolidatedData].asrt = message.value;

break;
case MessageType::UpdateAOBT:
Server::instance().updateAobt(message.callsign, message.value);

data[EuroscopeData].lastUpdate = std::chrono::utc_clock::now();
data[ConsolidatedData].aobt = message.value;

break;
case MessageType::UpdateAORT:
Server::instance().updateAobt(message.callsign, message.value);

data[EuroscopeData].lastUpdate = std::chrono::utc_clock::now();
data[ConsolidatedData].aobt = message.value;

break;
default:
break;
}

break;
}
}
}
}

void DataManager::queueAsynchronousMessage(MessageType type, const std::string callsign,
const std::chrono::utc_clock::time_point value) {
std::lock_guard guard(this->m_asyncMessagesLock);
this->m_asynchronousMessages.push_back({type, callsign, value});
}

DataManager::MessageType DataManager::deltaEuroscopeToBackend(const std::array<types::Pilot, 3>& data,
Json::Value& message) {
message.clear();
33 changes: 28 additions & 5 deletions src/core/DataManager.h
Original file line number Diff line number Diff line change
@@ -36,6 +36,19 @@ class DataManager {
DataManager &operator=(DataManager &&) = delete;
static DataManager &instance();

enum class MessageType {
None,
Post,
Patch,
UpdateEXOT,
UpdateTOBT,
UpdateTOBTConfirmed,
UpdateASAT,
UpdateASRT,
UpdateAOBT,
UpdateAORT,
};

private:
std::mutex m_pilotLock;
std::map<std::string, std::array<types::Pilot, 3>> m_pilots;
@@ -65,15 +78,25 @@ class DataManager {
/// @param pilot
void consolidateData(std::array<types::Pilot, 3> &pilot);

enum class MessageType {
None,
Post,
Patch,
};
MessageType deltaEuroscopeToBackend(const std::array<types::Pilot, 3> &data, Json::Value &message);

struct AsynchronousMessage {
const MessageType type;
const std::string callsign;
const std::chrono::utc_clock::time_point value;
};

std::mutex m_asyncMessagesLock;
std::list<struct AsynchronousMessage> m_asynchronousMessages;
void processAsynchronousMessages(std::map<std::string, std::array<types::Pilot, 3U>> &pilots);

public:
void setActiveAirports(const std::list<std::string> activeAirports);
void queueFlightplanUpdate(EuroScopePlugIn::CFlightPlan flightplan);
void queueAsynchronousMessage(MessageType message, const std::string callsign,
const std::chrono::utc_clock::time_point value);

bool checkPilotExists(std::string &callsign);
const types::Pilot getPilot(const std::string &callsign);
};
} // namespace vacdm::core
77 changes: 76 additions & 1 deletion src/core/Server.cpp
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ Server::Server()
m_apiIsChecked(false),
m_apiIsValid(false),
m_baseUrl("https://vacdm-dev.vatsim-germany.org"),
m_clientIsMaster(false),
m_clientIsMaster(true),
m_errorCode() {
/* configure the get request */
curl_easy_setopt(m_getRequest.socket, CURLOPT_SSL_VERIFYPEER, 0L);
@@ -372,6 +372,81 @@ void Server::postPilot(types::Pilot pilot) {
this->sendPostMessage("/api/v1/pilots", root);
}

void Server::updateExot(const std::string& callsign, const std::chrono::utc_clock::time_point& exot) {
Json::Value root;

root["callsign"] = callsign;
root["vacdm"] = Json::Value();
root["vacdm"]["exot"] = std::chrono::duration_cast<std::chrono::minutes>(exot.time_since_epoch()).count();
root["vacdm"]["tsat"] = utils::Date::timestampToIsoString(types::defaultTime);
root["vacdm"]["ttot"] = utils::Date::timestampToIsoString(types::defaultTime);
root["vacdm"]["asat"] = utils::Date::timestampToIsoString(types::defaultTime);
root["vacdm"]["aobt"] = utils::Date::timestampToIsoString(types::defaultTime);
root["vacdm"]["atot"] = utils::Date::timestampToIsoString(types::defaultTime);

this->sendPatchMessage("/api/v1/pilots/" + callsign, root);
}

void Server::updateTobt(const types::Pilot& pilot, const std::chrono::utc_clock::time_point& tobt, bool manualTobt) {
Json::Value root;

bool resetTsat = (tobt == types::defaultTime && true == manualTobt) || tobt >= pilot.tsat;
root["callsign"] = pilot.callsign;
root["vacdm"] = Json::Value();

root["vacdm"] = Json::Value();
root["vacdm"]["tobt"] = utils::Date::timestampToIsoString(pilot.tobt);
if (true == resetTsat) root["vacdm"]["tsat"] = utils::Date::timestampToIsoString(types::defaultTime);
if (false == manualTobt) root["vacdm"]["tobt_state"] = "CONFIRMED";

root["vacdm"]["ttot"] = utils::Date::timestampToIsoString(types::defaultTime);
root["vacdm"]["asat"] = utils::Date::timestampToIsoString(types::defaultTime);
root["vacdm"]["aobt"] = utils::Date::timestampToIsoString(types::defaultTime);
root["vacdm"]["atot"] = utils::Date::timestampToIsoString(types::defaultTime);

this->sendPatchMessage("/api/v1/pilots/" + pilot.callsign, root);
}

void Server::updateAsat(const std::string& callsign, const std::chrono::utc_clock::time_point& asat) {
Json::Value root;

root["callsign"] = callsign;
root["vacdm"] = Json::Value();
root["vacdm"]["asat"] = utils::Date::timestampToIsoString(asat);

this->sendPatchMessage("/api/v1/pilots/" + callsign, root);
}

void Server::updateAsrt(const std::string& callsign, const std::chrono::utc_clock::time_point& asrt) {
Json::Value root;

root["callsign"] = callsign;
root["vacdm"] = Json::Value();
root["vacdm"]["asrt"] = utils::Date::timestampToIsoString(asrt);

this->sendPatchMessage("/api/v1/pilots/" + callsign, root);
}

void Server::updateAobt(const std::string& callsign, const std::chrono::utc_clock::time_point& aobt) {
Json::Value root;

root["callsign"] = callsign;
root["vacdm"] = Json::Value();
root["vacdm"]["aobt"] = utils::Date::timestampToIsoString(aobt);

this->sendPatchMessage("/api/v1/pilots/" + callsign, root);
}

void Server::updateAort(const std::string& callsign, const std::chrono::utc_clock::time_point& aort) {
Json::Value root;

root["callsign"] = callsign;
root["vacdm"] = Json::Value();
root["vacdm"]["aort"] = utils::Date::timestampToIsoString(aort);

this->sendPatchMessage("/api/v1/pilots/" + callsign, root);
}

bool Server::getMaster() { return this->m_clientIsMaster; }

const std::string& Server::errorMessage() const { return this->m_errorCode; }
7 changes: 7 additions & 0 deletions src/core/Server.h
Original file line number Diff line number Diff line change
@@ -68,6 +68,13 @@ class Server {
/// @param root message content
void sendPatchMessage(const std::string& endpointUrl, const Json::Value& root);

void updateExot(const std::string& pilot, const std::chrono::utc_clock::time_point& exot);
void updateTobt(const types::Pilot& pilot, const std::chrono::utc_clock::time_point& tobt, bool manualTobt);
void updateAsat(const std::string& callsign, const std::chrono::utc_clock::time_point& asat);
void updateAsrt(const std::string& callsign, const std::chrono::utc_clock::time_point& asrt);
void updateAobt(const std::string& callsign, const std::chrono::utc_clock::time_point& aobt);
void updateAort(const std::string& callsign, const std::chrono::utc_clock::time_point& aort);

const std::string& errorMessage() const;
void setMaster(bool master);
bool getMaster();
9 changes: 9 additions & 0 deletions src/utils/Number.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <string>

namespace vacdm {
static __inline bool isNumber(const std::string& s) {
return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
}
} // namespace vacdm
Loading