mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-02 23:25:53 +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"));
|
||||
connect(&m_fastTimer, &QTimer::timeout, this, &CSimulatorXPlane::fastTimerTimeout);
|
||||
connect(&m_slowTimer, &QTimer::timeout, this, &CSimulatorXPlane::slowTimerTimeout);
|
||||
connect(&m_airportUpdater, &QTimer::timeout, this, &CSimulatorXPlane::updateAirportsInRange);
|
||||
m_fastTimer.start(100);
|
||||
m_slowTimer.start(1000);
|
||||
m_airportUpdater.start(60000);
|
||||
|
||||
this->setDefaultModel({ "Jets A320_a A320_a_Austrian_Airlines A320_a_Austrian_Airlines", CAircraftModel::TypeModelMatchingDefaultModel,
|
||||
"A320 AUA", CAircraftIcaoCode("A320", "L2J")});
|
||||
@@ -793,6 +795,11 @@ namespace BlackSimPlugin
|
||||
this->rememberElevationAndCG(callsign, elevation, CLength(modelVerticalOffsetMeters, CLengthUnit::m()));
|
||||
}
|
||||
|
||||
void CSimulatorXPlane::updateAirportsInRange()
|
||||
{
|
||||
if (this->isConnected()) { m_serviceProxy->updateAirportsInRange(); }
|
||||
}
|
||||
|
||||
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,
|
||||
IOwnAircraftProvider *ownAircraftProvider,
|
||||
IRemoteAircraftProvider *remoteAircraftProvider,
|
||||
|
||||
@@ -190,6 +190,7 @@ namespace BlackSimPlugin
|
||||
|
||||
void requestRemoteAircraftDataFromXPlane();
|
||||
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
|
||||
|
||||
@@ -201,6 +202,7 @@ namespace BlackSimPlugin
|
||||
CXSwiftBusWeatherProxy *m_weatherProxy { nullptr };
|
||||
QTimer m_fastTimer;
|
||||
QTimer m_slowTimer;
|
||||
QTimer m_airportUpdater;
|
||||
BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft
|
||||
BlackMisc::CData<BlackMisc::Simulation::Data::TModelSetCacheXP> m_modelSet { this };
|
||||
|
||||
|
||||
@@ -20,17 +20,6 @@
|
||||
#define XPLM_MSG_LIVERY_LOADED 108
|
||||
#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;
|
||||
|
||||
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()
|
||||
{
|
||||
QXPlaneMessageHandler::install();
|
||||
g_qApp = QSharedApplication::sharedInstance();
|
||||
QXPlaneEventLoop::exec();
|
||||
|
||||
g_plugin = new XSwiftBus::CPlugin;
|
||||
return 1;
|
||||
}
|
||||
@@ -65,7 +50,6 @@ PLUGIN_API int XPluginEnable()
|
||||
PLUGIN_API void XPluginDisable()
|
||||
{
|
||||
delete g_plugin;
|
||||
g_qApp.reset();
|
||||
}
|
||||
|
||||
PLUGIN_API void XPluginReceiveMessage(XPLMPluginID from, long msg, void *param)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "weather.h"
|
||||
#include "utils.h"
|
||||
#include "XPLM/XPLMProcessing.h"
|
||||
#include <QTimer>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
|
||||
@@ -71,6 +70,8 @@ namespace XSwiftBus
|
||||
m_service = new CService(m_dbusConnection.get());
|
||||
m_traffic = new CTraffic(m_dbusConnection.get());
|
||||
m_weather = new CWeather(m_dbusConnection.get());
|
||||
|
||||
INFO_LOG("XSwiftBus started.");
|
||||
}
|
||||
|
||||
void CPlugin::onAircraftModelChanged()
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#endif
|
||||
#include "dbusconnection.h"
|
||||
#include "menus.h"
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
@@ -36,10 +34,8 @@ namespace XSwiftBus
|
||||
/*!
|
||||
* Main plugin class
|
||||
*/
|
||||
class CPlugin : public QObject
|
||||
class CPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
CPlugin();
|
||||
|
||||
@@ -10,11 +10,8 @@
|
||||
#include "service.h"
|
||||
#include <XPLM/XPLMPlanes.h>
|
||||
#include <XPLM/XPLMUtilities.h>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringBuilder>
|
||||
#include <QDir>
|
||||
#include <fstream>
|
||||
#include "utils.h"
|
||||
|
||||
// clazy:excludeall=reserve-candidates
|
||||
|
||||
@@ -25,9 +22,6 @@ namespace XSwiftBus
|
||||
{
|
||||
registerDBusObjectPath(XSWIFTBUS_SERVICE_INTERFACENAME, XSWIFTBUS_SERVICE_OBJECTPATH);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -36,35 +30,38 @@ namespace XSwiftBus
|
||||
char filename[256];
|
||||
char path[512];
|
||||
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());
|
||||
}
|
||||
|
||||
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; }
|
||||
int lineLength = m_messages.maxLineLength() - 1;
|
||||
QStringList wrappedLines;
|
||||
for (int i = 0; i < text.size(); i += lineLength)
|
||||
if (text.empty()) { return; }
|
||||
static const std::string ellipsis = "...";
|
||||
int lineLength = m_messages.maxLineLength() - ellipsis.size();
|
||||
std::vector<std::string> wrappedLines;
|
||||
for (size_t i = 0; i < text.size(); i += lineLength)
|
||||
{
|
||||
static const QChar ellipsis = 0x2026;
|
||||
wrappedLines.push_back(text.mid(i, lineLength) + ellipsis);
|
||||
// static const QChar ellipsis = 0x2026;
|
||||
// wrappedLines.push_back(QString::fromStdString(text).mid(i, lineLength) + ellipsis);
|
||||
wrappedLines.push_back(text.substr(i, lineLength) + ellipsis);
|
||||
}
|
||||
wrappedLines.back().chop(1);
|
||||
if (wrappedLines.back().isEmpty()) { wrappedLines.pop_back(); }
|
||||
else if (wrappedLines.back().size() == 1 && wrappedLines.size() > 1)
|
||||
wrappedLines.back().erase(wrappedLines.back().size() - 3);
|
||||
if (wrappedLines.back().empty()) { wrappedLines.pop_back(); }
|
||||
else if (wrappedLines.back().size() == ellipsis.size() && wrappedLines.size() > 1)
|
||||
{
|
||||
(wrappedLines.end() - 2)->chop(1);
|
||||
(wrappedLines.end() - 2)->append(wrappedLines.back());
|
||||
auto secondLastLine = wrappedLines.end() - 2;
|
||||
secondLastLine->erase(wrappedLines.back().size() - 3);
|
||||
secondLastLine->append(wrappedLines.back());
|
||||
wrappedLines.pop_back();
|
||||
}
|
||||
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 path[512];
|
||||
@@ -72,7 +69,7 @@ namespace XSwiftBus
|
||||
return path;
|
||||
}
|
||||
|
||||
QString CService::getAircraftModelFilename() const
|
||||
std::string CService::getAircraftModelFilename() const
|
||||
{
|
||||
char filename[256];
|
||||
char path[512];
|
||||
@@ -80,21 +77,21 @@ namespace XSwiftBus
|
||||
return filename;
|
||||
}
|
||||
|
||||
QString CService::getAircraftModelString() const
|
||||
std::string CService::getAircraftModelString() const
|
||||
{
|
||||
char filename[256];
|
||||
char path[512];
|
||||
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
||||
const auto model = extractAcfProperties(path, QFileInfo(path));
|
||||
const auto model = extractAcfProperties(path);
|
||||
return model.getModelString();
|
||||
}
|
||||
|
||||
QString CService::getAircraftName() const
|
||||
std::string CService::getAircraftName() const
|
||||
{
|
||||
char filename[256];
|
||||
char path[512];
|
||||
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
|
||||
const auto model = extractAcfProperties(path, QFileInfo(path));
|
||||
const auto model = extractAcfProperties(path);
|
||||
return model.getName();
|
||||
}
|
||||
|
||||
@@ -114,14 +111,14 @@ namespace XSwiftBus
|
||||
return version % 100;
|
||||
}
|
||||
|
||||
QString CService::getXPlaneInstallationPath() const
|
||||
std::string CService::getXPlaneInstallationPath() const
|
||||
{
|
||||
char path[512];
|
||||
XPLMGetSystemPath(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
QString CService::getXPlanePreferencesPath() const
|
||||
std::string CService::getXPlanePreferencesPath() const
|
||||
{
|
||||
char path[512];
|
||||
XPLMGetPrefsPath(path);
|
||||
@@ -206,7 +203,7 @@ namespace XSwiftBus
|
||||
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
addTextMessage(QString::fromStdString(text), red, green, blue);
|
||||
addTextMessage(text, red, green, blue);
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getOwnAircraftSituationData")
|
||||
@@ -246,49 +243,49 @@ namespace XSwiftBus
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getAircraftModelPath().toStdString());
|
||||
sendDBusReply(sender, serial, getAircraftModelPath());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getAircraftModelFilename")
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getAircraftModelFilename().toStdString());
|
||||
sendDBusReply(sender, serial, getAircraftModelFilename());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getAircraftModelString")
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getAircraftModelString().toStdString());
|
||||
sendDBusReply(sender, serial, getAircraftModelString());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getAircraftName")
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getAircraftName().toStdString());
|
||||
sendDBusReply(sender, serial, getAircraftName());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getAircraftLivery")
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getAircraftLivery().toStdString());
|
||||
sendDBusReply(sender, serial, getAircraftLivery());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getAircraftIcaoCode")
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getAircraftIcaoCode().toStdString());
|
||||
sendDBusReply(sender, serial, getAircraftIcaoCode());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getAircraftDescription")
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getAircraftDescription().toStdString());
|
||||
sendDBusReply(sender, serial, getAircraftDescription());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getXPlaneVersionMajor")
|
||||
@@ -309,14 +306,14 @@ namespace XSwiftBus
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getXPlaneInstallationPath().toStdString());
|
||||
sendDBusReply(sender, serial, getXPlaneInstallationPath());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "getXPlanePreferencesPath")
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
sendDBusReply(sender, serial, getXPlanePreferencesPath().toStdString());
|
||||
sendDBusReply(sender, serial, getXPlanePreferencesPath());
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "isPaused")
|
||||
@@ -599,7 +596,7 @@ namespace XSwiftBus
|
||||
{
|
||||
queueDBusCall([=]()
|
||||
{
|
||||
std::vector<double> array = getEngineN1Percentage().toVector().toStdVector();
|
||||
std::vector<double> array = getEngineN1Percentage();
|
||||
sendDBusReply(sender, serial, array);
|
||||
});
|
||||
}
|
||||
@@ -633,19 +630,19 @@ namespace XSwiftBus
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CService::emitAircraftModelChanged(const QString &path, const QString &filename, const QString &livery,
|
||||
const QString &icao, const QString &modelString, const QString &name,
|
||||
const QString &description)
|
||||
void CService::emitAircraftModelChanged(const std::string &path, const std::string &filename, const std::string &livery,
|
||||
const std::string &icao, const std::string &modelString, const std::string &name,
|
||||
const std::string &description)
|
||||
{
|
||||
CDBusMessage signalAircraftModelChanged = CDBusMessage::createSignal(XSWIFTBUS_SERVICE_OBJECTPATH, XSWIFTBUS_SERVICE_INTERFACENAME, "aircraftModelChanged");
|
||||
signalAircraftModelChanged.beginArgumentWrite();
|
||||
signalAircraftModelChanged.appendArgument(path.toStdString());
|
||||
signalAircraftModelChanged.appendArgument(filename.toStdString());
|
||||
signalAircraftModelChanged.appendArgument(livery.toStdString());
|
||||
signalAircraftModelChanged.appendArgument(icao.toStdString());
|
||||
signalAircraftModelChanged.appendArgument(modelString.toStdString());
|
||||
signalAircraftModelChanged.appendArgument(name.toStdString());
|
||||
signalAircraftModelChanged.appendArgument(description.toStdString());
|
||||
signalAircraftModelChanged.appendArgument(path);
|
||||
signalAircraftModelChanged.appendArgument(filename);
|
||||
signalAircraftModelChanged.appendArgument(livery);
|
||||
signalAircraftModelChanged.appendArgument(icao);
|
||||
signalAircraftModelChanged.appendArgument(modelString);
|
||||
signalAircraftModelChanged.appendArgument(name);
|
||||
signalAircraftModelChanged.appendArgument(description);
|
||||
sendDBusMessage(signalAircraftModelChanged);
|
||||
}
|
||||
|
||||
@@ -676,105 +673,115 @@ namespace XSwiftBus
|
||||
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
|
||||
{
|
||||
return QStringLiteral("[ACF] ") % model.getName();
|
||||
return std::string("[ACF] ") + model.getName();
|
||||
}
|
||||
}
|
||||
else if (model.hasAircraftDesignator())
|
||||
{
|
||||
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
|
||||
{
|
||||
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.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();
|
||||
}
|
||||
else
|
||||
{
|
||||
return model.getDistributor().getDescription() % ' ' % model.getName();
|
||||
return model.getDistributor().getDescription() + ' ' + model.getName();
|
||||
}
|
||||
}
|
||||
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;
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return model; }
|
||||
|
||||
QTextStream ts(&file);
|
||||
if (ts.readLine() == "I" && ts.readLine().contains("version") && ts.readLine() == "ACF")
|
||||
std::ifstream fs(filePath, std::ios::in | std::ios::binary);
|
||||
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();
|
||||
QVector<QStringRef> tokens = line.splitRef(' ', QString::SkipEmptyParts);
|
||||
if (tokens.size() < 3 || tokens.at(0) != QLatin1String("P")) { continue; }
|
||||
if (tokens.at(1) == QLatin1String("acf/_ICAO"))
|
||||
auto tokens = split(line, 2);
|
||||
if (tokens.size() < 3 || tokens.at(0) != "P") { continue; }
|
||||
if (tokens.at(1) == "acf/_ICAO")
|
||||
{
|
||||
const QString icao(tokens.at(2).toString());
|
||||
const std::string icao(tokens.at(2));
|
||||
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()));
|
||||
model.setDescription("[ACF] " % desc);
|
||||
const std::string desc(tokens.at(2));
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else if (tokens.at(1) == QLatin1String("acf/_author"))
|
||||
else if (tokens.at(1) == "acf/_author")
|
||||
{
|
||||
if (model.getDistributor().hasDescription()) { continue; }
|
||||
thread_local const QRegularExpression end("\\W\\s", QRegularExpression::UseUnicodePropertiesOption);
|
||||
QString author = line.mid(tokens.at(2).position());
|
||||
author = author.left(author.indexOf(end)).trimmed();
|
||||
if (author.isEmpty()) { continue; }
|
||||
std::string author = tokens.at(2);
|
||||
size_t pos = author.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_");
|
||||
author = author.substr(0, pos);
|
||||
if (author.empty()) { continue; }
|
||||
const CDistributor dist(author);
|
||||
model.setDistributor(dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
model.setModelString(stringForFlyableModel(model, fileInfo));
|
||||
fs.close();
|
||||
|
||||
model.setModelString(stringForFlyableModel(model, filePath));
|
||||
if (!model.hasDescription()) { model.setDescription(descriptionForFlyableModel(model)); }
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -21,12 +21,7 @@
|
||||
#include "messages.h"
|
||||
#include "navdatareference.h"
|
||||
#include <XPLM/XPLMNavigation.h>
|
||||
#include <QStringList>
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QFileInfo>
|
||||
|
||||
class QTimer;
|
||||
#include <string>
|
||||
|
||||
//! \cond PRIVATE
|
||||
#define XSWIFTBUS_SERVICE_INTERFACENAME "org.swift_project.xswiftbus.service"
|
||||
@@ -40,15 +35,20 @@ namespace XSwiftBus
|
||||
class CDistributor
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
CDistributor() = default;
|
||||
CDistributor(const QString &distributor) : m_distributor(distributor) {}
|
||||
|
||||
bool hasDescription() const { return !m_description.isEmpty(); }
|
||||
QString getDescription() const { return m_description; }
|
||||
//! Constructor
|
||||
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:
|
||||
QString m_distributor;
|
||||
QString m_description;
|
||||
std::string m_description;
|
||||
};
|
||||
|
||||
//! Simplified implementation of \sa BlackMisc::Simulation::CAircraftModel
|
||||
@@ -58,44 +58,44 @@ namespace XSwiftBus
|
||||
CAircraftModel() = default;
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasDescription
|
||||
bool hasDescription() const { return !m_description.isEmpty(); }
|
||||
bool hasDescription() const { return !m_description.empty(); }
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasAircraftDesignator
|
||||
bool hasAircraftDesignator() const { return !m_icao.isEmpty(); }
|
||||
bool hasAircraftDesignator() const { return !m_icao.empty(); }
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getName
|
||||
QString getName() const { return m_name; }
|
||||
std::string getName() const { return m_name; }
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getDistributor
|
||||
CDistributor getDistributor() const { return m_distributor; }
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getAircraftIcaoCodeDesignator
|
||||
QString getAircraftIcaoCodeDesignator() const { return m_icao; }
|
||||
std::string getAircraftIcaoCodeDesignator() const { return m_icao; }
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::getModelString
|
||||
QString getModelString() const { return m_modelString; }
|
||||
std::string getModelString() const { return m_modelString; }
|
||||
|
||||
//! \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
|
||||
void setDescription(const QString &description) { m_description = description; }
|
||||
void setDescription(const std::string &description) { m_description = description; }
|
||||
|
||||
//! \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
|
||||
void setDistributor(const CDistributor &distributor) { m_distributor = distributor; }
|
||||
|
||||
//! \copydoc BlackMisc::Simulation::CAircraftModel::setModelString
|
||||
void setModelString(const QString &modelString) { m_modelString = modelString; }
|
||||
void setModelString(const std::string &modelString) { m_modelString = modelString; }
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_icao;
|
||||
QString m_description;
|
||||
std::string m_name;
|
||||
std::string m_icao;
|
||||
std::string m_description;
|
||||
CDistributor m_distributor;
|
||||
QString m_modelString;
|
||||
std::string m_modelString;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -111,16 +111,16 @@ namespace XSwiftBus
|
||||
~CService() override = default;
|
||||
|
||||
//! 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;
|
||||
}
|
||||
|
||||
//! 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;
|
||||
}
|
||||
|
||||
@@ -128,31 +128,31 @@ namespace XSwiftBus
|
||||
void onAircraftModelChanged();
|
||||
|
||||
//! 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.
|
||||
void updateAirportsInRange();
|
||||
|
||||
//! Get full path to current aircraft model
|
||||
QString getAircraftModelPath() const;
|
||||
std::string getAircraftModelPath() const;
|
||||
|
||||
//! Get base filename of current aircraft model
|
||||
QString getAircraftModelFilename() const;
|
||||
std::string getAircraftModelFilename() const;
|
||||
|
||||
//! Get canonical swift model string of current aircraft model
|
||||
QString getAircraftModelString() const;
|
||||
std::string getAircraftModelString() const;
|
||||
|
||||
//! Get name of current aircraft model
|
||||
QString getAircraftName() const;
|
||||
std::string getAircraftName() const;
|
||||
|
||||
//! 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
|
||||
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
|
||||
QString getAircraftDescription() const { return m_descrip.get().c_str(); }
|
||||
std::string getAircraftDescription() const { return m_descrip.get(); }
|
||||
|
||||
//! Get major version number
|
||||
int getXPlaneVersionMajor() const;
|
||||
@@ -161,10 +161,10 @@ namespace XSwiftBus
|
||||
int getXPlaneVersionMinor() const;
|
||||
|
||||
//! Get root of X-Plane install path
|
||||
QString getXPlaneInstallationPath() const;
|
||||
std::string getXPlaneInstallationPath() const;
|
||||
|
||||
//! Get full path to X-Plane preferences file
|
||||
QString getXPlanePreferencesPath() const;
|
||||
std::string getXPlanePreferencesPath() const;
|
||||
|
||||
//! True if sim is paused
|
||||
bool isPaused() const { return m_paused.get(); }
|
||||
@@ -275,14 +275,14 @@ namespace XSwiftBus
|
||||
int getNumberOfEngines() const { return m_numberOfEngines.get(); }
|
||||
|
||||
//! Get the N1 speed as percent of max (per engine)
|
||||
QList<double> getEngineN1Percentage() const
|
||||
std::vector<double> getEngineN1Percentage() const
|
||||
{
|
||||
QList<double> list;
|
||||
const int number = getNumberOfEngines();
|
||||
std::vector<double> list;
|
||||
const auto number = static_cast<unsigned int>(getNumberOfEngines());
|
||||
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;
|
||||
}
|
||||
@@ -299,21 +299,20 @@ namespace XSwiftBus
|
||||
DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) override;
|
||||
|
||||
private:
|
||||
void emitAircraftModelChanged(const QString &path, const QString &filename, const QString &livery,
|
||||
const QString &icao, const QString &modelString, const QString &name,
|
||||
const QString &description);
|
||||
void emitAircraftModelChanged(const std::string &path, const std::string &filename, const std::string &livery,
|
||||
const std::string &icao, const std::string &modelString, const std::string &name,
|
||||
const std::string &description);
|
||||
|
||||
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);
|
||||
|
||||
CMessageBoxControl m_messages { 128, 128, 16 };
|
||||
std::vector<CNavDataReference> m_airports;
|
||||
QTimer *m_airportUpdater = nullptr;
|
||||
void readAirportsDatabase();
|
||||
|
||||
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_ICAO> m_icao;
|
||||
|
||||
@@ -18,18 +18,17 @@
|
||||
#include "XPMPPlaneRenderer.h"
|
||||
#include <XPLM/XPLMProcessing.h>
|
||||
#include <XPLM/XPLMUtilities.h>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
|
||||
// clazy:excludeall=reserve-candidates
|
||||
|
||||
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_)
|
||||
{
|
||||
std::memset(static_cast<void *>(&surfaces), 0, sizeof(surfaces));
|
||||
@@ -38,8 +37,9 @@ namespace XSwiftBus
|
||||
surfaces.size = sizeof(surfaces);
|
||||
xpdr.size = sizeof(xpdr);
|
||||
|
||||
std::strncpy(label, qPrintable(callsign), sizeof(label));
|
||||
surfaces.lights.timeOffset = static_cast<quint16>(qrand() % 0xffff);
|
||||
std::strncpy(label, callsign.c_str(), sizeof(label));
|
||||
std::srand(static_cast<unsigned int>(std::time(nullptr)));
|
||||
surfaces.lights.timeOffset = static_cast<uint16_t>(std::rand() % 0xffff);
|
||||
}
|
||||
|
||||
CTraffic::CTraffic(CDBusConnection *dbusConnection) :
|
||||
@@ -60,8 +60,12 @@ namespace XSwiftBus
|
||||
initXPlanePath();
|
||||
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"),
|
||||
qPrintable(dir + "lights.png"), qPrintable(dir + "Doc8643.txt"), "C172", preferences, preferences);
|
||||
std::string csl = dir + "CSL";
|
||||
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; }
|
||||
}
|
||||
|
||||
@@ -70,7 +74,7 @@ namespace XSwiftBus
|
||||
if (! s_legacyDataOK) { return false; }
|
||||
|
||||
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; }
|
||||
m_initialized = true;
|
||||
|
||||
@@ -104,11 +108,11 @@ namespace XSwiftBus
|
||||
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");
|
||||
signalRemoteAircraftData.beginArgumentWrite();
|
||||
signalRemoteAircraftData.appendArgument(callsign.toStdString());
|
||||
signalRemoteAircraftData.appendArgument(callsign);
|
||||
signalRemoteAircraftData.appendArgument(latitude);
|
||||
signalRemoteAircraftData.appendArgument(longitude);
|
||||
signalRemoteAircraftData.appendArgument(elevation);
|
||||
@@ -141,19 +145,21 @@ namespace XSwiftBus
|
||||
return def;
|
||||
}
|
||||
|
||||
bool CTraffic::loadPlanesPackage(const QString &path)
|
||||
bool CTraffic::loadPlanesPackage(const std::string &path)
|
||||
{
|
||||
initXPlanePath();
|
||||
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; }
|
||||
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)
|
||||
@@ -183,16 +189,16 @@ namespace XSwiftBus
|
||||
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;
|
||||
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
|
||||
{
|
||||
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)
|
||||
@@ -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);
|
||||
if (!plane) { return; }
|
||||
m_planesByCallsign.remove(callsign);
|
||||
m_planesById.remove(plane->id);
|
||||
auto planeIt = m_planesByCallsign.find(callsign);
|
||||
if (planeIt == m_planesByCallsign.end()) { return; }
|
||||
|
||||
Plane *plane = planeIt->second;
|
||||
m_planesByCallsign.erase(callsign);
|
||||
m_planesById.erase(plane->id);
|
||||
XPMPDestroyPlane(plane->id);
|
||||
delete plane;
|
||||
}
|
||||
|
||||
void CTraffic::removeAllPlanes()
|
||||
{
|
||||
const QList<Plane *> planes = m_planesByCallsign.values();
|
||||
for (Plane *plane : planes)
|
||||
for (const auto &kv : m_planesByCallsign)
|
||||
{
|
||||
Plane *plane = kv.second;
|
||||
assert(plane);
|
||||
XPMPDestroyPlane(plane->id);
|
||||
delete plane;
|
||||
@@ -226,9 +234,12 @@ namespace XSwiftBus
|
||||
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; }
|
||||
plane->position.lat = latitude;
|
||||
plane->position.lon = longitude;
|
||||
@@ -238,11 +249,14 @@ namespace XSwiftBus
|
||||
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)
|
||||
{
|
||||
Q_UNUSED(onGround);
|
||||
Plane *plane = m_planesByCallsign.value(callsign, nullptr);
|
||||
(void) onGround;
|
||||
auto planeIt = m_planesByCallsign.find(callsign);
|
||||
if (planeIt == m_planesByCallsign.end()) { return; }
|
||||
|
||||
Plane *plane = planeIt->second;
|
||||
if (!plane) { return; }
|
||||
|
||||
plane->hasSurfaces = true;
|
||||
@@ -263,9 +277,12 @@ namespace XSwiftBus
|
||||
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; }
|
||||
plane->hasXpdr = true;
|
||||
plane->xpdr.code = code;
|
||||
@@ -277,9 +294,9 @@ namespace XSwiftBus
|
||||
void CTraffic::requestRemoteAircraftData()
|
||||
{
|
||||
if (m_planesByCallsign.empty()) { return; }
|
||||
const QList<Plane *> planes = m_planesByCallsign.values();
|
||||
for (const Plane *plane : planes)
|
||||
for (const auto &kv : m_planesByCallsign)
|
||||
{
|
||||
Plane *plane = kv.second;
|
||||
assert(plane);
|
||||
double lat = plane->position.lat;
|
||||
double lon = plane->position.lon;
|
||||
@@ -287,7 +304,7 @@ namespace XSwiftBus
|
||||
double groundElevation = plane->terrainProbe.getElevation(lat, lon, elevation);
|
||||
if (std::isnan(groundElevation)) { groundElevation = 0.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);
|
||||
}
|
||||
}
|
||||
@@ -332,7 +349,7 @@ namespace XSwiftBus
|
||||
message.getArgument(path);
|
||||
queueDBusCall([ = ]()
|
||||
{
|
||||
sendDBusReply(sender, serial, loadPlanesPackage(QString::fromStdString(path)));
|
||||
sendDBusReply(sender, serial, loadPlanesPackage(path));
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "setDefaultIcao")
|
||||
@@ -342,7 +359,7 @@ namespace XSwiftBus
|
||||
message.getArgument(defaultIcao);
|
||||
queueDBusCall([ = ]()
|
||||
{
|
||||
setDefaultIcao(QString::fromStdString(defaultIcao));
|
||||
setDefaultIcao(defaultIcao);
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "setDrawingLabels")
|
||||
@@ -404,7 +421,7 @@ namespace XSwiftBus
|
||||
|
||||
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")
|
||||
@@ -415,7 +432,7 @@ namespace XSwiftBus
|
||||
message.getArgument(callsign);
|
||||
queueDBusCall([ = ]()
|
||||
{
|
||||
removePlane(QString::fromStdString(callsign));
|
||||
removePlane(callsign);
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "removeAllPlanes")
|
||||
@@ -446,7 +463,7 @@ namespace XSwiftBus
|
||||
message.getArgument(heading);
|
||||
queueDBusCall([ = ]()
|
||||
{
|
||||
setPlanePosition(QString::fromStdString(callsign), latitude, longitude, altitude, pitch, roll, heading);
|
||||
setPlanePosition(callsign, latitude, longitude, altitude, pitch, roll, heading);
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "setPlaneSurfaces")
|
||||
@@ -489,7 +506,7 @@ namespace XSwiftBus
|
||||
message.getArgument(onGround);
|
||||
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,
|
||||
onGround);
|
||||
});
|
||||
@@ -508,7 +525,7 @@ namespace XSwiftBus
|
||||
message.getArgument(ident);
|
||||
queueDBusCall([ = ]()
|
||||
{
|
||||
setPlaneTransponder(QString::fromStdString(callsign), code, modeC, ident);
|
||||
setPlaneTransponder(callsign, code, modeC, ident);
|
||||
});
|
||||
}
|
||||
else if (message.getMethodName() == "requestRemoteAircraftData")
|
||||
@@ -546,8 +563,9 @@ namespace XSwiftBus
|
||||
|
||||
int CTraffic::getPlaneData(void *id, int dataType, void *io_data)
|
||||
{
|
||||
QHash<void *, Plane *> planesById = m_planesById;
|
||||
Plane *plane = m_planesById.value(id, nullptr);
|
||||
auto planeIt = m_planesById.find(id);
|
||||
assert(planeIt != m_planesById.end());
|
||||
Plane *plane = planeIt->second;
|
||||
if (!plane) { return xpmpData_Unavailable; }
|
||||
|
||||
switch (dataType)
|
||||
@@ -568,18 +586,20 @@ namespace XSwiftBus
|
||||
case xpmpDataType_Surfaces:
|
||||
if (plane->hasSurfaces)
|
||||
{
|
||||
const auto currentTime = QDateTime::currentMSecsSinceEpoch();
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
|
||||
if (plane->surfaces.gearPosition != plane->targetGearPosition)
|
||||
{
|
||||
// interpolate gear position
|
||||
constexpr float gearMoveTimeMs = 5000;
|
||||
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 = 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);
|
||||
|
||||
if (memcmpPayload(io_surfaces, &plane->surfaces))
|
||||
|
||||
@@ -15,11 +15,6 @@
|
||||
#include "dbusobject.h"
|
||||
#include "datarefs.h"
|
||||
#include "terrainprobe.h"
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QVector>
|
||||
#include <QStringList>
|
||||
#include "XPMPMultiplayer.h"
|
||||
#include <XPLM/XPLMDisplay.h>
|
||||
#include <functional>
|
||||
@@ -42,19 +37,19 @@ namespace XSwiftBus
|
||||
CTraffic(CDBusConnection *dbusConnection);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CTraffic();
|
||||
~CTraffic() override;
|
||||
|
||||
//! 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;
|
||||
}
|
||||
|
||||
//! 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;
|
||||
}
|
||||
|
||||
@@ -68,10 +63,10 @@ namespace XSwiftBus
|
||||
void cleanup();
|
||||
|
||||
//! 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
|
||||
void setDefaultIcao(const QString &defaultIcao);
|
||||
void setDefaultIcao(const std::string &defaultIcao);
|
||||
|
||||
//! Set whether the plugin draws type and callsign labels above aircraft
|
||||
void setDrawingLabels(bool drawing);
|
||||
@@ -86,23 +81,23 @@ namespace XSwiftBus
|
||||
void setMaxDrawDistance(double nauticalMiles);
|
||||
|
||||
//! 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
|
||||
void removePlane(const QString &callsign);
|
||||
void removePlane(const std::string &callsign);
|
||||
|
||||
//! Remove all traffic aircraft
|
||||
void removeAllPlanes();
|
||||
|
||||
//! 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
|
||||
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);
|
||||
|
||||
//! 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
|
||||
void requestRemoteAircraftData();
|
||||
@@ -117,7 +112,7 @@ namespace XSwiftBus
|
||||
bool m_enabled = false;
|
||||
|
||||
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 float preferences(const char *section, const char *name, float def);
|
||||
@@ -125,26 +120,27 @@ namespace XSwiftBus
|
||||
struct Plane
|
||||
{
|
||||
void *id = nullptr;
|
||||
QString callsign;
|
||||
QString aircraftIcao;
|
||||
QString airlineIcao;
|
||||
QString livery;
|
||||
QString modelName;
|
||||
std::string callsign;
|
||||
std::string aircraftIcao;
|
||||
std::string airlineIcao;
|
||||
std::string livery;
|
||||
std::string modelName;
|
||||
bool hasSurfaces = false;
|
||||
bool hasXpdr = false;
|
||||
char label[32] {};
|
||||
CTerrainProbe terrainProbe;
|
||||
XPMPPlaneSurfaces_t surfaces;
|
||||
float targetGearPosition = 0;
|
||||
qint64 prevSurfacesLerpTime = 0;
|
||||
std::chrono::system_clock::time_point prevSurfacesLerpTime;
|
||||
XPMPPlaneRadar_t xpdr;
|
||||
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;
|
||||
QHash<void *, Plane *> m_planesById;
|
||||
qint64 m_timestampLastSimFrame = QDateTime::currentMSecsSinceEpoch();
|
||||
std::unordered_map<std::string, Plane *> m_planesByCallsign;
|
||||
std::unordered_map<void *, Plane *> m_planesById;
|
||||
std::chrono::system_clock::time_point m_timestampLastSimFrame = std::chrono::system_clock::now();
|
||||
|
||||
int getPlaneData(void *id, int dataType, void *io_data);
|
||||
static int getPlaneData(void *id, int dataType, void *io_data, void *self)
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
|
||||
#include "utils.h"
|
||||
#include <XPMPMultiplayerCSL.h>
|
||||
#include <QString>
|
||||
#include <QtGlobal>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace XSwiftBus
|
||||
{
|
||||
|
||||
QString g_xplanePath;
|
||||
QString g_sep;
|
||||
std::string g_xplanePath;
|
||||
std::string g_sep;
|
||||
|
||||
//! Init global xplane path
|
||||
void initXPlanePath()
|
||||
{
|
||||
if (!g_xplanePath.isEmpty() && !g_sep.isEmpty()) {}
|
||||
if (!g_xplanePath.empty() && !g_sep.empty()) {}
|
||||
|
||||
char xplanePath[512];
|
||||
XPLMGetSystemPath(xplanePath);
|
||||
@@ -43,6 +43,116 @@ namespace XSwiftBus
|
||||
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
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
#include <XPLM/XPLMPlugin.h>
|
||||
#include <XPLM/XPLMProcessing.h>
|
||||
#include <XPLM/XPLMUtilities.h>
|
||||
#include <QCoreApplication>
|
||||
#include <QSharedPointer>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <clocale>
|
||||
#include <string>
|
||||
|
||||
/*!
|
||||
* \file
|
||||
@@ -28,58 +28,58 @@
|
||||
/*!
|
||||
* Install a Qt message handler which outputs to the X-Plane debug log.
|
||||
*/
|
||||
class QXPlaneMessageHandler
|
||||
{
|
||||
static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
QByteArray localMsg = msg.toLocal8Bit();
|
||||
QByteArray file(context.file);
|
||||
if (file.isEmpty()) file = "<unknown>";
|
||||
//class QXPlaneMessageHandler
|
||||
//{
|
||||
// static void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
// {
|
||||
// QByteArray localMsg = msg.toLocal8Bit();
|
||||
// QByteArray file(context.file);
|
||||
// if (file.isEmpty()) file = "<unknown>";
|
||||
|
||||
int line = context.line;
|
||||
// int line = context.line;
|
||||
|
||||
char *buffer = new char[64 + localMsg.size() + file.size()];
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
std::sprintf(buffer, "%s:%d: Debug: %s\n", file.constData(), line, localMsg.constData());
|
||||
XPLMDebugString(buffer);
|
||||
break;
|
||||
case QtInfoMsg:
|
||||
std::sprintf(buffer, "%s:%d: Info: %s\n", file.constData(), line, localMsg.constData());
|
||||
XPLMDebugString(buffer);
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
std::sprintf(buffer, "%s:%d: Warning: %s\n", file.constData(), line, localMsg.constData());
|
||||
XPLMDebugString(buffer);
|
||||
break;
|
||||
default:
|
||||
case QtCriticalMsg:
|
||||
std::sprintf(buffer, "%s:%d: Error: %s\n", file.constData(), line, localMsg.constData());
|
||||
XPLMDebugString(buffer);
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
std::sprintf(buffer, "%s:%d: Fatal: %s\n", file.constData(), line, localMsg.constData());
|
||||
XPLMDebugString(buffer);
|
||||
std::abort();
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
// char *buffer = new char[64 + localMsg.size() + file.size()];
|
||||
// switch (type) {
|
||||
// case QtDebugMsg:
|
||||
// std::sprintf(buffer, "%s:%d: Debug: %s\n", file.constData(), line, localMsg.constData());
|
||||
// XPLMDebugString(buffer);
|
||||
// break;
|
||||
// case QtInfoMsg:
|
||||
// std::sprintf(buffer, "%s:%d: Info: %s\n", file.constData(), line, localMsg.constData());
|
||||
// XPLMDebugString(buffer);
|
||||
// break;
|
||||
// case QtWarningMsg:
|
||||
// std::sprintf(buffer, "%s:%d: Warning: %s\n", file.constData(), line, localMsg.constData());
|
||||
// XPLMDebugString(buffer);
|
||||
// break;
|
||||
// default:
|
||||
// case QtCriticalMsg:
|
||||
// std::sprintf(buffer, "%s:%d: Error: %s\n", file.constData(), line, localMsg.constData());
|
||||
// XPLMDebugString(buffer);
|
||||
// break;
|
||||
// case QtFatalMsg:
|
||||
// std::sprintf(buffer, "%s:%d: Fatal: %s\n", file.constData(), line, localMsg.constData());
|
||||
// XPLMDebugString(buffer);
|
||||
// std::abort();
|
||||
// }
|
||||
// delete[] buffer;
|
||||
// }
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Install the handler.
|
||||
*/
|
||||
static void install()
|
||||
{
|
||||
qInstallMessageHandler(handler);
|
||||
}
|
||||
//public:
|
||||
// /*!
|
||||
// * Install the handler.
|
||||
// */
|
||||
// static void install()
|
||||
// {
|
||||
// qInstallMessageHandler(handler);
|
||||
// }
|
||||
|
||||
//! Not copyable.
|
||||
//! @{
|
||||
QXPlaneMessageHandler(const QXPlaneMessageHandler &) = delete;
|
||||
QXPlaneMessageHandler &operator =(const QXPlaneMessageHandler &) = delete;
|
||||
//! @}
|
||||
};
|
||||
// //! Not copyable.
|
||||
// //! @{
|
||||
// QXPlaneMessageHandler(const QXPlaneMessageHandler &) = delete;
|
||||
// QXPlaneMessageHandler &operator =(const QXPlaneMessageHandler &) = delete;
|
||||
// //! @}
|
||||
//};
|
||||
|
||||
/*!
|
||||
* QApplication subclass used by XSwiftBus.
|
||||
@@ -89,101 +89,134 @@ public:
|
||||
* 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.
|
||||
*/
|
||||
class QSharedApplication : public QCoreApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
//class QSharedApplication : public QCoreApplication
|
||||
//{
|
||||
// Q_OBJECT
|
||||
|
||||
QWeakPointer<QCoreApplication> m_weakptr;
|
||||
// QWeakPointer<QCoreApplication> m_weakptr;
|
||||
|
||||
QSharedApplication(QSharedPointer<QCoreApplication> &ptr, int &argc, char **argv) : QCoreApplication(argc, argv)
|
||||
{
|
||||
ptr.reset(this);
|
||||
m_weakptr = ptr;
|
||||
}
|
||||
// QSharedApplication(QSharedPointer<QCoreApplication> &ptr, int &argc, char **argv) : QCoreApplication(argc, argv)
|
||||
// {
|
||||
// ptr.reset(this);
|
||||
// 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:
|
||||
/*!
|
||||
* Returns a shared pointer to the QApplication.
|
||||
*
|
||||
* The QApplication will not be destroyed while this shared pointer exists.
|
||||
*/
|
||||
static QSharedPointer<QCoreApplication> sharedInstance()
|
||||
{
|
||||
QSharedPointer<QCoreApplication> ptr;
|
||||
if (! instance())
|
||||
{
|
||||
static int argc = 1;
|
||||
static char *argv[] = { strdup("X-Plane") };
|
||||
//public:
|
||||
// /*!
|
||||
// * Returns a shared pointer to the QApplication.
|
||||
// *
|
||||
// * The QApplication will not be destroyed while this shared pointer exists.
|
||||
// */
|
||||
// static QSharedPointer<QCoreApplication> sharedInstance()
|
||||
// {
|
||||
// QSharedPointer<QCoreApplication> ptr;
|
||||
// if (! instance())
|
||||
// {
|
||||
// static int argc = 1;
|
||||
// static char *argv[] = { strdup("X-Plane") };
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
/* Workaround for #362 */
|
||||
char* xplocale = setlocale(LC_ALL, nullptr);
|
||||
#endif
|
||||
//#ifdef Q_OS_UNIX
|
||||
// /* Workaround for #362 */
|
||||
// char* xplocale = setlocale(LC_ALL, nullptr);
|
||||
//#endif
|
||||
|
||||
new QSharedApplication(ptr, argc, argv);
|
||||
// new QSharedApplication(ptr, argc, argv);
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
setlocale(LC_ALL, xplocale);
|
||||
#endif
|
||||
}
|
||||
if (! instance()->inherits("QSharedApplication"))
|
||||
{
|
||||
qFatal("There is an unshared QCoreApplication in another plugin");
|
||||
}
|
||||
return static_cast<QSharedApplication*>(instance())->m_weakptr;
|
||||
}
|
||||
};
|
||||
//#ifdef Q_OS_UNIX
|
||||
// setlocale(LC_ALL, xplocale);
|
||||
//#endif
|
||||
// }
|
||||
// if (! instance()->inherits("QSharedApplication"))
|
||||
// {
|
||||
// qFatal("There is an unshared QCoreApplication in another plugin");
|
||||
// }
|
||||
// return static_cast<QSharedApplication*>(instance())->m_weakptr;
|
||||
// }
|
||||
//};
|
||||
|
||||
/*!
|
||||
* Runs the Qt event loop inside the X-Plane event loop.
|
||||
*/
|
||||
class QXPlaneEventLoop : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
///*!
|
||||
// * Runs the Qt event loop inside the X-Plane event loop.
|
||||
// */
|
||||
//class QXPlaneEventLoop : public QObject
|
||||
//{
|
||||
// Q_OBJECT
|
||||
|
||||
QXPlaneEventLoop(QObject *parent) : QObject(parent)
|
||||
{
|
||||
XPLMRegisterFlightLoopCallback(callback, -1, nullptr);
|
||||
}
|
||||
// QXPlaneEventLoop(QObject *parent) : QObject(parent)
|
||||
// {
|
||||
// XPLMRegisterFlightLoopCallback(callback, -1, nullptr);
|
||||
// }
|
||||
|
||||
~QXPlaneEventLoop()
|
||||
{
|
||||
XPLMUnregisterFlightLoopCallback(callback, nullptr);
|
||||
}
|
||||
// ~QXPlaneEventLoop()
|
||||
// {
|
||||
// XPLMUnregisterFlightLoopCallback(callback, nullptr);
|
||||
// }
|
||||
|
||||
static float callback(float, float, int, void *)
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
QCoreApplication::sendPostedEvents();
|
||||
return -1;
|
||||
}
|
||||
// static float callback(float, float, int, void *)
|
||||
// {
|
||||
// QCoreApplication::processEvents();
|
||||
// QCoreApplication::sendPostedEvents();
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Registers the X-Plane callback which calls into the Qt event loop,
|
||||
* unless one was already registered.
|
||||
*/
|
||||
static void exec()
|
||||
{
|
||||
if (! QCoreApplication::instance()->findChild<QXPlaneEventLoop *>())
|
||||
{
|
||||
new QXPlaneEventLoop(QCoreApplication::instance());
|
||||
}
|
||||
}
|
||||
};
|
||||
//public:
|
||||
// /*!
|
||||
// * Registers the X-Plane callback which calls into the Qt event loop,
|
||||
// * unless one was already registered.
|
||||
// */
|
||||
// static void exec()
|
||||
// {
|
||||
// if (! QCoreApplication::instance()->findChild<QXPlaneEventLoop *>())
|
||||
// {
|
||||
// new QXPlaneEventLoop(QCoreApplication::instance());
|
||||
// }
|
||||
// }
|
||||
//};
|
||||
|
||||
namespace XSwiftBus
|
||||
{
|
||||
//! Absolute xplane path
|
||||
extern QString g_xplanePath;
|
||||
extern std::string g_xplanePath;
|
||||
|
||||
//! Platform specific dir separator
|
||||
extern QString g_sep;
|
||||
extern std::string g_sep;
|
||||
|
||||
//! Init global xplane path
|
||||
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
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//! \cond PRIVATE
|
||||
|
||||
#include "weather.h"
|
||||
#include <QDebug>
|
||||
#include "utils.h"
|
||||
|
||||
namespace XSwiftBus
|
||||
{
|
||||
@@ -37,7 +37,7 @@ namespace XSwiftBus
|
||||
case 0: setCloudLayerImpl(m_cloudLayer0, 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;
|
||||
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 1: setWindLayerImpl(m_windLayer1, 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)
|
||||
|
||||
QT += core gui widgets dbus network
|
||||
|
||||
TEMPLATE = lib
|
||||
|
||||
CONFIG += shared plugin
|
||||
CONFIG -= qt
|
||||
|
||||
INCLUDEPATH += $$EXTERNALSROOT/common/include/XPLM
|
||||
|
||||
@@ -107,7 +106,6 @@ INSTALLS += target
|
||||
|
||||
dep_target.path = $$PREFIX/$$XSWIFTBUS_DIR
|
||||
win32 {
|
||||
dep_target.files *= $$DestRoot/lib/blackmisc.dll
|
||||
dep_target.files *= $$DestRoot/bin/dbus-daemon.exe
|
||||
win32-g++ {
|
||||
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/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
|
||||
|
||||
dbus_share.path = $$PREFIX/$$XSWIFTBUS_DIR/share/dbus-1
|
||||
@@ -135,24 +127,8 @@ win32 {
|
||||
legacy_data_target.files *= LegacyData
|
||||
} else:macx: {
|
||||
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
|
||||
|
||||
# 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.files *= LegacyData
|
||||
|
||||
@@ -160,48 +136,13 @@ win32 {
|
||||
# We cannot modify the original library since this is xswiftbus specific.
|
||||
legacy_data_target.depends += 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/libdbus-1.3.dylib\" \"@loader_path/libdbus-1.3.dylib\" $$shell_path($$PREFIX/$$XSWIFTBUS_DIR/mac.xpl)
|
||||
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: {
|
||||
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
|
||||
|
||||
# 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.files *= LegacyData
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user