mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-05 01:35:45 +08:00
[xswiftbus] Make xswiftbus completely Qt free
This commit is contained in:
@@ -97,8 +97,10 @@ namespace BlackSimPlugin
|
|||||||
m_slowTimer.setObjectName(this->objectName().append(":m_slowTimer"));
|
m_slowTimer.setObjectName(this->objectName().append(":m_slowTimer"));
|
||||||
connect(&m_fastTimer, &QTimer::timeout, this, &CSimulatorXPlane::fastTimerTimeout);
|
connect(&m_fastTimer, &QTimer::timeout, this, &CSimulatorXPlane::fastTimerTimeout);
|
||||||
connect(&m_slowTimer, &QTimer::timeout, this, &CSimulatorXPlane::slowTimerTimeout);
|
connect(&m_slowTimer, &QTimer::timeout, this, &CSimulatorXPlane::slowTimerTimeout);
|
||||||
|
connect(&m_airportUpdater, &QTimer::timeout, this, &CSimulatorXPlane::updateAirportsInRange);
|
||||||
m_fastTimer.start(100);
|
m_fastTimer.start(100);
|
||||||
m_slowTimer.start(1000);
|
m_slowTimer.start(1000);
|
||||||
|
m_airportUpdater.start(60000);
|
||||||
|
|
||||||
this->setDefaultModel({ "Jets A320_a A320_a_Austrian_Airlines A320_a_Austrian_Airlines", CAircraftModel::TypeModelMatchingDefaultModel,
|
this->setDefaultModel({ "Jets A320_a A320_a_Austrian_Airlines A320_a_Austrian_Airlines", CAircraftModel::TypeModelMatchingDefaultModel,
|
||||||
"A320 AUA", CAircraftIcaoCode("A320", "L2J")});
|
"A320 AUA", CAircraftIcaoCode("A320", "L2J")});
|
||||||
@@ -793,6 +795,11 @@ namespace BlackSimPlugin
|
|||||||
this->rememberElevationAndCG(callsign, elevation, CLength(modelVerticalOffsetMeters, CLengthUnit::m()));
|
this->rememberElevationAndCG(callsign, elevation, CLength(modelVerticalOffsetMeters, CLengthUnit::m()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSimulatorXPlane::updateAirportsInRange()
|
||||||
|
{
|
||||||
|
if (this->isConnected()) { m_serviceProxy->updateAirportsInRange(); }
|
||||||
|
}
|
||||||
|
|
||||||
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,
|
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,
|
||||||
IOwnAircraftProvider *ownAircraftProvider,
|
IOwnAircraftProvider *ownAircraftProvider,
|
||||||
IRemoteAircraftProvider *remoteAircraftProvider,
|
IRemoteAircraftProvider *remoteAircraftProvider,
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ namespace BlackSimPlugin
|
|||||||
|
|
||||||
void requestRemoteAircraftDataFromXPlane();
|
void requestRemoteAircraftDataFromXPlane();
|
||||||
void updateRemoteAircraftFromSimulator(const QString &callsign, double latitudeDeg, double longitudeDeg, double elevationMeters, double modelVerticalOffsetMeters);
|
void updateRemoteAircraftFromSimulator(const QString &callsign, double latitudeDeg, double longitudeDeg, double elevationMeters, double modelVerticalOffsetMeters);
|
||||||
|
void updateAirportsInRange();
|
||||||
|
|
||||||
static constexpr int GuessRemoteAircraftPartsCycle = 20; //!< guess every n-th cycle
|
static constexpr int GuessRemoteAircraftPartsCycle = 20; //!< guess every n-th cycle
|
||||||
|
|
||||||
@@ -201,6 +202,7 @@ namespace BlackSimPlugin
|
|||||||
CXSwiftBusWeatherProxy *m_weatherProxy { nullptr };
|
CXSwiftBusWeatherProxy *m_weatherProxy { nullptr };
|
||||||
QTimer m_fastTimer;
|
QTimer m_fastTimer;
|
||||||
QTimer m_slowTimer;
|
QTimer m_slowTimer;
|
||||||
|
QTimer m_airportUpdater;
|
||||||
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
|
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
|
||||||
BlackMisc::CData<BlackMisc::Simulation::Data::TModelSetCacheXP> m_modelSet { this };
|
BlackMisc::CData<BlackMisc::Simulation::Data::TModelSetCacheXP> m_modelSet { this };
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,6 @@
|
|||||||
#define XPLM_MSG_LIVERY_LOADED 108
|
#define XPLM_MSG_LIVERY_LOADED 108
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Change QSharedPointer<QCoreApplication> to QSharedPointer<QApplication> below
|
|
||||||
// in case you want to have Qt Gui components inside a X-Plane plugin. The current
|
|
||||||
// default was used since QApplication causes an infinite loop in X-Plane on MacOS
|
|
||||||
// platforms. X-Plane is allocating an NSApplication but never calling run(), rather
|
|
||||||
// it controls the main loop itself and pumps the event Q as needed. This causes
|
|
||||||
// unusual start conditions for QCocoaEventDispatcher and ends up in the infinite
|
|
||||||
// loop. Since QCoreApplication is not using QCocoaEventDispatcher it works fine
|
|
||||||
// and is used as a workaround.
|
|
||||||
// See https://dev.vatsim-germany.org/issues/293 for more information.
|
|
||||||
|
|
||||||
QSharedPointer<QCoreApplication> g_qApp;
|
|
||||||
XSwiftBus::CPlugin *g_plugin;
|
XSwiftBus::CPlugin *g_plugin;
|
||||||
|
|
||||||
PLUGIN_API int XPluginStart(char *o_name, char *o_sig, char *o_desc)
|
PLUGIN_API int XPluginStart(char *o_name, char *o_sig, char *o_desc)
|
||||||
@@ -54,10 +43,6 @@ PLUGIN_API void XPluginStop()
|
|||||||
|
|
||||||
PLUGIN_API int XPluginEnable()
|
PLUGIN_API int XPluginEnable()
|
||||||
{
|
{
|
||||||
QXPlaneMessageHandler::install();
|
|
||||||
g_qApp = QSharedApplication::sharedInstance();
|
|
||||||
QXPlaneEventLoop::exec();
|
|
||||||
|
|
||||||
g_plugin = new XSwiftBus::CPlugin;
|
g_plugin = new XSwiftBus::CPlugin;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -65,7 +50,6 @@ PLUGIN_API int XPluginEnable()
|
|||||||
PLUGIN_API void XPluginDisable()
|
PLUGIN_API void XPluginDisable()
|
||||||
{
|
{
|
||||||
delete g_plugin;
|
delete g_plugin;
|
||||||
g_qApp.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PLUGIN_API void XPluginReceiveMessage(XPLMPluginID from, long msg, void *param)
|
PLUGIN_API void XPluginReceiveMessage(XPLMPluginID from, long msg, void *param)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "weather.h"
|
#include "weather.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "XPLM/XPLMProcessing.h"
|
#include "XPLM/XPLMProcessing.h"
|
||||||
#include <QTimer>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@@ -71,6 +70,8 @@ namespace XSwiftBus
|
|||||||
m_service = new CService(m_dbusConnection.get());
|
m_service = new CService(m_dbusConnection.get());
|
||||||
m_traffic = new CTraffic(m_dbusConnection.get());
|
m_traffic = new CTraffic(m_dbusConnection.get());
|
||||||
m_weather = new CWeather(m_dbusConnection.get());
|
m_weather = new CWeather(m_dbusConnection.get());
|
||||||
|
|
||||||
|
INFO_LOG("XSwiftBus started.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlugin::onAircraftModelChanged()
|
void CPlugin::onAircraftModelChanged()
|
||||||
|
|||||||
@@ -22,8 +22,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "dbusconnection.h"
|
#include "dbusconnection.h"
|
||||||
#include "menus.h"
|
#include "menus.h"
|
||||||
#include <QObject>
|
|
||||||
#include <QVector>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@@ -36,10 +34,8 @@ namespace XSwiftBus
|
|||||||
/*!
|
/*!
|
||||||
* Main plugin class
|
* Main plugin class
|
||||||
*/
|
*/
|
||||||
class CPlugin : public QObject
|
class CPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CPlugin();
|
CPlugin();
|
||||||
|
|||||||
@@ -10,11 +10,8 @@
|
|||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include <XPLM/XPLMPlanes.h>
|
#include <XPLM/XPLMPlanes.h>
|
||||||
#include <XPLM/XPLMUtilities.h>
|
#include <XPLM/XPLMUtilities.h>
|
||||||
#include <QDebug>
|
#include <fstream>
|
||||||
#include <QTimer>
|
#include "utils.h"
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QStringBuilder>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
// clazy:excludeall=reserve-candidates
|
// clazy:excludeall=reserve-candidates
|
||||||
|
|
||||||
@@ -25,9 +22,6 @@ namespace XSwiftBus
|
|||||||
{
|
{
|
||||||
registerDBusObjectPath(XSWIFTBUS_SERVICE_INTERFACENAME, XSWIFTBUS_SERVICE_OBJECTPATH);
|
registerDBusObjectPath(XSWIFTBUS_SERVICE_INTERFACENAME, XSWIFTBUS_SERVICE_OBJECTPATH);
|
||||||
m_messages.addMessage( { "xswiftbus started.", 0, 255, 255 } );
|
m_messages.addMessage( { "xswiftbus started.", 0, 255, 255 } );
|
||||||
m_airportUpdater = new QTimer();
|
|
||||||
m_airportUpdater->start(60000);
|
|
||||||
QObject::connect(m_airportUpdater, &QTimer::timeout, [this] () { updateAirportsInRange(); });
|
|
||||||
updateAirportsInRange();
|
updateAirportsInRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,35 +30,38 @@ namespace XSwiftBus
|
|||||||
char filename[256];
|
char filename[256];
|
||||||
char path[512];
|
char path[512];
|
||||||
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
||||||
const auto model = extractAcfProperties(path, QFileInfo(path));
|
const auto model = extractAcfProperties(path);
|
||||||
emitAircraftModelChanged(path, filename, getAircraftLivery(), getAircraftIcaoCode(), model.getModelString(), model.getName(), getAircraftDescription());
|
emitAircraftModelChanged(path, filename, getAircraftLivery(), getAircraftIcaoCode(), model.getModelString(), model.getName(), getAircraftDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CService::addTextMessage(const QString &text, double red, double green, double blue)
|
void CService::addTextMessage(const std::string &text, double red, double green, double blue)
|
||||||
{
|
{
|
||||||
if (text.isEmpty()) { return; }
|
if (text.empty()) { return; }
|
||||||
int lineLength = m_messages.maxLineLength() - 1;
|
static const std::string ellipsis = "...";
|
||||||
QStringList wrappedLines;
|
int lineLength = m_messages.maxLineLength() - ellipsis.size();
|
||||||
for (int i = 0; i < text.size(); i += lineLength)
|
std::vector<std::string> wrappedLines;
|
||||||
|
for (size_t i = 0; i < text.size(); i += lineLength)
|
||||||
{
|
{
|
||||||
static const QChar ellipsis = 0x2026;
|
// static const QChar ellipsis = 0x2026;
|
||||||
wrappedLines.push_back(text.mid(i, lineLength) + ellipsis);
|
// wrappedLines.push_back(QString::fromStdString(text).mid(i, lineLength) + ellipsis);
|
||||||
|
wrappedLines.push_back(text.substr(i, lineLength) + ellipsis);
|
||||||
}
|
}
|
||||||
wrappedLines.back().chop(1);
|
wrappedLines.back().erase(wrappedLines.back().size() - 3);
|
||||||
if (wrappedLines.back().isEmpty()) { wrappedLines.pop_back(); }
|
if (wrappedLines.back().empty()) { wrappedLines.pop_back(); }
|
||||||
else if (wrappedLines.back().size() == 1 && wrappedLines.size() > 1)
|
else if (wrappedLines.back().size() == ellipsis.size() && wrappedLines.size() > 1)
|
||||||
{
|
{
|
||||||
(wrappedLines.end() - 2)->chop(1);
|
auto secondLastLine = wrappedLines.end() - 2;
|
||||||
(wrappedLines.end() - 2)->append(wrappedLines.back());
|
secondLastLine->erase(wrappedLines.back().size() - 3);
|
||||||
|
secondLastLine->append(wrappedLines.back());
|
||||||
wrappedLines.pop_back();
|
wrappedLines.pop_back();
|
||||||
}
|
}
|
||||||
for (const auto &line : wrappedLines)
|
for (const auto &line : wrappedLines)
|
||||||
{
|
{
|
||||||
m_messages.addMessage({ line.toStdString(), static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue) });
|
m_messages.addMessage({ line, static_cast<float>(red), static_cast<float>(green), static_cast<float>(blue) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CService::getAircraftModelPath() const
|
std::string CService::getAircraftModelPath() const
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
char path[512];
|
char path[512];
|
||||||
@@ -72,7 +69,7 @@ namespace XSwiftBus
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CService::getAircraftModelFilename() const
|
std::string CService::getAircraftModelFilename() const
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
char path[512];
|
char path[512];
|
||||||
@@ -80,21 +77,21 @@ namespace XSwiftBus
|
|||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CService::getAircraftModelString() const
|
std::string CService::getAircraftModelString() const
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
char path[512];
|
char path[512];
|
||||||
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
||||||
const auto model = extractAcfProperties(path, QFileInfo(path));
|
const auto model = extractAcfProperties(path);
|
||||||
return model.getModelString();
|
return model.getModelString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CService::getAircraftName() const
|
std::string CService::getAircraftName() const
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
char path[512];
|
char path[512];
|
||||||
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
||||||
const auto model = extractAcfProperties(path, QFileInfo(path));
|
const auto model = extractAcfProperties(path);
|
||||||
return model.getName();
|
return model.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,14 +111,14 @@ namespace XSwiftBus
|
|||||||
return version % 100;
|
return version % 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CService::getXPlaneInstallationPath() const
|
std::string CService::getXPlaneInstallationPath() const
|
||||||
{
|
{
|
||||||
char path[512];
|
char path[512];
|
||||||
XPLMGetSystemPath(path);
|
XPLMGetSystemPath(path);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CService::getXPlanePreferencesPath() const
|
std::string CService::getXPlanePreferencesPath() const
|
||||||
{
|
{
|
||||||
char path[512];
|
char path[512];
|
||||||
XPLMGetPrefsPath(path);
|
XPLMGetPrefsPath(path);
|
||||||
@@ -206,7 +203,7 @@ namespace XSwiftBus
|
|||||||
|
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
addTextMessage(QString::fromStdString(text), red, green, blue);
|
addTextMessage(text, red, green, blue);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getOwnAircraftSituationData")
|
else if (message.getMethodName() == "getOwnAircraftSituationData")
|
||||||
@@ -246,49 +243,49 @@ namespace XSwiftBus
|
|||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getAircraftModelPath().toStdString());
|
sendDBusReply(sender, serial, getAircraftModelPath());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getAircraftModelFilename")
|
else if (message.getMethodName() == "getAircraftModelFilename")
|
||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getAircraftModelFilename().toStdString());
|
sendDBusReply(sender, serial, getAircraftModelFilename());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getAircraftModelString")
|
else if (message.getMethodName() == "getAircraftModelString")
|
||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getAircraftModelString().toStdString());
|
sendDBusReply(sender, serial, getAircraftModelString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getAircraftName")
|
else if (message.getMethodName() == "getAircraftName")
|
||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getAircraftName().toStdString());
|
sendDBusReply(sender, serial, getAircraftName());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getAircraftLivery")
|
else if (message.getMethodName() == "getAircraftLivery")
|
||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getAircraftLivery().toStdString());
|
sendDBusReply(sender, serial, getAircraftLivery());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getAircraftIcaoCode")
|
else if (message.getMethodName() == "getAircraftIcaoCode")
|
||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getAircraftIcaoCode().toStdString());
|
sendDBusReply(sender, serial, getAircraftIcaoCode());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getAircraftDescription")
|
else if (message.getMethodName() == "getAircraftDescription")
|
||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getAircraftDescription().toStdString());
|
sendDBusReply(sender, serial, getAircraftDescription());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getXPlaneVersionMajor")
|
else if (message.getMethodName() == "getXPlaneVersionMajor")
|
||||||
@@ -309,14 +306,14 @@ namespace XSwiftBus
|
|||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getXPlaneInstallationPath().toStdString());
|
sendDBusReply(sender, serial, getXPlaneInstallationPath());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "getXPlanePreferencesPath")
|
else if (message.getMethodName() == "getXPlanePreferencesPath")
|
||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, getXPlanePreferencesPath().toStdString());
|
sendDBusReply(sender, serial, getXPlanePreferencesPath());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "isPaused")
|
else if (message.getMethodName() == "isPaused")
|
||||||
@@ -599,7 +596,7 @@ namespace XSwiftBus
|
|||||||
{
|
{
|
||||||
queueDBusCall([=]()
|
queueDBusCall([=]()
|
||||||
{
|
{
|
||||||
std::vector<double> array = getEngineN1Percentage().toVector().toStdVector();
|
std::vector<double> array = getEngineN1Percentage();
|
||||||
sendDBusReply(sender, serial, array);
|
sendDBusReply(sender, serial, array);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -633,19 +630,19 @@ namespace XSwiftBus
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CService::emitAircraftModelChanged(const QString &path, const QString &filename, const QString &livery,
|
void CService::emitAircraftModelChanged(const std::string &path, const std::string &filename, const std::string &livery,
|
||||||
const QString &icao, const QString &modelString, const QString &name,
|
const std::string &icao, const std::string &modelString, const std::string &name,
|
||||||
const QString &description)
|
const std::string &description)
|
||||||
{
|
{
|
||||||
CDBusMessage signalAircraftModelChanged = CDBusMessage::createSignal(XSWIFTBUS_SERVICE_OBJECTPATH, XSWIFTBUS_SERVICE_INTERFACENAME, "aircraftModelChanged");
|
CDBusMessage signalAircraftModelChanged = CDBusMessage::createSignal(XSWIFTBUS_SERVICE_OBJECTPATH, XSWIFTBUS_SERVICE_INTERFACENAME, "aircraftModelChanged");
|
||||||
signalAircraftModelChanged.beginArgumentWrite();
|
signalAircraftModelChanged.beginArgumentWrite();
|
||||||
signalAircraftModelChanged.appendArgument(path.toStdString());
|
signalAircraftModelChanged.appendArgument(path);
|
||||||
signalAircraftModelChanged.appendArgument(filename.toStdString());
|
signalAircraftModelChanged.appendArgument(filename);
|
||||||
signalAircraftModelChanged.appendArgument(livery.toStdString());
|
signalAircraftModelChanged.appendArgument(livery);
|
||||||
signalAircraftModelChanged.appendArgument(icao.toStdString());
|
signalAircraftModelChanged.appendArgument(icao);
|
||||||
signalAircraftModelChanged.appendArgument(modelString.toStdString());
|
signalAircraftModelChanged.appendArgument(modelString);
|
||||||
signalAircraftModelChanged.appendArgument(name.toStdString());
|
signalAircraftModelChanged.appendArgument(name);
|
||||||
signalAircraftModelChanged.appendArgument(description.toStdString());
|
signalAircraftModelChanged.appendArgument(description);
|
||||||
sendDBusMessage(signalAircraftModelChanged);
|
sendDBusMessage(signalAircraftModelChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,105 +673,115 @@ namespace XSwiftBus
|
|||||||
return closestAirports;
|
return closestAirports;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString descriptionForFlyableModel(const CAircraftModel &model)
|
//! Qt free version of BlackMisc::Simulation::XPlane::descriptionForFlyableModel()
|
||||||
|
std::string descriptionForFlyableModel(const CAircraftModel &model)
|
||||||
{
|
{
|
||||||
if (!model.getName().isEmpty())
|
if (!model.getName().empty())
|
||||||
{
|
{
|
||||||
if (model.getDistributor().hasDescription() && !model.getName().contains(model.getDistributor().getDescription()))
|
if (model.getDistributor().hasDescription() && model.getName().find(model.getDistributor().getDescription()) == std::string::npos)
|
||||||
{
|
{
|
||||||
return QStringLiteral("[ACF] ") % model.getName() % QStringLiteral(" by ") % model.getDistributor().getDescription();
|
return std::string("[ACF] ") + model.getName() + " by " + model.getDistributor().getDescription();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return QStringLiteral("[ACF] ") % model.getName();
|
return std::string("[ACF] ") + model.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (model.hasAircraftDesignator())
|
else if (model.hasAircraftDesignator())
|
||||||
{
|
{
|
||||||
if (model.getDistributor().hasDescription())
|
if (model.getDistributor().hasDescription())
|
||||||
{
|
{
|
||||||
return QStringLiteral("[ACF] ") % model.getAircraftIcaoCodeDesignator() % QStringLiteral(" by ") % model.getDistributor().getDescription();
|
return std::string("[ACF] ") + model.getAircraftIcaoCodeDesignator() + " by " + model.getDistributor().getDescription();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return QStringLiteral("[ACF] ") % model.getAircraftIcaoCodeDesignator();
|
return std::string("[ACF] ") + model.getAircraftIcaoCodeDesignator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QStringLiteral("[ACF]");
|
return std::string("[ACF]");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString stringForFlyableModel(const CAircraftModel &model, const QFileInfo &acfFile)
|
//! Qt free version of BlackMisc::Simulation::XPlane::stringForFlyableModel()
|
||||||
|
std::string stringForFlyableModel(const CAircraftModel &model, const std::string &acfFile)
|
||||||
{
|
{
|
||||||
if (model.getDistributor().hasDescription())
|
if (model.getDistributor().hasDescription())
|
||||||
{
|
{
|
||||||
if (!model.getName().isEmpty())
|
if (!model.getName().empty())
|
||||||
{
|
{
|
||||||
if (model.getName().contains(model.getDistributor().getDescription()))
|
if (model.getName().find(model.getDistributor().getDescription()) != std::string::npos)
|
||||||
{
|
{
|
||||||
return model.getName();
|
return model.getName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return model.getDistributor().getDescription() % ' ' % model.getName();
|
return model.getDistributor().getDescription() + ' ' + model.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (model.hasAircraftDesignator())
|
else if (model.hasAircraftDesignator())
|
||||||
{
|
{
|
||||||
return model.getDistributor().getDescription() % ' ' % model.getAircraftIcaoCodeDesignator();
|
return model.getDistributor().getDescription() + ' ' + model.getAircraftIcaoCodeDesignator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return acfFile.dir().dirName() % ' ' % acfFile.baseName();
|
return getDirName(acfFile) + ' ' + getBaseName(acfFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAircraftModel CService::extractAcfProperties(const QString &filePath, const QFileInfo &fileInfo)
|
CAircraftModel CService::extractAcfProperties(const std::string &filePath)
|
||||||
{
|
{
|
||||||
CAircraftModel model;
|
CAircraftModel model;
|
||||||
QFile file(filePath);
|
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return model; }
|
|
||||||
|
|
||||||
QTextStream ts(&file);
|
std::ifstream fs(filePath, std::ios::in | std::ios::binary);
|
||||||
if (ts.readLine() == "I" && ts.readLine().contains("version") && ts.readLine() == "ACF")
|
if(!fs.is_open()) { return model; }
|
||||||
|
|
||||||
|
std::string i;
|
||||||
|
std::string version;
|
||||||
|
std::string acf;
|
||||||
|
std::getline(fs, i);
|
||||||
|
std::getline(fs, version);
|
||||||
|
std::getline(fs, acf);
|
||||||
|
|
||||||
|
if (i == "I" && version.find("version") != std::string::npos && acf == "ACF")
|
||||||
{
|
{
|
||||||
while (!ts.atEnd())
|
std::string line;
|
||||||
|
while (std::getline(fs, line))
|
||||||
{
|
{
|
||||||
const QString line = ts.readLine();
|
auto tokens = split(line, 2);
|
||||||
QVector<QStringRef> tokens = line.splitRef(' ', QString::SkipEmptyParts);
|
if (tokens.size() < 3 || tokens.at(0) != "P") { continue; }
|
||||||
if (tokens.size() < 3 || tokens.at(0) != QLatin1String("P")) { continue; }
|
if (tokens.at(1) == "acf/_ICAO")
|
||||||
if (tokens.at(1) == QLatin1String("acf/_ICAO"))
|
|
||||||
{
|
{
|
||||||
const QString icao(tokens.at(2).toString());
|
const std::string icao(tokens.at(2));
|
||||||
model.setAircraftIcaoCode(icao);
|
model.setAircraftIcaoCode(icao);
|
||||||
}
|
}
|
||||||
else if (tokens.at(1) == QLatin1String("acf/_descrip"))
|
else if (tokens.at(1) == "acf/_descrip")
|
||||||
{
|
{
|
||||||
const QString desc(line.mid(tokens.at(2).position()));
|
const std::string desc(tokens.at(2));
|
||||||
model.setDescription("[ACF] " % desc);
|
model.setDescription("[ACF] " + desc);
|
||||||
}
|
}
|
||||||
else if (tokens.at(1) == QLatin1String("acf/_name"))
|
else if (tokens.at(1) == "acf/_name")
|
||||||
{
|
{
|
||||||
const QString name(line.mid(tokens.at(2).position()));
|
const std::string name(tokens.at(2));
|
||||||
model.setName(name);
|
model.setName(name);
|
||||||
}
|
}
|
||||||
else if (tokens.at(1) == QLatin1String("acf/_studio"))
|
else if (tokens.at(1) == "acf/_studio")
|
||||||
{
|
{
|
||||||
const CDistributor dist(line.mid(tokens.at(2).position()));
|
const CDistributor dist(tokens.at(2));
|
||||||
model.setDistributor(dist);
|
model.setDistributor(dist);
|
||||||
}
|
}
|
||||||
else if (tokens.at(1) == QLatin1String("acf/_author"))
|
else if (tokens.at(1) == "acf/_author")
|
||||||
{
|
{
|
||||||
if (model.getDistributor().hasDescription()) { continue; }
|
if (model.getDistributor().hasDescription()) { continue; }
|
||||||
thread_local const QRegularExpression end("\\W\\s", QRegularExpression::UseUnicodePropertiesOption);
|
std::string author = tokens.at(2);
|
||||||
QString author = line.mid(tokens.at(2).position());
|
size_t pos = author.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_");
|
||||||
author = author.left(author.indexOf(end)).trimmed();
|
author = author.substr(0, pos);
|
||||||
if (author.isEmpty()) { continue; }
|
if (author.empty()) { continue; }
|
||||||
const CDistributor dist(author);
|
const CDistributor dist(author);
|
||||||
model.setDistributor(dist);
|
model.setDistributor(dist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.close();
|
|
||||||
|
|
||||||
model.setModelString(stringForFlyableModel(model, fileInfo));
|
fs.close();
|
||||||
|
|
||||||
|
model.setModelString(stringForFlyableModel(model, filePath));
|
||||||
if (!model.hasDescription()) { model.setDescription(descriptionForFlyableModel(model)); }
|
if (!model.hasDescription()) { model.setDescription(descriptionForFlyableModel(model)); }
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,7 @@
|
|||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "navdatareference.h"
|
#include "navdatareference.h"
|
||||||
#include <XPLM/XPLMNavigation.h>
|
#include <XPLM/XPLMNavigation.h>
|
||||||
#include <QStringList>
|
#include <string>
|
||||||
#include <QObject>
|
|
||||||
#include <QList>
|
|
||||||
#include <QFileInfo>
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
//! \cond PRIVATE
|
//! \cond PRIVATE
|
||||||
#define XSWIFTBUS_SERVICE_INTERFACENAME "org.swift_project.xswiftbus.service"
|
#define XSWIFTBUS_SERVICE_INTERFACENAME "org.swift_project.xswiftbus.service"
|
||||||
@@ -40,15 +35,20 @@ namespace XSwiftBus
|
|||||||
class CDistributor
|
class CDistributor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
//! Default constructor
|
||||||
CDistributor() = default;
|
CDistributor() = default;
|
||||||
CDistributor(const QString &distributor) : m_distributor(distributor) {}
|
|
||||||
|
|
||||||
bool hasDescription() const { return !m_description.isEmpty(); }
|
//! Constructor
|
||||||
QString getDescription() const { return m_description; }
|
CDistributor(const std::string &description) : m_description(description) {}
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CDistributor::hasDescription
|
||||||
|
bool hasDescription() const { return !m_description.empty(); }
|
||||||
|
|
||||||
|
//! \copydoc BlackMisc::Simulation::CDistributor::getDescription
|
||||||
|
std::string getDescription() const { return m_description; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_distributor;
|
std::string m_description;
|
||||||
QString m_description;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Simplified implementation of \sa BlackMisc::Simulation::CAircraftModel
|
//! Simplified implementation of \sa BlackMisc::Simulation::CAircraftModel
|
||||||
@@ -58,44 +58,44 @@ namespace XSwiftBus
|
|||||||
CAircraftModel() = default;
|
CAircraftModel() = default;
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasDescription
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasDescription
|
||||||
bool hasDescription() const { return !m_description.isEmpty(); }
|
bool hasDescription() const { return !m_description.empty(); }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasAircraftDesignator
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasAircraftDesignator
|
||||||
bool hasAircraftDesignator() const { return !m_icao.isEmpty(); }
|
bool hasAircraftDesignator() const { return !m_icao.empty(); }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getName
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::getName
|
||||||
QString getName() const { return m_name; }
|
std::string getName() const { return m_name; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getDistributor
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::getDistributor
|
||||||
CDistributor getDistributor() const { return m_distributor; }
|
CDistributor getDistributor() const { return m_distributor; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getAircraftIcaoCodeDesignator
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::getAircraftIcaoCodeDesignator
|
||||||
QString getAircraftIcaoCodeDesignator() const { return m_icao; }
|
std::string getAircraftIcaoCodeDesignator() const { return m_icao; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getModelString
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::getModelString
|
||||||
QString getModelString() const { return m_modelString; }
|
std::string getModelString() const { return m_modelString; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::setAircraftIcaoCode
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::setAircraftIcaoCode
|
||||||
void setAircraftIcaoCode(const QString &icao) { m_icao = icao; }
|
void setAircraftIcaoCode(const std::string &icao) { m_icao = icao; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::setDescription
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::setDescription
|
||||||
void setDescription(const QString &description) { m_description = description; }
|
void setDescription(const std::string &description) { m_description = description; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::setName
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::setName
|
||||||
void setName(const QString &name) { m_name = name; }
|
void setName(const std::string &name) { m_name = name; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::setDistributor
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::setDistributor
|
||||||
void setDistributor(const CDistributor &distributor) { m_distributor = distributor; }
|
void setDistributor(const CDistributor &distributor) { m_distributor = distributor; }
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::setModelString
|
//! \copydoc BlackMisc::Simulation::CAircraftModel::setModelString
|
||||||
void setModelString(const QString &modelString) { m_modelString = modelString; }
|
void setModelString(const std::string &modelString) { m_modelString = modelString; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_name;
|
std::string m_name;
|
||||||
QString m_icao;
|
std::string m_icao;
|
||||||
QString m_description;
|
std::string m_description;
|
||||||
CDistributor m_distributor;
|
CDistributor m_distributor;
|
||||||
QString m_modelString;
|
std::string m_modelString;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -111,16 +111,16 @@ namespace XSwiftBus
|
|||||||
~CService() override = default;
|
~CService() override = default;
|
||||||
|
|
||||||
//! DBus interface name
|
//! DBus interface name
|
||||||
static const QString &InterfaceName()
|
static const std::string &InterfaceName()
|
||||||
{
|
{
|
||||||
static const QString s(XSWIFTBUS_SERVICE_INTERFACENAME);
|
static const std::string s(XSWIFTBUS_SERVICE_INTERFACENAME);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! DBus object path
|
//! DBus object path
|
||||||
static const QString &ObjectPath()
|
static const std::string &ObjectPath()
|
||||||
{
|
{
|
||||||
static const QString s(XSWIFTBUS_SERVICE_OBJECTPATH);
|
static const std::string s(XSWIFTBUS_SERVICE_OBJECTPATH);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,31 +128,31 @@ namespace XSwiftBus
|
|||||||
void onAircraftModelChanged();
|
void onAircraftModelChanged();
|
||||||
|
|
||||||
//! Add a text message to the on-screen display, with RGB components in the range [0,1]
|
//! Add a text message to the on-screen display, with RGB components in the range [0,1]
|
||||||
void addTextMessage(const QString &text, double red, double green, double blue);
|
void addTextMessage(const std::string &text, double red, double green, double blue);
|
||||||
|
|
||||||
//! Called by newly connected client to cause airportsInRangeUpdated to be emitted.
|
//! Called by newly connected client to cause airportsInRangeUpdated to be emitted.
|
||||||
void updateAirportsInRange();
|
void updateAirportsInRange();
|
||||||
|
|
||||||
//! Get full path to current aircraft model
|
//! Get full path to current aircraft model
|
||||||
QString getAircraftModelPath() const;
|
std::string getAircraftModelPath() const;
|
||||||
|
|
||||||
//! Get base filename of current aircraft model
|
//! Get base filename of current aircraft model
|
||||||
QString getAircraftModelFilename() const;
|
std::string getAircraftModelFilename() const;
|
||||||
|
|
||||||
//! Get canonical swift model string of current aircraft model
|
//! Get canonical swift model string of current aircraft model
|
||||||
QString getAircraftModelString() const;
|
std::string getAircraftModelString() const;
|
||||||
|
|
||||||
//! Get name of current aircraft model
|
//! Get name of current aircraft model
|
||||||
QString getAircraftName() const;
|
std::string getAircraftName() const;
|
||||||
|
|
||||||
//! Get path to current aircraft livery
|
//! Get path to current aircraft livery
|
||||||
QString getAircraftLivery() const { return m_liveryPath.get().c_str(); }
|
std::string getAircraftLivery() const { return m_liveryPath.get(); }
|
||||||
|
|
||||||
//! Get the ICAO code of the current aircraft model
|
//! Get the ICAO code of the current aircraft model
|
||||||
QString getAircraftIcaoCode() const { return m_icao.get().c_str(); }
|
std::string getAircraftIcaoCode() const { return m_icao.get(); }
|
||||||
|
|
||||||
//! Get the description of the current aircraft model
|
//! Get the description of the current aircraft model
|
||||||
QString getAircraftDescription() const { return m_descrip.get().c_str(); }
|
std::string getAircraftDescription() const { return m_descrip.get(); }
|
||||||
|
|
||||||
//! Get major version number
|
//! Get major version number
|
||||||
int getXPlaneVersionMajor() const;
|
int getXPlaneVersionMajor() const;
|
||||||
@@ -161,10 +161,10 @@ namespace XSwiftBus
|
|||||||
int getXPlaneVersionMinor() const;
|
int getXPlaneVersionMinor() const;
|
||||||
|
|
||||||
//! Get root of X-Plane install path
|
//! Get root of X-Plane install path
|
||||||
QString getXPlaneInstallationPath() const;
|
std::string getXPlaneInstallationPath() const;
|
||||||
|
|
||||||
//! Get full path to X-Plane preferences file
|
//! Get full path to X-Plane preferences file
|
||||||
QString getXPlanePreferencesPath() const;
|
std::string getXPlanePreferencesPath() const;
|
||||||
|
|
||||||
//! True if sim is paused
|
//! True if sim is paused
|
||||||
bool isPaused() const { return m_paused.get(); }
|
bool isPaused() const { return m_paused.get(); }
|
||||||
@@ -275,14 +275,14 @@ namespace XSwiftBus
|
|||||||
int getNumberOfEngines() const { return m_numberOfEngines.get(); }
|
int getNumberOfEngines() const { return m_numberOfEngines.get(); }
|
||||||
|
|
||||||
//! Get the N1 speed as percent of max (per engine)
|
//! Get the N1 speed as percent of max (per engine)
|
||||||
QList<double> getEngineN1Percentage() const
|
std::vector<double> getEngineN1Percentage() const
|
||||||
{
|
{
|
||||||
QList<double> list;
|
std::vector<double> list;
|
||||||
const int number = getNumberOfEngines();
|
const auto number = static_cast<unsigned int>(getNumberOfEngines());
|
||||||
list.reserve(number);
|
list.reserve(number);
|
||||||
for (int engineNumber = 0; engineNumber < number; ++engineNumber)
|
for (unsigned int engineNumber = 0; engineNumber < number; ++engineNumber)
|
||||||
{
|
{
|
||||||
list.append(m_enginesN1Percentage.getAt(engineNumber));
|
list.push_back(m_enginesN1Percentage.getAt(engineNumber));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@@ -299,21 +299,20 @@ namespace XSwiftBus
|
|||||||
DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) override;
|
DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emitAircraftModelChanged(const QString &path, const QString &filename, const QString &livery,
|
void emitAircraftModelChanged(const std::string &path, const std::string &filename, const std::string &livery,
|
||||||
const QString &icao, const QString &modelString, const QString &name,
|
const std::string &icao, const std::string &modelString, const std::string &name,
|
||||||
const QString &description);
|
const std::string &description);
|
||||||
|
|
||||||
void emitAirportsInRangeUpdated(const std::vector<std::string> &icaoCodes, const std::vector<std::string> &names,
|
void emitAirportsInRangeUpdated(const std::vector<std::string> &icaoCodes, const std::vector<std::string> &names,
|
||||||
const std::vector<double> &lats, const std::vector<double> &lons, const std::vector<double> &alts);
|
const std::vector<double> &lats, const std::vector<double> &lons, const std::vector<double> &alts);
|
||||||
|
|
||||||
CMessageBoxControl m_messages { 128, 128, 16 };
|
CMessageBoxControl m_messages { 128, 128, 16 };
|
||||||
std::vector<CNavDataReference> m_airports;
|
std::vector<CNavDataReference> m_airports;
|
||||||
QTimer *m_airportUpdater = nullptr;
|
|
||||||
void readAirportsDatabase();
|
void readAirportsDatabase();
|
||||||
|
|
||||||
std::vector<CNavDataReference> findClosestAirports(int number, double latitude, double longitude);
|
std::vector<CNavDataReference> findClosestAirports(int number, double latitude, double longitude);
|
||||||
|
|
||||||
static CAircraftModel extractAcfProperties(const QString &filePath, const QFileInfo &fileInfo);
|
static CAircraftModel extractAcfProperties(const std::string &filePath);
|
||||||
|
|
||||||
StringDataRef<xplane::data::sim::aircraft::view::acf_livery_path> m_liveryPath;
|
StringDataRef<xplane::data::sim::aircraft::view::acf_livery_path> m_liveryPath;
|
||||||
StringDataRef<xplane::data::sim::aircraft::view::acf_ICAO> m_icao;
|
StringDataRef<xplane::data::sim::aircraft::view::acf_ICAO> m_icao;
|
||||||
|
|||||||
@@ -18,18 +18,17 @@
|
|||||||
#include "XPMPPlaneRenderer.h"
|
#include "XPMPPlaneRenderer.h"
|
||||||
#include <XPLM/XPLMProcessing.h>
|
#include <XPLM/XPLMProcessing.h>
|
||||||
#include <XPLM/XPLMUtilities.h>
|
#include <XPLM/XPLMUtilities.h>
|
||||||
#include <QDateTime>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <ctime>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
// clazy:excludeall=reserve-candidates
|
// clazy:excludeall=reserve-candidates
|
||||||
|
|
||||||
namespace XSwiftBus
|
namespace XSwiftBus
|
||||||
{
|
{
|
||||||
CTraffic::Plane::Plane(void *id_, QString callsign_, QString aircraftIcao_, QString airlineIcao_, QString livery_, QString modelName_)
|
CTraffic::Plane::Plane(void *id_, const std::string &callsign_, const std::string &aircraftIcao_, const std::string &airlineIcao_, const std::string &livery_, const std::string &modelName_)
|
||||||
: id(id_), callsign(callsign_), aircraftIcao(aircraftIcao_), airlineIcao(airlineIcao_), livery(livery_), modelName(modelName_)
|
: id(id_), callsign(callsign_), aircraftIcao(aircraftIcao_), airlineIcao(airlineIcao_), livery(livery_), modelName(modelName_)
|
||||||
{
|
{
|
||||||
std::memset(static_cast<void *>(&surfaces), 0, sizeof(surfaces));
|
std::memset(static_cast<void *>(&surfaces), 0, sizeof(surfaces));
|
||||||
@@ -38,8 +37,9 @@ namespace XSwiftBus
|
|||||||
surfaces.size = sizeof(surfaces);
|
surfaces.size = sizeof(surfaces);
|
||||||
xpdr.size = sizeof(xpdr);
|
xpdr.size = sizeof(xpdr);
|
||||||
|
|
||||||
std::strncpy(label, qPrintable(callsign), sizeof(label));
|
std::strncpy(label, callsign.c_str(), sizeof(label));
|
||||||
surfaces.lights.timeOffset = static_cast<quint16>(qrand() % 0xffff);
|
std::srand(static_cast<unsigned int>(std::time(nullptr)));
|
||||||
|
surfaces.lights.timeOffset = static_cast<uint16_t>(std::rand() % 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTraffic::CTraffic(CDBusConnection *dbusConnection) :
|
CTraffic::CTraffic(CDBusConnection *dbusConnection) :
|
||||||
@@ -60,8 +60,12 @@ namespace XSwiftBus
|
|||||||
initXPlanePath();
|
initXPlanePath();
|
||||||
auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "LegacyData" + g_sep;
|
auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "LegacyData" + g_sep;
|
||||||
|
|
||||||
auto err = XPMPMultiplayerInitLegacyData(qPrintable(dir + "CSL"), qPrintable(dir + "related.txt"),
|
std::string csl = dir + "CSL";
|
||||||
qPrintable(dir + "lights.png"), qPrintable(dir + "Doc8643.txt"), "C172", preferences, preferences);
|
std::string related = dir + "related.txt";
|
||||||
|
std::string doc8643 = dir + "Doc8643.txt";
|
||||||
|
std::string lights = dir + "lights.png";
|
||||||
|
auto err = XPMPMultiplayerInitLegacyData(csl.c_str(), related.c_str(), lights.c_str(), doc8643.c_str(),
|
||||||
|
"C172", preferences, preferences);
|
||||||
if (*err) { s_legacyDataOK = false; }
|
if (*err) { s_legacyDataOK = false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +74,7 @@ namespace XSwiftBus
|
|||||||
if (! s_legacyDataOK) { return false; }
|
if (! s_legacyDataOK) { return false; }
|
||||||
|
|
||||||
auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep;
|
auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep;
|
||||||
auto err = XPMPMultiplayerInit(preferences, preferences, qPrintable(dir));
|
auto err = XPMPMultiplayerInit(preferences, preferences, dir.c_str());
|
||||||
if (*err) { cleanup(); return false; }
|
if (*err) { cleanup(); return false; }
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
|
|
||||||
@@ -104,11 +108,11 @@ namespace XSwiftBus
|
|||||||
sendDBusSignal("simFrame");
|
sendDBusSignal("simFrame");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::emitRemoteAircraftData(const QString &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset)
|
void CTraffic::emitRemoteAircraftData(const std::string &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset)
|
||||||
{
|
{
|
||||||
CDBusMessage signalRemoteAircraftData = CDBusMessage::createSignal(XSWIFTBUS_TRAFFIC_OBJECTPATH, XSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftData");
|
CDBusMessage signalRemoteAircraftData = CDBusMessage::createSignal(XSWIFTBUS_TRAFFIC_OBJECTPATH, XSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftData");
|
||||||
signalRemoteAircraftData.beginArgumentWrite();
|
signalRemoteAircraftData.beginArgumentWrite();
|
||||||
signalRemoteAircraftData.appendArgument(callsign.toStdString());
|
signalRemoteAircraftData.appendArgument(callsign);
|
||||||
signalRemoteAircraftData.appendArgument(latitude);
|
signalRemoteAircraftData.appendArgument(latitude);
|
||||||
signalRemoteAircraftData.appendArgument(longitude);
|
signalRemoteAircraftData.appendArgument(longitude);
|
||||||
signalRemoteAircraftData.appendArgument(elevation);
|
signalRemoteAircraftData.appendArgument(elevation);
|
||||||
@@ -141,19 +145,21 @@ namespace XSwiftBus
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTraffic::loadPlanesPackage(const QString &path)
|
bool CTraffic::loadPlanesPackage(const std::string &path)
|
||||||
{
|
{
|
||||||
initXPlanePath();
|
initXPlanePath();
|
||||||
auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "LegacyData" + g_sep;
|
auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep + "LegacyData" + g_sep;
|
||||||
|
|
||||||
auto err = XPMPLoadCSLPackage(qPrintable(path), qPrintable(dir + "related.txt"), qPrintable(dir + "Doc8643.txt"));
|
std::string related = dir + "related.txt";
|
||||||
|
std::string doc8643 = dir + "Doc8643.txt";
|
||||||
|
auto err = XPMPLoadCSLPackage(path.c_str(), related.c_str(), doc8643.c_str());
|
||||||
if (*err) { return false; }
|
if (*err) { return false; }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::setDefaultIcao(const QString &defaultIcao)
|
void CTraffic::setDefaultIcao(const std::string &defaultIcao)
|
||||||
{
|
{
|
||||||
XPMPSetDefaultPlaneICAO(qPrintable(defaultIcao));
|
XPMPSetDefaultPlaneICAO(defaultIcao.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::setDrawingLabels(bool drawing)
|
void CTraffic::setDrawingLabels(bool drawing)
|
||||||
@@ -183,16 +189,16 @@ namespace XSwiftBus
|
|||||||
g_drawDistance = static_cast<float>(nauticalMiles);
|
g_drawDistance = static_cast<float>(nauticalMiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::addPlane(const QString &callsign, const QString &modelName, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery)
|
void CTraffic::addPlane(const std::string &callsign, const std::string &modelName, const std::string &aircraftIcao, const std::string &airlineIcao, const std::string &livery)
|
||||||
{
|
{
|
||||||
XPMPPlaneID id = nullptr;
|
XPMPPlaneID id = nullptr;
|
||||||
if (modelName.isEmpty())
|
if (modelName.empty())
|
||||||
{
|
{
|
||||||
id = XPMPCreatePlane(qPrintable(aircraftIcao), qPrintable(airlineIcao), qPrintable(livery), getPlaneData, static_cast<void *>(this));
|
id = XPMPCreatePlane(aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str(), getPlaneData, static_cast<void *>(this));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id = XPMPCreatePlaneWithModelName(qPrintable(modelName), qPrintable(aircraftIcao), qPrintable(airlineIcao), qPrintable(livery), getPlaneData, static_cast<void *>(this));
|
id = XPMPCreatePlaneWithModelName(modelName.c_str(), aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str(), getPlaneData, static_cast<void *>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
@@ -203,21 +209,23 @@ namespace XSwiftBus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::removePlane(const QString &callsign)
|
void CTraffic::removePlane(const std::string &callsign)
|
||||||
{
|
{
|
||||||
Plane *plane = m_planesByCallsign.value(callsign, nullptr);
|
auto planeIt = m_planesByCallsign.find(callsign);
|
||||||
if (!plane) { return; }
|
if (planeIt == m_planesByCallsign.end()) { return; }
|
||||||
m_planesByCallsign.remove(callsign);
|
|
||||||
m_planesById.remove(plane->id);
|
Plane *plane = planeIt->second;
|
||||||
|
m_planesByCallsign.erase(callsign);
|
||||||
|
m_planesById.erase(plane->id);
|
||||||
XPMPDestroyPlane(plane->id);
|
XPMPDestroyPlane(plane->id);
|
||||||
delete plane;
|
delete plane;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::removeAllPlanes()
|
void CTraffic::removeAllPlanes()
|
||||||
{
|
{
|
||||||
const QList<Plane *> planes = m_planesByCallsign.values();
|
for (const auto &kv : m_planesByCallsign)
|
||||||
for (Plane *plane : planes)
|
|
||||||
{
|
{
|
||||||
|
Plane *plane = kv.second;
|
||||||
assert(plane);
|
assert(plane);
|
||||||
XPMPDestroyPlane(plane->id);
|
XPMPDestroyPlane(plane->id);
|
||||||
delete plane;
|
delete plane;
|
||||||
@@ -226,9 +234,12 @@ namespace XSwiftBus
|
|||||||
m_planesById.clear();
|
m_planesById.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading)
|
void CTraffic::setPlanePosition(const std::string &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading)
|
||||||
{
|
{
|
||||||
Plane *plane = m_planesByCallsign.value(callsign, nullptr);
|
auto planeIt = m_planesByCallsign.find(callsign);
|
||||||
|
if (planeIt == m_planesByCallsign.end()) { return; }
|
||||||
|
|
||||||
|
Plane *plane = planeIt->second;
|
||||||
if (!plane) { return; }
|
if (!plane) { return; }
|
||||||
plane->position.lat = latitude;
|
plane->position.lat = latitude;
|
||||||
plane->position.lon = longitude;
|
plane->position.lon = longitude;
|
||||||
@@ -238,11 +249,14 @@ namespace XSwiftBus
|
|||||||
plane->position.heading = static_cast<float>(heading);
|
plane->position.heading = static_cast<float>(heading);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
void CTraffic::setPlaneSurfaces(const std::string &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround)
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround)
|
||||||
{
|
{
|
||||||
Q_UNUSED(onGround);
|
(void) onGround;
|
||||||
Plane *plane = m_planesByCallsign.value(callsign, nullptr);
|
auto planeIt = m_planesByCallsign.find(callsign);
|
||||||
|
if (planeIt == m_planesByCallsign.end()) { return; }
|
||||||
|
|
||||||
|
Plane *plane = planeIt->second;
|
||||||
if (!plane) { return; }
|
if (!plane) { return; }
|
||||||
|
|
||||||
plane->hasSurfaces = true;
|
plane->hasSurfaces = true;
|
||||||
@@ -263,9 +277,12 @@ namespace XSwiftBus
|
|||||||
plane->surfaces.lights.flashPattern = lightPattern;
|
plane->surfaces.lights.flashPattern = lightPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTraffic::setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident)
|
void CTraffic::setPlaneTransponder(const std::string &callsign, int code, bool modeC, bool ident)
|
||||||
{
|
{
|
||||||
Plane *plane = m_planesByCallsign.value(callsign, nullptr);
|
auto planeIt = m_planesByCallsign.find(callsign);
|
||||||
|
if (planeIt == m_planesByCallsign.end()) { return; }
|
||||||
|
|
||||||
|
Plane *plane = planeIt->second;
|
||||||
if (!plane) { return; }
|
if (!plane) { return; }
|
||||||
plane->hasXpdr = true;
|
plane->hasXpdr = true;
|
||||||
plane->xpdr.code = code;
|
plane->xpdr.code = code;
|
||||||
@@ -277,9 +294,9 @@ namespace XSwiftBus
|
|||||||
void CTraffic::requestRemoteAircraftData()
|
void CTraffic::requestRemoteAircraftData()
|
||||||
{
|
{
|
||||||
if (m_planesByCallsign.empty()) { return; }
|
if (m_planesByCallsign.empty()) { return; }
|
||||||
const QList<Plane *> planes = m_planesByCallsign.values();
|
for (const auto &kv : m_planesByCallsign)
|
||||||
for (const Plane *plane : planes)
|
|
||||||
{
|
{
|
||||||
|
Plane *plane = kv.second;
|
||||||
assert(plane);
|
assert(plane);
|
||||||
double lat = plane->position.lat;
|
double lat = plane->position.lat;
|
||||||
double lon = plane->position.lon;
|
double lon = plane->position.lon;
|
||||||
@@ -287,7 +304,7 @@ namespace XSwiftBus
|
|||||||
double groundElevation = plane->terrainProbe.getElevation(lat, lon, elevation);
|
double groundElevation = plane->terrainProbe.getElevation(lat, lon, elevation);
|
||||||
if (std::isnan(groundElevation)) { groundElevation = 0.0; }
|
if (std::isnan(groundElevation)) { groundElevation = 0.0; }
|
||||||
double fudgeFactor = 3.0;
|
double fudgeFactor = 3.0;
|
||||||
actualVertOffsetInfo(qPrintable(plane->modelName), nullptr, &fudgeFactor);
|
actualVertOffsetInfo(plane->modelName.c_str(), nullptr, &fudgeFactor);
|
||||||
emitRemoteAircraftData(plane->callsign, lat, lon, groundElevation, fudgeFactor);
|
emitRemoteAircraftData(plane->callsign, lat, lon, groundElevation, fudgeFactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,7 +349,7 @@ namespace XSwiftBus
|
|||||||
message.getArgument(path);
|
message.getArgument(path);
|
||||||
queueDBusCall([ = ]()
|
queueDBusCall([ = ]()
|
||||||
{
|
{
|
||||||
sendDBusReply(sender, serial, loadPlanesPackage(QString::fromStdString(path)));
|
sendDBusReply(sender, serial, loadPlanesPackage(path));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "setDefaultIcao")
|
else if (message.getMethodName() == "setDefaultIcao")
|
||||||
@@ -342,7 +359,7 @@ namespace XSwiftBus
|
|||||||
message.getArgument(defaultIcao);
|
message.getArgument(defaultIcao);
|
||||||
queueDBusCall([ = ]()
|
queueDBusCall([ = ]()
|
||||||
{
|
{
|
||||||
setDefaultIcao(QString::fromStdString(defaultIcao));
|
setDefaultIcao(defaultIcao);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "setDrawingLabels")
|
else if (message.getMethodName() == "setDrawingLabels")
|
||||||
@@ -404,7 +421,7 @@ namespace XSwiftBus
|
|||||||
|
|
||||||
queueDBusCall([ = ]()
|
queueDBusCall([ = ]()
|
||||||
{
|
{
|
||||||
addPlane(QString::fromStdString(callsign), QString::fromStdString(modelName), QString::fromStdString(aircraftIcao), QString::fromStdString(airlineIcao), QString::fromStdString(livery));
|
addPlane(callsign, modelName, aircraftIcao, airlineIcao, livery);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "removePlane")
|
else if (message.getMethodName() == "removePlane")
|
||||||
@@ -415,7 +432,7 @@ namespace XSwiftBus
|
|||||||
message.getArgument(callsign);
|
message.getArgument(callsign);
|
||||||
queueDBusCall([ = ]()
|
queueDBusCall([ = ]()
|
||||||
{
|
{
|
||||||
removePlane(QString::fromStdString(callsign));
|
removePlane(callsign);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "removeAllPlanes")
|
else if (message.getMethodName() == "removeAllPlanes")
|
||||||
@@ -446,7 +463,7 @@ namespace XSwiftBus
|
|||||||
message.getArgument(heading);
|
message.getArgument(heading);
|
||||||
queueDBusCall([ = ]()
|
queueDBusCall([ = ]()
|
||||||
{
|
{
|
||||||
setPlanePosition(QString::fromStdString(callsign), latitude, longitude, altitude, pitch, roll, heading);
|
setPlanePosition(callsign, latitude, longitude, altitude, pitch, roll, heading);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "setPlaneSurfaces")
|
else if (message.getMethodName() == "setPlaneSurfaces")
|
||||||
@@ -489,7 +506,7 @@ namespace XSwiftBus
|
|||||||
message.getArgument(onGround);
|
message.getArgument(onGround);
|
||||||
queueDBusCall([ = ]()
|
queueDBusCall([ = ]()
|
||||||
{
|
{
|
||||||
setPlaneSurfaces(QString::fromStdString(callsign), gear, flap, spoiler, speedBrake, slat, wingSweep, thrust, elevator,
|
setPlaneSurfaces(callsign, gear, flap, spoiler, speedBrake, slat, wingSweep, thrust, elevator,
|
||||||
rudder, aileron, landLight, beaconLight, strobeLight, navLight, lightPattern,
|
rudder, aileron, landLight, beaconLight, strobeLight, navLight, lightPattern,
|
||||||
onGround);
|
onGround);
|
||||||
});
|
});
|
||||||
@@ -508,7 +525,7 @@ namespace XSwiftBus
|
|||||||
message.getArgument(ident);
|
message.getArgument(ident);
|
||||||
queueDBusCall([ = ]()
|
queueDBusCall([ = ]()
|
||||||
{
|
{
|
||||||
setPlaneTransponder(QString::fromStdString(callsign), code, modeC, ident);
|
setPlaneTransponder(callsign, code, modeC, ident);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (message.getMethodName() == "requestRemoteAircraftData")
|
else if (message.getMethodName() == "requestRemoteAircraftData")
|
||||||
@@ -546,8 +563,9 @@ namespace XSwiftBus
|
|||||||
|
|
||||||
int CTraffic::getPlaneData(void *id, int dataType, void *io_data)
|
int CTraffic::getPlaneData(void *id, int dataType, void *io_data)
|
||||||
{
|
{
|
||||||
QHash<void *, Plane *> planesById = m_planesById;
|
auto planeIt = m_planesById.find(id);
|
||||||
Plane *plane = m_planesById.value(id, nullptr);
|
assert(planeIt != m_planesById.end());
|
||||||
|
Plane *plane = planeIt->second;
|
||||||
if (!plane) { return xpmpData_Unavailable; }
|
if (!plane) { return xpmpData_Unavailable; }
|
||||||
|
|
||||||
switch (dataType)
|
switch (dataType)
|
||||||
@@ -568,18 +586,20 @@ namespace XSwiftBus
|
|||||||
case xpmpDataType_Surfaces:
|
case xpmpDataType_Surfaces:
|
||||||
if (plane->hasSurfaces)
|
if (plane->hasSurfaces)
|
||||||
{
|
{
|
||||||
const auto currentTime = QDateTime::currentMSecsSinceEpoch();
|
const auto now = std::chrono::system_clock::now();
|
||||||
|
|
||||||
if (plane->surfaces.gearPosition != plane->targetGearPosition)
|
if (plane->surfaces.gearPosition != plane->targetGearPosition)
|
||||||
{
|
{
|
||||||
// interpolate gear position
|
// interpolate gear position
|
||||||
constexpr float gearMoveTimeMs = 5000;
|
constexpr float gearMoveTimeMs = 5000;
|
||||||
const auto gearPositionDiffRemaining = plane->targetGearPosition - plane->surfaces.gearPosition;
|
const auto gearPositionDiffRemaining = plane->targetGearPosition - plane->surfaces.gearPosition;
|
||||||
const auto gearPositionDiffThisFrame = (currentTime - plane->prevSurfacesLerpTime) / gearMoveTimeMs;
|
|
||||||
|
auto diffMs = std::chrono::duration_cast<std::chrono::milliseconds>(now - plane->prevSurfacesLerpTime);
|
||||||
|
const auto gearPositionDiffThisFrame = (diffMs.count()) / gearMoveTimeMs;
|
||||||
plane->surfaces.gearPosition += std::copysign(gearPositionDiffThisFrame, gearPositionDiffRemaining);
|
plane->surfaces.gearPosition += std::copysign(gearPositionDiffThisFrame, gearPositionDiffRemaining);
|
||||||
plane->surfaces.gearPosition = qBound(0.0f, plane->surfaces.gearPosition, 1.0f);
|
plane->surfaces.gearPosition = std::max(0.0f, std::min(plane->surfaces.gearPosition, 1.0f));
|
||||||
}
|
}
|
||||||
plane->prevSurfacesLerpTime = currentTime;
|
plane->prevSurfacesLerpTime = now;
|
||||||
const auto io_surfaces = static_cast<XPMPPlaneSurfaces_t *>(io_data);
|
const auto io_surfaces = static_cast<XPMPPlaneSurfaces_t *>(io_data);
|
||||||
|
|
||||||
if (memcmpPayload(io_surfaces, &plane->surfaces))
|
if (memcmpPayload(io_surfaces, &plane->surfaces))
|
||||||
|
|||||||
@@ -15,11 +15,6 @@
|
|||||||
#include "dbusobject.h"
|
#include "dbusobject.h"
|
||||||
#include "datarefs.h"
|
#include "datarefs.h"
|
||||||
#include "terrainprobe.h"
|
#include "terrainprobe.h"
|
||||||
#include <QDateTime>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QVector>
|
|
||||||
#include <QStringList>
|
|
||||||
#include "XPMPMultiplayer.h"
|
#include "XPMPMultiplayer.h"
|
||||||
#include <XPLM/XPLMDisplay.h>
|
#include <XPLM/XPLMDisplay.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -42,19 +37,19 @@ namespace XSwiftBus
|
|||||||
CTraffic(CDBusConnection *dbusConnection);
|
CTraffic(CDBusConnection *dbusConnection);
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
virtual ~CTraffic();
|
~CTraffic() override;
|
||||||
|
|
||||||
//! DBus interface name
|
//! DBus interface name
|
||||||
static const QString &InterfaceName()
|
static const std::string &InterfaceName()
|
||||||
{
|
{
|
||||||
static QString s(XSWIFTBUS_TRAFFIC_INTERFACENAME);
|
static std::string s(XSWIFTBUS_TRAFFIC_INTERFACENAME);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! DBus object path
|
//! DBus object path
|
||||||
static const QString &ObjectPath()
|
static const std::string &ObjectPath()
|
||||||
{
|
{
|
||||||
static QString s(XSWIFTBUS_TRAFFIC_OBJECTPATH);
|
static std::string s(XSWIFTBUS_TRAFFIC_OBJECTPATH);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,10 +63,10 @@ namespace XSwiftBus
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
//! Load a collection of planes from the given directory and return true if successful
|
//! Load a collection of planes from the given directory and return true if successful
|
||||||
bool loadPlanesPackage(const QString &path);
|
bool loadPlanesPackage(const std::string &path);
|
||||||
|
|
||||||
//! Set the ICAO code to use for aircraft without a model match
|
//! Set the ICAO code to use for aircraft without a model match
|
||||||
void setDefaultIcao(const QString &defaultIcao);
|
void setDefaultIcao(const std::string &defaultIcao);
|
||||||
|
|
||||||
//! Set whether the plugin draws type and callsign labels above aircraft
|
//! Set whether the plugin draws type and callsign labels above aircraft
|
||||||
void setDrawingLabels(bool drawing);
|
void setDrawingLabels(bool drawing);
|
||||||
@@ -86,23 +81,23 @@ namespace XSwiftBus
|
|||||||
void setMaxDrawDistance(double nauticalMiles);
|
void setMaxDrawDistance(double nauticalMiles);
|
||||||
|
|
||||||
//! Introduce a new traffic aircraft
|
//! Introduce a new traffic aircraft
|
||||||
void addPlane(const QString &callsign, const QString &modelName, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery);
|
void addPlane(const std::string &callsign, const std::string &modelName, const std::string &aircraftIcao, const std::string &airlineIcao, const std::string &livery);
|
||||||
|
|
||||||
//! Remove a traffic aircraft
|
//! Remove a traffic aircraft
|
||||||
void removePlane(const QString &callsign);
|
void removePlane(const std::string &callsign);
|
||||||
|
|
||||||
//! Remove all traffic aircraft
|
//! Remove all traffic aircraft
|
||||||
void removeAllPlanes();
|
void removeAllPlanes();
|
||||||
|
|
||||||
//! Set the position of a traffic aircraft
|
//! Set the position of a traffic aircraft
|
||||||
void setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading);
|
void setPlanePosition(const std::string &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading);
|
||||||
|
|
||||||
//! Set the flight control surfaces and lights of a traffic aircraft
|
//! Set the flight control surfaces and lights of a traffic aircraft
|
||||||
void setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
void setPlaneSurfaces(const std::string &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust,
|
||||||
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround);
|
double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround);
|
||||||
|
|
||||||
//! Set the transponder of a traffic aircraft
|
//! Set the transponder of a traffic aircraft
|
||||||
void setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident);
|
void setPlaneTransponder(const std::string &callsign, int code, bool modeC, bool ident);
|
||||||
|
|
||||||
//! Request traffic plane data. A signal remoteAircraftData will be emitted for each known plane
|
//! Request traffic plane data. A signal remoteAircraftData will be emitted for each known plane
|
||||||
void requestRemoteAircraftData();
|
void requestRemoteAircraftData();
|
||||||
@@ -117,7 +112,7 @@ namespace XSwiftBus
|
|||||||
bool m_enabled = false;
|
bool m_enabled = false;
|
||||||
|
|
||||||
void emitSimFrame();
|
void emitSimFrame();
|
||||||
void emitRemoteAircraftData(const QString &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset);
|
void emitRemoteAircraftData(const std::string &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset);
|
||||||
|
|
||||||
static int preferences(const char *section, const char *name, int def);
|
static int preferences(const char *section, const char *name, int def);
|
||||||
static float preferences(const char *section, const char *name, float def);
|
static float preferences(const char *section, const char *name, float def);
|
||||||
@@ -125,26 +120,27 @@ namespace XSwiftBus
|
|||||||
struct Plane
|
struct Plane
|
||||||
{
|
{
|
||||||
void *id = nullptr;
|
void *id = nullptr;
|
||||||
QString callsign;
|
std::string callsign;
|
||||||
QString aircraftIcao;
|
std::string aircraftIcao;
|
||||||
QString airlineIcao;
|
std::string airlineIcao;
|
||||||
QString livery;
|
std::string livery;
|
||||||
QString modelName;
|
std::string modelName;
|
||||||
bool hasSurfaces = false;
|
bool hasSurfaces = false;
|
||||||
bool hasXpdr = false;
|
bool hasXpdr = false;
|
||||||
char label[32] {};
|
char label[32] {};
|
||||||
CTerrainProbe terrainProbe;
|
CTerrainProbe terrainProbe;
|
||||||
XPMPPlaneSurfaces_t surfaces;
|
XPMPPlaneSurfaces_t surfaces;
|
||||||
float targetGearPosition = 0;
|
float targetGearPosition = 0;
|
||||||
qint64 prevSurfacesLerpTime = 0;
|
std::chrono::system_clock::time_point prevSurfacesLerpTime;
|
||||||
XPMPPlaneRadar_t xpdr;
|
XPMPPlaneRadar_t xpdr;
|
||||||
XPMPPlanePosition_t position;
|
XPMPPlanePosition_t position;
|
||||||
Plane(void *id_, QString callsign_, QString aircraftIcao_, QString airlineIcao_, QString livery_, QString modelName_);
|
Plane(void *id_, const std::string &callsign_, const std::string &aircraftIcao_, const std::string &airlineIcao_,
|
||||||
|
const std::string &livery_, const std::string &modelName_);
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<QString, Plane *> m_planesByCallsign;
|
std::unordered_map<std::string, Plane *> m_planesByCallsign;
|
||||||
QHash<void *, Plane *> m_planesById;
|
std::unordered_map<void *, Plane *> m_planesById;
|
||||||
qint64 m_timestampLastSimFrame = QDateTime::currentMSecsSinceEpoch();
|
std::chrono::system_clock::time_point m_timestampLastSimFrame = std::chrono::system_clock::now();
|
||||||
|
|
||||||
int getPlaneData(void *id, int dataType, void *io_data);
|
int getPlaneData(void *id, int dataType, void *io_data);
|
||||||
static int getPlaneData(void *id, int dataType, void *io_data, void *self)
|
static int getPlaneData(void *id, int dataType, void *io_data, void *self)
|
||||||
|
|||||||
@@ -15,19 +15,19 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <XPMPMultiplayerCSL.h>
|
#include <XPMPMultiplayerCSL.h>
|
||||||
#include <QString>
|
#include <string>
|
||||||
#include <QtGlobal>
|
#include <sstream>
|
||||||
|
|
||||||
namespace XSwiftBus
|
namespace XSwiftBus
|
||||||
{
|
{
|
||||||
|
|
||||||
QString g_xplanePath;
|
std::string g_xplanePath;
|
||||||
QString g_sep;
|
std::string g_sep;
|
||||||
|
|
||||||
//! Init global xplane path
|
//! Init global xplane path
|
||||||
void initXPlanePath()
|
void initXPlanePath()
|
||||||
{
|
{
|
||||||
if (!g_xplanePath.isEmpty() && !g_sep.isEmpty()) {}
|
if (!g_xplanePath.empty() && !g_sep.empty()) {}
|
||||||
|
|
||||||
char xplanePath[512];
|
char xplanePath[512];
|
||||||
XPLMGetSystemPath(xplanePath);
|
XPLMGetSystemPath(xplanePath);
|
||||||
@@ -43,6 +43,116 @@ namespace XSwiftBus
|
|||||||
g_xplanePath = xplanePath;
|
g_xplanePath = xplanePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getDirName(const string &filePath)
|
||||||
|
{
|
||||||
|
std::string seperator = "/\\";
|
||||||
|
std::size_t sepPos = filePath.find_last_of(seperator);
|
||||||
|
if(sepPos != std::string::npos)
|
||||||
|
{
|
||||||
|
return filePath.substr(0, sepPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getFileName(const std::string &filePath)
|
||||||
|
{
|
||||||
|
std::string seperator = "/\\";
|
||||||
|
std::size_t sepPos = filePath.find_last_of(seperator);
|
||||||
|
if(sepPos != std::string::npos)
|
||||||
|
{
|
||||||
|
return filePath.substr(sepPos + 1, filePath.size() - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getBaseName(const std::string &filePath)
|
||||||
|
{
|
||||||
|
std::string seperator = ".";
|
||||||
|
std::string fileName = getFileName(filePath);
|
||||||
|
std::size_t sepPos = fileName.find(seperator);
|
||||||
|
if(sepPos != std::string::npos)
|
||||||
|
{
|
||||||
|
return fileName.substr(0, sepPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string &str, size_t maxSplitCount)
|
||||||
|
{
|
||||||
|
std::string s(str);
|
||||||
|
std::string delimiter = " ";
|
||||||
|
size_t pos = 0;
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
while ((pos = s.find(delimiter)) != std::string::npos)
|
||||||
|
{
|
||||||
|
tokens.push_back(s.substr(0, pos));
|
||||||
|
s.erase(0, pos + delimiter.length());
|
||||||
|
if (tokens.size() == maxSplitCount) { break; }
|
||||||
|
}
|
||||||
|
tokens.push_back(s);
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::print(const std::string &filePath, int line, MsgType type, const std::string &message)
|
||||||
|
{
|
||||||
|
(void) line;
|
||||||
|
(void) type;
|
||||||
|
|
||||||
|
assert(!filePath.empty());
|
||||||
|
std::ostringstream ss;
|
||||||
|
|
||||||
|
ss << "xswiftbus";
|
||||||
|
ss << ' ';
|
||||||
|
|
||||||
|
#if defined(XSWIFTBUS_ENABLE_TRACE_LOG)
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DebugMsg:
|
||||||
|
ss << "Debug";
|
||||||
|
break;
|
||||||
|
case InfoMsg:
|
||||||
|
ss << "Info";
|
||||||
|
break;
|
||||||
|
case WarningMsg:
|
||||||
|
ss << "Warning";
|
||||||
|
break;
|
||||||
|
case FatalMsg:
|
||||||
|
ss << "Fatal";
|
||||||
|
}
|
||||||
|
ss << ' ';
|
||||||
|
|
||||||
|
std::string seperator = "/\\";
|
||||||
|
std::size_t sepPos = filePath.find_last_of(seperator);
|
||||||
|
if(sepPos != std::string::npos)
|
||||||
|
{
|
||||||
|
ss << filePath.substr(sepPos + 1, filePath.size() - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << filePath;
|
||||||
|
}
|
||||||
|
ss << ' ';
|
||||||
|
|
||||||
|
ss << line;
|
||||||
|
ss << " : ";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ss << message;
|
||||||
|
ss << "\n";
|
||||||
|
|
||||||
|
std::string buffer = ss.str();
|
||||||
|
XPLMDebugString(buffer.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \endcond
|
//! \endcond
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
#include <XPLM/XPLMPlugin.h>
|
#include <XPLM/XPLMPlugin.h>
|
||||||
#include <XPLM/XPLMProcessing.h>
|
#include <XPLM/XPLMProcessing.h>
|
||||||
#include <XPLM/XPLMUtilities.h>
|
#include <XPLM/XPLMUtilities.h>
|
||||||
#include <QCoreApplication>
|
#include <vector>
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \file
|
* \file
|
||||||
@@ -28,58 +28,58 @@
|
|||||||
/*!
|
/*!
|
||||||
* Install a Qt message handler which outputs to the X-Plane debug log.
|
* Install a Qt message handler which outputs to the X-Plane debug log.
|
||||||
*/
|
*/
|
||||||
class QXPlaneMessageHandler
|
//class QXPlaneMessageHandler
|
||||||
{
|
//{
|
||||||
static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
// static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||||
{
|
// {
|
||||||
QByteArray localMsg = msg.toLocal8Bit();
|
// QByteArray localMsg = msg.toLocal8Bit();
|
||||||
QByteArray file(context.file);
|
// QByteArray file(context.file);
|
||||||
if (file.isEmpty()) file = "<unknown>";
|
// if (file.isEmpty()) file = "<unknown>";
|
||||||
|
|
||||||
int line = context.line;
|
// int line = context.line;
|
||||||
|
|
||||||
char *buffer = new char[64 + localMsg.size() + file.size()];
|
// char *buffer = new char[64 + localMsg.size() + file.size()];
|
||||||
switch (type) {
|
// switch (type) {
|
||||||
case QtDebugMsg:
|
// case QtDebugMsg:
|
||||||
std::sprintf(buffer, "%s:%d: Debug: %s\n", file.constData(), line, localMsg.constData());
|
// std::sprintf(buffer, "%s:%d: Debug: %s\n", file.constData(), line, localMsg.constData());
|
||||||
XPLMDebugString(buffer);
|
// XPLMDebugString(buffer);
|
||||||
break;
|
// break;
|
||||||
case QtInfoMsg:
|
// case QtInfoMsg:
|
||||||
std::sprintf(buffer, "%s:%d: Info: %s\n", file.constData(), line, localMsg.constData());
|
// std::sprintf(buffer, "%s:%d: Info: %s\n", file.constData(), line, localMsg.constData());
|
||||||
XPLMDebugString(buffer);
|
// XPLMDebugString(buffer);
|
||||||
break;
|
// break;
|
||||||
case QtWarningMsg:
|
// case QtWarningMsg:
|
||||||
std::sprintf(buffer, "%s:%d: Warning: %s\n", file.constData(), line, localMsg.constData());
|
// std::sprintf(buffer, "%s:%d: Warning: %s\n", file.constData(), line, localMsg.constData());
|
||||||
XPLMDebugString(buffer);
|
// XPLMDebugString(buffer);
|
||||||
break;
|
// break;
|
||||||
default:
|
// default:
|
||||||
case QtCriticalMsg:
|
// case QtCriticalMsg:
|
||||||
std::sprintf(buffer, "%s:%d: Error: %s\n", file.constData(), line, localMsg.constData());
|
// std::sprintf(buffer, "%s:%d: Error: %s\n", file.constData(), line, localMsg.constData());
|
||||||
XPLMDebugString(buffer);
|
// XPLMDebugString(buffer);
|
||||||
break;
|
// break;
|
||||||
case QtFatalMsg:
|
// case QtFatalMsg:
|
||||||
std::sprintf(buffer, "%s:%d: Fatal: %s\n", file.constData(), line, localMsg.constData());
|
// std::sprintf(buffer, "%s:%d: Fatal: %s\n", file.constData(), line, localMsg.constData());
|
||||||
XPLMDebugString(buffer);
|
// XPLMDebugString(buffer);
|
||||||
std::abort();
|
// std::abort();
|
||||||
}
|
// }
|
||||||
delete[] buffer;
|
// delete[] buffer;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public:
|
//public:
|
||||||
/*!
|
// /*!
|
||||||
* Install the handler.
|
// * Install the handler.
|
||||||
*/
|
// */
|
||||||
static void install()
|
// static void install()
|
||||||
{
|
// {
|
||||||
qInstallMessageHandler(handler);
|
// qInstallMessageHandler(handler);
|
||||||
}
|
// }
|
||||||
|
|
||||||
//! Not copyable.
|
// //! Not copyable.
|
||||||
//! @{
|
// //! @{
|
||||||
QXPlaneMessageHandler(const QXPlaneMessageHandler &) = delete;
|
// QXPlaneMessageHandler(const QXPlaneMessageHandler &) = delete;
|
||||||
QXPlaneMessageHandler &operator =(const QXPlaneMessageHandler &) = delete;
|
// QXPlaneMessageHandler &operator =(const QXPlaneMessageHandler &) = delete;
|
||||||
//! @}
|
// //! @}
|
||||||
};
|
//};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* QApplication subclass used by XSwiftBus.
|
* QApplication subclass used by XSwiftBus.
|
||||||
@@ -89,101 +89,134 @@ public:
|
|||||||
* Qt framework, they can simply copy & paste this class into their project
|
* Qt framework, they can simply copy & paste this class into their project
|
||||||
* and both X-Plane plugins will be able to share a single QApplication safely.
|
* and both X-Plane plugins will be able to share a single QApplication safely.
|
||||||
*/
|
*/
|
||||||
class QSharedApplication : public QCoreApplication
|
//class QSharedApplication : public QCoreApplication
|
||||||
{
|
//{
|
||||||
Q_OBJECT
|
// Q_OBJECT
|
||||||
|
|
||||||
QWeakPointer<QCoreApplication> m_weakptr;
|
// QWeakPointer<QCoreApplication> m_weakptr;
|
||||||
|
|
||||||
QSharedApplication(QSharedPointer<QCoreApplication> &ptr, int &argc, char **argv) : QCoreApplication(argc, argv)
|
// QSharedApplication(QSharedPointer<QCoreApplication> &ptr, int &argc, char **argv) : QCoreApplication(argc, argv)
|
||||||
{
|
// {
|
||||||
ptr.reset(this);
|
// ptr.reset(this);
|
||||||
m_weakptr = ptr;
|
// m_weakptr = ptr;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static char *strdup(const char *s) { auto s2 = static_cast<char *>(std::malloc(std::strlen(s) + 1)); return std::strcpy(s2, s); }
|
// static char *strdup(const char *s) { auto s2 = static_cast<char *>(std::malloc(std::strlen(s) + 1)); return std::strcpy(s2, s); }
|
||||||
|
|
||||||
public:
|
//public:
|
||||||
/*!
|
// /*!
|
||||||
* Returns a shared pointer to the QApplication.
|
// * Returns a shared pointer to the QApplication.
|
||||||
*
|
// *
|
||||||
* The QApplication will not be destroyed while this shared pointer exists.
|
// * The QApplication will not be destroyed while this shared pointer exists.
|
||||||
*/
|
// */
|
||||||
static QSharedPointer<QCoreApplication> sharedInstance()
|
// static QSharedPointer<QCoreApplication> sharedInstance()
|
||||||
{
|
// {
|
||||||
QSharedPointer<QCoreApplication> ptr;
|
// QSharedPointer<QCoreApplication> ptr;
|
||||||
if (! instance())
|
// if (! instance())
|
||||||
{
|
// {
|
||||||
static int argc = 1;
|
// static int argc = 1;
|
||||||
static char *argv[] = { strdup("X-Plane") };
|
// static char *argv[] = { strdup("X-Plane") };
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
//#ifdef Q_OS_UNIX
|
||||||
/* Workaround for #362 */
|
// /* Workaround for #362 */
|
||||||
char* xplocale = setlocale(LC_ALL, nullptr);
|
// char* xplocale = setlocale(LC_ALL, nullptr);
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
new QSharedApplication(ptr, argc, argv);
|
// new QSharedApplication(ptr, argc, argv);
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
//#ifdef Q_OS_UNIX
|
||||||
setlocale(LC_ALL, xplocale);
|
// setlocale(LC_ALL, xplocale);
|
||||||
#endif
|
//#endif
|
||||||
}
|
// }
|
||||||
if (! instance()->inherits("QSharedApplication"))
|
// if (! instance()->inherits("QSharedApplication"))
|
||||||
{
|
// {
|
||||||
qFatal("There is an unshared QCoreApplication in another plugin");
|
// qFatal("There is an unshared QCoreApplication in another plugin");
|
||||||
}
|
// }
|
||||||
return static_cast<QSharedApplication*>(instance())->m_weakptr;
|
// return static_cast<QSharedApplication*>(instance())->m_weakptr;
|
||||||
}
|
// }
|
||||||
};
|
//};
|
||||||
|
|
||||||
/*!
|
///*!
|
||||||
* Runs the Qt event loop inside the X-Plane event loop.
|
// * Runs the Qt event loop inside the X-Plane event loop.
|
||||||
*/
|
// */
|
||||||
class QXPlaneEventLoop : public QObject
|
//class QXPlaneEventLoop : public QObject
|
||||||
{
|
//{
|
||||||
Q_OBJECT
|
// Q_OBJECT
|
||||||
|
|
||||||
QXPlaneEventLoop(QObject *parent) : QObject(parent)
|
// QXPlaneEventLoop(QObject *parent) : QObject(parent)
|
||||||
{
|
// {
|
||||||
XPLMRegisterFlightLoopCallback(callback, -1, nullptr);
|
// XPLMRegisterFlightLoopCallback(callback, -1, nullptr);
|
||||||
}
|
// }
|
||||||
|
|
||||||
~QXPlaneEventLoop()
|
// ~QXPlaneEventLoop()
|
||||||
{
|
// {
|
||||||
XPLMUnregisterFlightLoopCallback(callback, nullptr);
|
// XPLMUnregisterFlightLoopCallback(callback, nullptr);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static float callback(float, float, int, void *)
|
// static float callback(float, float, int, void *)
|
||||||
{
|
// {
|
||||||
QCoreApplication::processEvents();
|
// QCoreApplication::processEvents();
|
||||||
QCoreApplication::sendPostedEvents();
|
// QCoreApplication::sendPostedEvents();
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public:
|
//public:
|
||||||
/*!
|
// /*!
|
||||||
* Registers the X-Plane callback which calls into the Qt event loop,
|
// * Registers the X-Plane callback which calls into the Qt event loop,
|
||||||
* unless one was already registered.
|
// * unless one was already registered.
|
||||||
*/
|
// */
|
||||||
static void exec()
|
// static void exec()
|
||||||
{
|
// {
|
||||||
if (! QCoreApplication::instance()->findChild<QXPlaneEventLoop *>())
|
// if (! QCoreApplication::instance()->findChild<QXPlaneEventLoop *>())
|
||||||
{
|
// {
|
||||||
new QXPlaneEventLoop(QCoreApplication::instance());
|
// new QXPlaneEventLoop(QCoreApplication::instance());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
//};
|
||||||
|
|
||||||
namespace XSwiftBus
|
namespace XSwiftBus
|
||||||
{
|
{
|
||||||
//! Absolute xplane path
|
//! Absolute xplane path
|
||||||
extern QString g_xplanePath;
|
extern std::string g_xplanePath;
|
||||||
|
|
||||||
//! Platform specific dir separator
|
//! Platform specific dir separator
|
||||||
extern QString g_sep;
|
extern std::string g_sep;
|
||||||
|
|
||||||
//! Init global xplane path
|
//! Init global xplane path
|
||||||
void initXPlanePath();
|
void initXPlanePath();
|
||||||
|
|
||||||
|
//! Returns the directory name of a given file path
|
||||||
|
std::string getDirName(const std::string &filePath);
|
||||||
|
|
||||||
|
//! Returns the filename (including extension) of a given file path
|
||||||
|
std::string getFileName(const std::string &filePath);
|
||||||
|
|
||||||
|
//! Returns the filename without extension of a given file path
|
||||||
|
std::string getBaseName(const std::string &filePath);
|
||||||
|
|
||||||
|
//! Splits the given string maximal maxSplitCount times and returns the tokens
|
||||||
|
//! The size of the returned vector is up to maxSplitCount + 1 or less
|
||||||
|
std::vector<std::string> split(const std::string &str, size_t maxSplitCount = 0);
|
||||||
|
|
||||||
|
//! Simple logger class.
|
||||||
|
//! Don't use it directly, but the _LOG macros instead
|
||||||
|
class Logger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Message type
|
||||||
|
enum MsgType { DebugMsg, WarningMsg, FatalMsg, InfoMsg };
|
||||||
|
|
||||||
|
Logger() = delete;
|
||||||
|
|
||||||
|
//! Print message to X-Plane log
|
||||||
|
static void print(const std::string &filePath, int line, MsgType type, const std::string &message);
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Logger convenience macros
|
||||||
|
//! @{
|
||||||
|
#define DEBUG_LOG(msg) Logger::print(__FILE__, __LINE__, Logger::DebugMsg, msg)
|
||||||
|
#define INFO_LOG(msg) Logger::print(__FILE__, __LINE__, Logger::InfoMsg, msg)
|
||||||
|
//! @}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
//! \cond PRIVATE
|
//! \cond PRIVATE
|
||||||
|
|
||||||
#include "weather.h"
|
#include "weather.h"
|
||||||
#include <QDebug>
|
#include "utils.h"
|
||||||
|
|
||||||
namespace XSwiftBus
|
namespace XSwiftBus
|
||||||
{
|
{
|
||||||
@@ -37,7 +37,7 @@ namespace XSwiftBus
|
|||||||
case 0: setCloudLayerImpl(m_cloudLayer0, base, tops, type, coverage); break;
|
case 0: setCloudLayerImpl(m_cloudLayer0, base, tops, type, coverage); break;
|
||||||
case 1: setCloudLayerImpl(m_cloudLayer1, base, tops, type, coverage); break;
|
case 1: setCloudLayerImpl(m_cloudLayer1, base, tops, type, coverage); break;
|
||||||
case 2: setCloudLayerImpl(m_cloudLayer2, base, tops, type, coverage); break;
|
case 2: setCloudLayerImpl(m_cloudLayer2, base, tops, type, coverage); break;
|
||||||
default: qDebug() << "Invalid cloud layer" << layer; break;
|
default: DEBUG_LOG("Invalid cloud layer"); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ namespace XSwiftBus
|
|||||||
case 0: setWindLayerImpl(m_windLayer0, altitude, direction, speed, shearDirection, shearSpeed, turbulence); break;
|
case 0: setWindLayerImpl(m_windLayer0, altitude, direction, speed, shearDirection, shearSpeed, turbulence); break;
|
||||||
case 1: setWindLayerImpl(m_windLayer1, altitude, direction, speed, shearDirection, shearSpeed, turbulence); break;
|
case 1: setWindLayerImpl(m_windLayer1, altitude, direction, speed, shearDirection, shearSpeed, turbulence); break;
|
||||||
case 2: setWindLayerImpl(m_windLayer2, altitude, direction, speed, shearDirection, shearSpeed, turbulence); break;
|
case 2: setWindLayerImpl(m_windLayer2, altitude, direction, speed, shearDirection, shearSpeed, turbulence); break;
|
||||||
default: qDebug() << "Invalid wind layer" << layer; break;
|
default: DEBUG_LOG("Invalid wind layer"); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
load(common_pre)
|
load(common_pre)
|
||||||
|
|
||||||
QT += core gui widgets dbus network
|
|
||||||
|
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
|
|
||||||
CONFIG += shared plugin
|
CONFIG += shared plugin
|
||||||
|
CONFIG -= qt
|
||||||
|
|
||||||
INCLUDEPATH += $$EXTERNALSROOT/common/include/XPLM
|
INCLUDEPATH += $$EXTERNALSROOT/common/include/XPLM
|
||||||
|
|
||||||
@@ -107,7 +106,6 @@ INSTALLS += target
|
|||||||
|
|
||||||
dep_target.path = $$PREFIX/$$XSWIFTBUS_DIR
|
dep_target.path = $$PREFIX/$$XSWIFTBUS_DIR
|
||||||
win32 {
|
win32 {
|
||||||
dep_target.files *= $$DestRoot/lib/blackmisc.dll
|
|
||||||
dep_target.files *= $$DestRoot/bin/dbus-daemon.exe
|
dep_target.files *= $$DestRoot/bin/dbus-daemon.exe
|
||||||
win32-g++ {
|
win32-g++ {
|
||||||
dep_target.files *= $$DestRoot/bin/libdbus-1-3.dll
|
dep_target.files *= $$DestRoot/bin/libdbus-1-3.dll
|
||||||
@@ -118,12 +116,6 @@ win32 {
|
|||||||
dep_target.files *= $$DestRoot/bin/expat.dll
|
dep_target.files *= $$DestRoot/bin/expat.dll
|
||||||
dep_target.files *= $$DestRoot/bin/libevent_core.dll
|
dep_target.files *= $$DestRoot/bin/libevent_core.dll
|
||||||
}
|
}
|
||||||
dep_target.files *= $$[QT_INSTALL_BINS]/Qt5Core$${DLL_DEBUG_SUFFIX}.dll
|
|
||||||
dep_target.files *= $$[QT_INSTALL_BINS]/Qt5Gui$${DLL_DEBUG_SUFFIX}.dll
|
|
||||||
dep_target.files *= $$[QT_INSTALL_BINS]/Qt5Widgets$${DLL_DEBUG_SUFFIX}.dll
|
|
||||||
dep_target.files *= $$[QT_INSTALL_BINS]/Qt5DBus$${DLL_DEBUG_SUFFIX}.dll
|
|
||||||
dep_target.files *= $$[QT_INSTALL_BINS]/Qt5Network$${DLL_DEBUG_SUFFIX}.dll
|
|
||||||
dep_target.files *= $$[QT_INSTALL_BINS]/Qt5Xml$${DLL_DEBUG_SUFFIX}.dll
|
|
||||||
dep_target.CONFIG += no_check_exist
|
dep_target.CONFIG += no_check_exist
|
||||||
|
|
||||||
dbus_share.path = $$PREFIX/$$XSWIFTBUS_DIR/share/dbus-1
|
dbus_share.path = $$PREFIX/$$XSWIFTBUS_DIR/share/dbus-1
|
||||||
@@ -135,24 +127,8 @@ win32 {
|
|||||||
legacy_data_target.files *= LegacyData
|
legacy_data_target.files *= LegacyData
|
||||||
} else:macx: {
|
} else:macx: {
|
||||||
dep_target.files *= $$DestRoot/lib/libdbus-1.3.dylib
|
dep_target.files *= $$DestRoot/lib/libdbus-1.3.dylib
|
||||||
dep_target.files *= $$DestRoot/lib/libevent_core.2.1.8.dylib
|
|
||||||
dep_target.extra += rsync -avzl --exclude \'Headers*\' --exclude \'*debug*\' $$[QT_INSTALL_LIBS]/QtCore.framework/ $${PREFIX}/$$XSWIFTBUS_DIR/QtCore.framework/ &&
|
|
||||||
dep_target.extra += rsync -avzl --exclude \'Headers*\' --exclude \'*debug*\' $$[QT_INSTALL_LIBS]/QtGui.framework/ $${PREFIX}/$$XSWIFTBUS_DIR/QtGui.framework/ &&
|
|
||||||
dep_target.extra += rsync -avzl --exclude \'Headers*\' --exclude \'*debug*\' $$[QT_INSTALL_LIBS]/QtWidgets.framework/ $${PREFIX}/$$XSWIFTBUS_DIR/QtWidgets.framework/ &&
|
|
||||||
dep_target.extra += rsync -avzl --exclude \'Headers*\' --exclude \'*debug*\' $$[QT_INSTALL_LIBS]/QtDBus.framework/ $${PREFIX}/$$XSWIFTBUS_DIR/QtDBus.framework/ &&
|
|
||||||
dep_target.extra += rsync -avzl --exclude \'Headers*\' --exclude \'*debug*\' $$[QT_INSTALL_LIBS]/QtNetwork.framework/ $${PREFIX}/$$XSWIFTBUS_DIR/QtNetwork.framework/ &&
|
|
||||||
dep_target.extra += rsync -avzl --exclude \'Headers*\' --exclude \'*debug*\' $$[QT_INSTALL_LIBS]/QtXml.framework/ $${PREFIX}/$$XSWIFTBUS_DIR/QtXml.framework/
|
|
||||||
dep_target.CONFIG += no_check_exist
|
dep_target.CONFIG += no_check_exist
|
||||||
|
|
||||||
# Manually copy to workaround shortcomings introduced
|
|
||||||
# when qmake migrated away from GNU install in Qt 5.9
|
|
||||||
dep_target.depends += copy_blackmisc
|
|
||||||
copy_blackmisc.target = copy_blackmisc
|
|
||||||
source_path = $$PREFIX/lib/libblackmisc.0.dylib
|
|
||||||
dest_path = $$PREFIX/$$XSWIFTBUS_DIR
|
|
||||||
copy_blackmisc.commands = cp $$shell_path($$source_path) $$shell_path($$dest_path)
|
|
||||||
QMAKE_EXTRA_TARGETS += copy_blackmisc
|
|
||||||
|
|
||||||
legacy_data_target.path = $$PREFIX/xswiftbus
|
legacy_data_target.path = $$PREFIX/xswiftbus
|
||||||
legacy_data_target.files *= LegacyData
|
legacy_data_target.files *= LegacyData
|
||||||
|
|
||||||
@@ -160,48 +136,13 @@ win32 {
|
|||||||
# We cannot modify the original library since this is xswiftbus specific.
|
# We cannot modify the original library since this is xswiftbus specific.
|
||||||
legacy_data_target.depends += fix_plugin_rpath
|
legacy_data_target.depends += fix_plugin_rpath
|
||||||
fix_plugin_rpath.target = fix_plugin_rpath
|
fix_plugin_rpath.target = fix_plugin_rpath
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/libblackmisc.0.dylib\" \"@loader_path/libblackmisc.0.dylib\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/QtWidgets.framework/Versions/5/QtWidgets\" \"@loader_path/QtWidgets.framework/Versions/5/QtWidgets\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/QtGui.framework/Versions/5/QtGui\" \"@loader_path/QtGui.framework/Versions/5/QtGui\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/QtDBus.framework/Versions/5/QtDBus\" \"@loader_path/QtDBus.framework/Versions/5/QtDBus\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/QtNetwork.framework/Versions/5/QtNetwork\" \"@loader_path/QtNetwork.framework/Versions/5/QtNetwork\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/QtCore.framework/Versions/5/QtCore\" \"@loader_path/QtCore.framework/Versions/5/QtCore\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/QtXml.framework/Versions/5/QtXml\" \"@loader_path/QtXml.framework/Versions/5/QtXml\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/libblackmisc.0.dylib) &&
|
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/libevent_core.2.1.8.dylib\" \"@loader_path/libevent_core.2.1.8.dylib\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/libevent_core.2.1.8.dylib\" \"@loader_path/libevent_core.2.1.8.dylib\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl) &&
|
||||||
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/libdbus-1.3.dylib\" \"@loader_path/libdbus-1.3.dylib\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl)
|
fix_plugin_rpath.commands += install_name_tool -change \"@rpath/libdbus-1.3.dylib\" \"@loader_path/libdbus-1.3.dylib\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl)
|
||||||
QMAKE_EXTRA_TARGETS += fix_plugin_rpath
|
QMAKE_EXTRA_TARGETS += fix_plugin_rpath
|
||||||
|
|
||||||
fix_plugin_rpath.depends += fix_misc_rpath
|
|
||||||
fix_misc_rpath.target = fix_misc_rpath
|
|
||||||
fix_misc_rpath.commands += install_name_tool -id \"@loader_path/libblackmisc.0.dylib\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/libblackmisc.0.dylib) &&
|
|
||||||
fix_misc_rpath.commands += install_name_tool -change \"@rpath/QtGui.framework/Versions/5/QtGui\" \"@loader_path/QtGui.framework/Versions/5/QtGui\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/libblackmisc.0.dylib) &&
|
|
||||||
fix_misc_rpath.commands += install_name_tool -change \"@rpath/QtDBus.framework/Versions/5/QtDBus\" \"@loader_path/QtDBus.framework/Versions/5/QtDBus\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/libblackmisc.0.dylib) &&
|
|
||||||
fix_misc_rpath.commands += install_name_tool -change \"@rpath/QtNetwork.framework/Versions/5/QtNetwork\" \"@loader_path/QtNetwork.framework/Versions/5/QtNetwork\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/libblackmisc.0.dylib) &&
|
|
||||||
fix_misc_rpath.commands += install_name_tool -change \"@rpath/QtCore.framework/Versions/5/QtCore\" \"@loader_path/QtCore.framework/Versions/5/QtCore\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/libblackmisc.0.dylib) &&
|
|
||||||
fix_misc_rpath.commands += install_name_tool -change \"@rpath/QtXml.framework/Versions/5/QtXml\" \"@loader_path/QtXml.framework/Versions/5/QtXml\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/libblackmisc.0.dylib)
|
|
||||||
QMAKE_EXTRA_TARGETS += fix_misc_rpath
|
|
||||||
|
|
||||||
} else:unix: {
|
} else:unix: {
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libQt5Core.so.5
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libQt5Gui.so.5
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libQt5Widgets.so.5
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libQt5DBus.so.5
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libQt5Network.so.5
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libQt5Xml.so.5
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libicui18n.so.56
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libicuuc.so.56
|
|
||||||
dep_target.files *= $$[QT_INSTALL_LIBS]/libicudata.so.56
|
|
||||||
dep_target.CONFIG += no_check_exist
|
dep_target.CONFIG += no_check_exist
|
||||||
|
|
||||||
# Manually copy to workaround shortcomings introduced
|
|
||||||
# when qmake migrated away from GNU install in Qt 5.9
|
|
||||||
dep_target.depends += copy_blackmisc
|
|
||||||
copy_blackmisc.target = copy_blackmisc
|
|
||||||
source_path = $$PREFIX/lib/libblackmisc.so.0
|
|
||||||
dest_path = $$PREFIX/$$XSWIFTBUS_DIR
|
|
||||||
copy_blackmisc.commands = cp $$shell_path($$source_path) $$shell_path($$dest_path)
|
|
||||||
QMAKE_EXTRA_TARGETS += copy_blackmisc
|
|
||||||
|
|
||||||
legacy_data_target.path = $$PREFIX/xswiftbus
|
legacy_data_target.path = $$PREFIX/xswiftbus
|
||||||
legacy_data_target.files *= LegacyData
|
legacy_data_target.files *= LegacyData
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user