REfactor SimDatabase PRODUCES CRASH ON EXIT

This commit is contained in:
Kilian Hofmann 2022-09-11 04:31:01 +02:00
parent 4445f1f12a
commit 161941ac1b
11 changed files with 207 additions and 140 deletions

View File

@ -21,6 +21,12 @@ namespace file
write<decltype(this->center)>(out, this->center); write<decltype(this->center)>(out, this->center);
write<decltype(this->radius)>(out, this->radius); write<decltype(this->radius)>(out, this->radius);
} }
bool Gate::contains(germanairlinesva::geodata::point coordinates) const
{
return germanairlinesva::geodata::distanceEarthP(this->center,
coordinates);
}
} // namespace simdata } // namespace simdata
} // namespace file } // namespace file
} // namespace germanairlinesva } // namespace germanairlinesva

View File

@ -24,9 +24,9 @@ namespace file
{ {
private: private:
std::uint32_t time; std::uint32_t time;
std::uint16_t altitude; std::uint16_t altitude = 0;
std::uint16_t groundSpeed; std::uint16_t groundSpeed = 0;
struct germanairlinesva::geodata::point coordinates; struct germanairlinesva::geodata::point coordinates{NAN, NAN};
public: public:
RecordingEntry() = default; RecordingEntry() = default;

View File

@ -43,6 +43,7 @@ namespace file
std::uint8_t radius); std::uint8_t radius);
void toFile(std::ofstream &out) const; void toFile(std::ofstream &out) const;
bool contains(germanairlinesva::geodata::point coordinates) const;
inline const std::string to_string() const inline const std::string to_string() const
{ {

View File

@ -0,0 +1,61 @@
#ifndef GERMANAIRLINESVA_FILE_SIMDATABASE_H
#define GERMANAIRLINESVA_FILE_SIMDATABASE_H
#include <cstdint>
#include <fstream>
#include <map>
#include <utility>
#include <vector>
#include "geodata.hpp"
#include "helpers.hpp"
#include "simdata/gate.h"
#include "simdata/runway.h"
namespace germanairlinesva
{
namespace file
{
namespace simdata
{
class SimDatabase
{
private:
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
airports;
public:
void toFile(std::ofstream &out) const;
const Gate *checkGate(
const std::string icao,
const struct germanairlinesva::geodata::point coordinates) const;
inline std::size_t numAirports() const { return this->airports.size(); }
inline const std::pair<std::vector<Gate>, std::vector<Runway>> &
getAirport(std::string icao) const
{
return this->airports.at(icao);
}
inline void addAirport(std::string icao,
std::vector<Gate> &gates,
std::vector<Runway> &runways)
{
this->airports[icao] = std::make_pair(gates, runways);
}
template <class... Args>
inline void addGate(std::string icao, Args &&...args)
{
this->airports[icao].first.emplace_back(std::forward<Args>(args)...);
}
template <class... Args>
inline void addRunway(std::string icao, Args &&...args)
{
this->airports[icao].second.emplace_back(std::forward<Args>(args)...);
}
};
} // namespace simdata
} // namespace file
} // namespace germanairlinesva
#endif

View File

@ -7,6 +7,7 @@
#include "simdata/gate.h" #include "simdata/gate.h"
#include "simdata/runway.h" #include "simdata/runway.h"
#include "simdata/simDatabase.h"
#include "util.hpp" #include "util.hpp"
namespace germanairlinesva namespace germanairlinesva
@ -15,19 +16,15 @@ namespace file
{ {
namespace simdata namespace simdata
{ {
int scan( int scan(const std::string defaultFile,
const std::string defaultFile, const std::string sceneryPack,
const std::string sceneryPack, const std::string logFile,
const std::string logFile, SimDatabase &airports);
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
&airports);
void makeAirport( void makeAirport(const std::string &kind,
const std::string &kind, std::ifstream &infile,
std::ifstream &infile, SimDatabase &airports,
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>> std::ofstream &logfile);
&airports,
std::ofstream &logfile);
void makeGate15(std::vector<Gate> &gates, void makeGate15(std::vector<Gate> &gates,
const std::vector<std::string> &fields); const std::vector<std::string> &fields);
void makeRunway(std::vector<Runway> &runways, void makeRunway(std::vector<Runway> &runways,

View File

@ -11,6 +11,7 @@
#include "simdata/gate.h" #include "simdata/gate.h"
#include "simdata/runway.h" #include "simdata/runway.h"
#include "simdata/simDatabase.h"
/* /*
* Header * Header
@ -33,92 +34,41 @@ namespace file
{ {
namespace simdata namespace simdata
{ {
static inline void toFile( static inline void toFile(const SimDatabase &database,
std::map< const std::string &file)
std::string,
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
std::vector<germanairlinesva::file::simdata::Runway>>>
&airports,
const std::string &file)
{ {
std::uint8_t null = 0;
std::ofstream out(file, std::fstream::binary); std::ofstream out(file, std::fstream::binary);
// File Header, Last member is version // File Header, Last member is version
std::uint8_t header[] = {'V', 'G', 'A', 'S', '\0', 1}; std::uint8_t header[] = {'V', 'G', 'A', 'S', '\0', 1};
out.write(reinterpret_cast<const char *>(header), 6); out.write(reinterpret_cast<const char *>(header), 6);
// Num Airports
std::uint16_t numAirports = airports.size(); database.toFile(out);
out.write(reinterpret_cast<const char *>(&numAirports),
sizeof(numAirports));
// Airport
for (const std::pair<
const std::string,
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
std::vector<germanairlinesva::file::simdata::Runway>>>
&airport : airports) {
std::string icao = airport.first;
std::vector<germanairlinesva::file::simdata::Gate> gates =
airport.second.first;
std::vector<germanairlinesva::file::simdata::Runway> runways =
airport.second.second;
// ICAO
std::uint8_t icaoLength = icao.length();
out.write(reinterpret_cast<const char *>(&icaoLength),
sizeof(icaoLength));
out.write(icao.c_str(), icaoLength);
out.write(reinterpret_cast<const char *>(&null), sizeof(null));
// Gates
std::uint16_t numGates = gates.size();
out.write(reinterpret_cast<const char *>(&numGates), sizeof(numGates));
for (germanairlinesva::file::simdata::Gate &gate : gates) {
gate.toFile(out);
}
// Runways
std::uint8_t numRunways = runways.size();
out.write(reinterpret_cast<const char *>(&numRunways),
sizeof(numRunways));
for (germanairlinesva::file::simdata::Runway &runway : runways) {
runway.toFile(out);
}
}
out.close(); out.close();
} }
static inline std::map< static inline const SimDatabase readVersion1(std::ifstream &in)
std::string,
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
std::vector<germanairlinesva::file::simdata::Runway>>>
readVersion1(std::ifstream &in)
{ {
std::map<std::string, SimDatabase database;
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
std::vector<germanairlinesva::file::simdata::Runway>>>
airports;
std::uint16_t numAirports; std::uint16_t numAirports = read<std::uint16_t>(in);
in.read(reinterpret_cast<char *>(&numAirports), sizeof(numAirports));
for (int i = 0; i < numAirports; i++) { for (int i = 0; i < numAirports; i++) {
// ICAO // ICAO
std::uint8_t icaoLength; std::string icao = readString(in);
in.read(reinterpret_cast<char *>(&icaoLength), sizeof(icaoLength));
char *icao = static_cast<char *>(calloc(icaoLength + 1, sizeof(char)));
in.read(icao, icaoLength + 1);
// Gates // Gates
std::uint16_t numGates; std::uint16_t numGates = read<std::uint16_t>(in);
in.read(reinterpret_cast<char *>(&numGates), sizeof(numGates));
for (int j = 0; j < numGates; j++) { for (int j = 0; j < numGates; j++) {
std::string designator = readString(in); std::string designator = readString(in);
struct germanairlinesva::geodata::point center = struct germanairlinesva::geodata::point center =
read<struct germanairlinesva::geodata::point>(in); read<struct germanairlinesva::geodata::point>(in);
std::uint8_t radius = read<std::uint8_t>(in); std::uint8_t radius = read<std::uint8_t>(in);
airports[icao].first.emplace_back(designator, center, radius); database.addGate(icao, designator, center, radius);
} }
// Runways // Runways
std::uint8_t numRunways; std::uint8_t numRunways = read<std::uint8_t>(in);
in.read(reinterpret_cast<char *>(&numRunways), sizeof(numRunways));
for (int j = 0; j < numRunways; j++) { for (int j = 0; j < numRunways; j++) {
std::string designator = readString(in); std::string designator = readString(in);
// Bounds // Bounds
@ -128,29 +78,18 @@ namespace file
std::uint16_t length = read<std::uint16_t>(in); std::uint16_t length = read<std::uint16_t>(in);
std::uint16_t trueHeading = read<std::uint16_t>(in); std::uint16_t trueHeading = read<std::uint16_t>(in);
airports[icao].second.emplace_back(designator, database
bounds, .addRunway(icao, designator, bounds, width, length, trueHeading);
width,
length,
trueHeading);
} }
} }
in.close(); in.close();
return airports; return database;
} }
static inline std::map< static inline const SimDatabase fromFile(const std::string &file)
std::string,
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
std::vector<germanairlinesva::file::simdata::Runway>>>
fromFile(const std::string &file)
{ {
std::map<std::string,
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
std::vector<germanairlinesva::file::simdata::Runway>>>
airports;
std::ifstream in(file, std::ifstream::binary); std::ifstream in(file, std::ifstream::binary);
// File Header // File Header
@ -159,13 +98,14 @@ namespace file
if (strcmp(ident, "VGAS") != 0) { if (strcmp(ident, "VGAS") != 0) {
throw std::invalid_argument("Wrong file"); throw std::invalid_argument("Wrong file");
} }
std::uint8_t version; std::uint8_t version = read<std::uint8_t>(in);
in.read(reinterpret_cast<char *>(&version), 1);
if (version == 1) { if (version == 1) {
return readVersion1(in); return readVersion1(in);
} }
return airports;
in.close();
return SimDatabase();
} }
} // namespace simdata } // namespace simdata
} // namespace file } // namespace file

39
file/simDatabase.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "simdata/simDatabase.h"
namespace germanairlinesva
{
namespace file
{
namespace simdata
{
void SimDatabase::toFile(std::ofstream &out) const
{
write<std::uint16_t>(out, this->airports.size());
for (const auto &airport : this->airports) {
writeString(out, airport.first);
write<std::uint16_t>(out, airport.second.first.size());
for (const Gate &gate : airport.second.first) {
gate.toFile(out);
}
write<std::uint8_t>(out, airport.second.second.size());
for (const Runway &runway : airport.second.second) {
runway.toFile(out);
}
}
}
const Gate *SimDatabase::checkGate(
const std::string icao,
const struct germanairlinesva::geodata::point coordinates) const
{
auto airport = this->getAirport(icao);
for (const Gate &gate : airport.first) {
if (gate.contains(coordinates)) {
return &gate;
}
}
return nullptr;
}
} // namespace simdata
} // namespace file
} // namespace germanairlinesva

View File

@ -6,12 +6,10 @@ namespace file
{ {
namespace simdata namespace simdata
{ {
int scan( int scan(const std::string defaultFile,
const std::string defaultFile, const std::string sceneryPack,
const std::string sceneryPack, const std::string logFile,
const std::string logFile, SimDatabase &database)
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>>
&airports)
{ {
std::ifstream base(defaultFile); std::ifstream base(defaultFile);
if (!base.good()) { if (!base.good()) {
@ -31,7 +29,7 @@ namespace file
// Default // Default
logfile << "<FILE> " << defaultFile << std::endl; logfile << "<FILE> " << defaultFile << std::endl;
makeAirport("DEFAULT", base, airports, logfile); makeAirport("DEFAULT", base, database, logfile);
base.close(); base.close();
std::string line; std::string line;
@ -51,7 +49,7 @@ namespace file
std::ifstream pack(path); std::ifstream pack(path);
if (pack.good()) { if (pack.good()) {
logfile << "<FILE> " << path << std::endl; logfile << "<FILE> " << path << std::endl;
makeAirport("CUSTOM", pack, airports, logfile); makeAirport("CUSTOM", pack, database, logfile);
pack.close(); pack.close();
} else { } else {
pack.close(); pack.close();
@ -61,19 +59,18 @@ namespace file
} }
logfile << std::endl logfile << std::endl
<< "<STATUS> Total airports: " << airports.size() << std::endl; << "<STATUS> Total airports: " << database.numAirports()
<< std::endl;
custom.close(); custom.close();
logfile.close(); logfile.close();
return 0; return 0;
} }
void makeAirport( void makeAirport(const std::string &kind,
const std::string &kind, std::ifstream &infile,
std::ifstream &infile, SimDatabase &database,
std::map<std::string, std::pair<std::vector<Gate>, std::vector<Runway>>> std::ofstream &logfile)
&airports,
std::ofstream &logfile)
{ {
std::string line; std::string line;
std::string *currentIcao = nullptr; std::string *currentIcao = nullptr;
@ -96,7 +93,7 @@ namespace file
// Write to file if ICAO is valid, and we have gates and runways // Write to file if ICAO is valid, and we have gates and runways
if (currentIcao != nullptr && !tmpRunways.empty() && if (currentIcao != nullptr && !tmpRunways.empty() &&
!tmpGates.empty()) { !tmpGates.empty()) {
airports[*currentIcao] = {tmpGates, tmpRunways}; database.addAirport(*currentIcao, tmpGates, tmpRunways);
validCount += 1; validCount += 1;
logfile << "\t<STATUS> " << *currentIcao << " committed" logfile << "\t<STATUS> " << *currentIcao << " committed"
<< std::endl; << std::endl;
@ -116,7 +113,7 @@ namespace file
// Write to file if ICAO is valid, and we have gates and runways // Write to file if ICAO is valid, and we have gates and runways
if (currentIcao != nullptr && !tmpRunways.empty() && if (currentIcao != nullptr && !tmpRunways.empty() &&
!tmpGates.empty()) { !tmpGates.empty()) {
airports[*currentIcao] = {tmpGates, tmpRunways}; database.addAirport(*currentIcao, tmpGates, tmpRunways);
validCount += 1; validCount += 1;
logfile << "\t<STATUS> " << *currentIcao << " committed" logfile << "\t<STATUS> " << *currentIcao << " committed"
<< std::endl; << std::endl;
@ -138,7 +135,7 @@ namespace file
} }
if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) { if (currentIcao != nullptr && !tmpRunways.empty() && !tmpGates.empty()) {
airports[*currentIcao] = {tmpGates, tmpRunways}; database.addAirport(*currentIcao, tmpGates, tmpRunways);
validCount += 1; validCount += 1;
logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl; logfile << "\t<STATUS> " << *currentIcao << " committed" << std::endl;
} }

View File

@ -77,6 +77,19 @@ namespace geodata
return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v)); return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
} }
// Input in degrees, Output in metres
static inline double distanceEarthP(point from, point to)
{
double lat1r, lon1r, lat2r, lon2r, u, v;
lat1r = toRadians(from.latitude);
lon1r = toRadians(from.longitude);
lat2r = toRadians(to.latitude);
lon2r = toRadians(to.longitude);
u = sin((lat2r - lat1r) / 2);
v = sin((lon2r - lon1r) / 2);
return 2.0 * EARTH_M * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
}
// Input and Output in degrees // Input and Output in degrees
static inline struct point calculatePointDD(struct point coordinates, static inline struct point calculatePointDD(struct point coordinates,
double bearing, double bearing,

View File

@ -49,7 +49,7 @@ void Websocket::onClientMessageCallback(const ix::WebSocketMessagePtr &msg)
this->webSocket->send("MASTER:" + user); this->webSocket->send("MASTER:" + user);
this->toLog("Connecting as " + user); this->toLog("Connecting as " + user);
} else if (msg->type == ix::WebSocketMessageType::Close) { } else if (msg->type == ix::WebSocketMessageType::Close) {
if (msg->closeInfo.reason.compare("DUPLICATE")) { if (msg->closeInfo.reason.compare("DUPLICATE") == 0) {
this->webSocket->disableAutomaticReconnection(); this->webSocket->disableAutomaticReconnection();
this->toLog("Disconnected due to beeing a duplicate simualtor"); this->toLog("Disconnected due to beeing a duplicate simualtor");

View File

@ -11,10 +11,7 @@ std::thread recordingThread;
std::atomic<bool> wantsExit; std::atomic<bool> wantsExit;
germanairlinesva::file::config::Config configuration; germanairlinesva::file::config::Config configuration;
std::map<std::string, germanairlinesva::file::simdata::SimDatabase database;
std::pair<std::vector<germanairlinesva::file::simdata::Gate>,
std::vector<germanairlinesva::file::simdata::Runway>>>
airports;
germanairlinesva_websocket::Websocket *connector; germanairlinesva_websocket::Websocket *connector;
int xplaneVersion; int xplaneVersion;
@ -116,18 +113,18 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
configuration = germanairlinesva::file::config::Config(); configuration = germanairlinesva::file::config::Config();
toLog("Config loaded"); toLog("Config loaded");
/*
try { try {
connector = new germanairlinesva_websocket::Websocket( connector = new germanairlinesva_websocket::Websocket(
"wss://ws.hofmannnet.myhome-server.de:8000", "wss://ws.hofmannnet.myhome-server.de:8000",
configuration.getUser(), configuration.getUser(),
toLog); toLog);
} catch (const std::invalid_argument &e) { } catch (const std::invalid_argument &e) {
toLog(e.what()); toLog(e.what());
return 0; return 0;
} }
toLog("WebSocket started"); toLog("WebSocket started");
*/
char hash[2 * MD5LEN + 1] = ""; char hash[2 * MD5LEN + 1] = "";
if (germanairlinesva::util::generateMD5(XPLANE_CUSTOM_SCENERY, hash, toLog) == if (germanairlinesva::util::generateMD5(XPLANE_CUSTOM_SCENERY, hash, toLog) ==
0) { 0) {
@ -139,32 +136,42 @@ PLUGIN_API int XPluginStart(char *outName, char *outSig, char *outDesc)
: XPLANE12_BASE_SCENERY, : XPLANE12_BASE_SCENERY,
XPLANE_CUSTOM_SCENERY, XPLANE_CUSTOM_SCENERY,
XPLANE_PLUGIN_DIRECTORY "log.txt", XPLANE_PLUGIN_DIRECTORY "log.txt",
airports); database);
germanairlinesva::file::simdata::toFile( germanairlinesva::file::simdata::toFile(
airports, database,
XPLANE_PLUGIN_DIRECTORY SIMDATABASE); XPLANE_PLUGIN_DIRECTORY SIMDATABASE);
configuration.updateScenery(hash); configuration.updateScenery(hash);
toLog("Sim Database updated"); toLog("Sim Database updated");
} else { } else {
airports = germanairlinesva::file::simdata::fromFile( database = germanairlinesva::file::simdata::fromFile(
XPLANE_PLUGIN_DIRECTORY SIMDATABASE); XPLANE_PLUGIN_DIRECTORY SIMDATABASE);
toLog("Sim Database loaded"); toLog("Sim Database loaded");
} }
toLog("Binary readback test");
germanairlinesva::file::simdata::toFile(database,
XPLANE_PLUGIN_DIRECTORY "sim2.bin");
toLog("Readback test of sim database using EDDF"); toLog("Readback test of sim database using EDDF");
auto ap = airports["EDDF"]; auto ap = database.getAirport("EDDF");
for (const auto &it : ap.first) { for (const auto &it : ap.first) {
toLog(" " + it.to_string()); toLog(" " + it.to_string());
} }
for (const auto &it : ap.second) { for (const auto &it : ap.second) {
toLog(" " + it.to_string()); toLog(" " + it.to_string());
} }
toLog("Readback test of sim database using XXXX");
try {
ap = database.getAirport("XXXX");
toLog(" Return was non null ! ERROR");
} catch (std::out_of_range) {
toLog(" Return was null");
}
} }
// Thread for sending data to websocket // Thread for sending data to websocket
serverThread = std::thread(&serverWorker); // serverThread = std::thread(&serverWorker);
recordingThread = std::thread(&recordingWorker); // recordingThread = std::thread(&recordingWorker);
toLog("Workers started"); toLog("Workers started");
toLog("Logbook Test"); toLog("Logbook Test");
@ -209,11 +216,13 @@ PLUGIN_API void XPluginStop(void)
XPLMUnregisterFlightLoopCallback(flightLoop, nullptr); XPLMUnregisterFlightLoopCallback(flightLoop, nullptr);
/* End threads */ /* End threads */
wantsExit = true; wantsExit = true;
delete connector; // serverThread.join();
serverThread.join(); // recordingThread.join();
recordingThread.join(); // delete connector;
p.toFile("flight.rec"); p.toFile("flight.rec");
toLog("Plugin stopped");
} }
PLUGIN_API void XPluginDisable(void) {} PLUGIN_API void XPluginDisable(void) {}
@ -286,6 +295,8 @@ void serverWorker()
std::this_thread::sleep_for(std::chrono::milliseconds(250)); std::this_thread::sleep_for(std::chrono::milliseconds(250));
} }
toLog("Server thread stopped");
} }
void recordingWorker() void recordingWorker()
@ -318,6 +329,8 @@ void recordingWorker()
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::this_thread::sleep_for(std::chrono::milliseconds(1000));
} }
toLog("Recording thread stopped");
} }
void toLog(const std::string &message) void toLog(const std::string &message)