195 lines
5.5 KiB
C++

#include "include/recorder.h"
namespace germanairlinesva
{
namespace gaconnector
{
namespace recorder
{
Recorder::Recorder(int simVersion,
std::function<void(const std::string)> toLog)
: toLog(std::move(toLog))
{
// Configuration
this->configuration = std::make_shared<file::config::Config>();
this->toLog("Configuration loaded");
// Database
#ifdef XP
char hash[2 * MD5LEN + 1] = "";
if (utilities::generateMD5(XPLANE_CUSTOM_SCENERY, hash, this->toLog) ==
0) {
this->database =
std::make_unique<file::simdata::SimDatabase>(simVersion,
hash,
this->configuration,
this->toLog);
}
#endif
// WebSocket
this->connector =
std::make_unique<websocket::Websocket>(WEBSOCKET_ADDRESS,
this->configuration->getUser(),
this->toLog);
this->toLog("WebSocket started");
// For Testing
#ifdef XP
this->test();
#endif
// Thread for sending data to websocket
this->serverThread = std::thread(&Recorder::serverWorker, this);
this->recordingThread = std::thread(&Recorder::recordingWorker, this);
this->toLog("Workers started");
}
Recorder::~Recorder()
{
wantsExit = true;
serverThread.join();
recordingThread.join();
}
void Recorder::setData(websocket::data &data)
{
const std::lock_guard<std::mutex> lock(mutex);
std::memcpy(&this->toSend, &data, sizeof(websocket::data));
}
void Recorder::handleMessages()
{
const std::lock_guard<std::mutex> lock(mutex);
if (!messageQueue().empty()) {
auto op = std::move(messageQueue().front());
messageQueue().pop();
op();
}
}
std::shared_ptr<file::config::Config> Recorder::getConfiguration() const
{
return this->configuration;
}
void Recorder::loadDatabase(int simVersion)
{
if (simVersion == MSFS_VERSION) {
return;
}
#if defined(IBM) && not defined(XP)
this->toLog("Loading database for " +
SimConnect::resolveVersion(simVersion));
PWSTR folder;
HRESULT result = SHGetKnownFolderPath(FOLDERID_RoamingAppData,
KF_FLAG_DEFAULT,
NULL,
&folder);
if (SUCCEEDED(result)) {
size_t origsize = wcslen(folder) + 1;
size_t convertedChars = 0;
char *nstring = new char[origsize * 2];
wcstombs_s(&convertedChars, nstring, origsize * 2, folder, _TRUNCATE);
std::string path(nstring);
path.append(SimConnect::resolveScenery(simVersion));
this->toLog(path);
delete[] nstring;
CoTaskMemFree(folder);
char hash[2 * MD5LEN + 1] = "";
if (utilities::generateMD5(path.c_str(), hash, toLog) == 0) {
database =
std::make_unique<file::simdata::SimDatabase>(simVersion,
hash,
this->configuration,
this->toLog);
}
this->test();
}
#endif
}
void Recorder::serverWorker()
{
utilities::setThreadName("GAServerWorker");
while (!wantsExit) {
struct websocket::data copy;
{
const std::lock_guard<std::mutex> lock(mutex);
std::memcpy(&copy, &toSend, sizeof(websocket::data));
}
connector->sendData(copy);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}
toLog("Server thread stopped");
}
void Recorder::recordingWorker()
{
utilities::setThreadName("GARecordingWorker");
file::recording::Recording path;
file::recording::RecordingEntry lastPath;
std::uint32_t segment = 0;
while (!wantsExit) {
struct websocket::data copy;
{
const std::lock_guard<std::mutex> lock(mutex);
std::memcpy(&copy, &toSend, sizeof(websocket::data));
}
file::recording::RecordingEntry currentPath(
segment,
static_cast<std::uint16_t>(copy.alt),
static_cast<std::uint16_t>(copy.gs),
{copy.lat, copy.lon});
if (strcmp(copy.path, "") != 0 && !copy.pause &&
lastPath != currentPath) {
path.addEntry(currentPath);
lastPath = currentPath;
}
segment++;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
path.toFile("flight.rec");
toLog("Recording thread stopped");
}
void Recorder::test() const
{
#ifndef MSFS
this->toLog("Readback test of sim database using EDDF");
auto ap = (*this->database)["EDDF"];
for (const auto &it : ap.first) {
this->toLog(" " + it.to_string());
}
for (const auto &it : ap.second) {
this->toLog(" " + it.to_string());
}
this->toLog("Readback test of sim database using XXXX");
auto ap2 = (*database)["XXXX"];
ap2.first.size() == 0 ? this->toLog(" SUCCESS") : this->toLog(" ERROR");
#endif
}
} // namespace recorder
} // namespace gaconnector
} // namespace germanairlinesva