[xswiftbus] Remove BlackMisc dependency

There were only very few classes used from Blackmisc after the interpolator
was moved to the driver. Therefore replace those few classes with
a simple alternative and remove BlackMisc from xswiftbus.
This commit is contained in:
Roland Winklmeier
2018-03-23 11:35:14 +01:00
parent b278d9ee2f
commit b0a8fcaa45
6 changed files with 288 additions and 19 deletions

View File

@@ -0,0 +1,39 @@
/* Copyright (C) 2018
* swift Project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "navdatareference.h"
#include <cmath>
namespace XSwiftBus
{
//! Converts degree to radian
inline double degreeToRadian(double angle)
{
return M_PI * angle / 180.0;
}
//! Returns the great circle distance between to nav data references
double calculateGreatCircleDistance(const CNavDataReference &a, const CNavDataReference &b)
{
const static double c_earthRadiusKm = 6372.8;
double latRad1 = degreeToRadian(a.latitude());
double latRad2 = degreeToRadian(b.latitude());
double lonRad1 = degreeToRadian(a.longitude());
double lonRad2 = degreeToRadian(b.longitude());
double diffLa = latRad2 - latRad1;
double doffLo = lonRad2 - lonRad1;
double computation = asin(sqrt(sin(diffLa / 2) * sin(diffLa / 2) + cos(latRad1) * cos(latRad2) * sin(doffLo / 2) * sin(doffLo / 2)));
return 2 * c_earthRadiusKm * computation;
}
}

View File

@@ -0,0 +1,49 @@
/* Copyright (C) 2018
* swift Project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKSIM_XSWIFTBUS_NAVDATAREFERENCE_H
#define BLACKSIM_XSWIFTBUS_NAVDATAREFERENCE_H
namespace XSwiftBus
{
//! Simplified version of CNavDataReference of \sa BlackMisc::Simulation::XPlane::CNavDataReference
class CNavDataReference
{
public:
//! Default constructor
CNavDataReference() = default;
//! Constructor
CNavDataReference(int id, double latitudeDegrees, double longitudeDegrees)
: m_id(id), m_latitudeDegrees(latitudeDegrees), m_longitudeDegrees(longitudeDegrees)
{ }
//! \copydoc BlackMisc::Simulation::XPlane::CNavDataReference::id
int id() const { return m_id; }
//! \copydoc BlackMisc::Simulation::XPlane::CNavDataReference::latitude
double latitude() const { return m_latitudeDegrees; }
//! \copydoc BlackMisc::Simulation::XPlane::CNavDataReference::longitude
double longitude() const { return m_longitudeDegrees; }
private:
int m_id = 0;
double m_latitudeDegrees = 0.0;
double m_longitudeDegrees = 0.0;
};
//! Free function to calculate great circle distance
double calculateGreatCircleDistance(const CNavDataReference &a, const CNavDataReference &b);
} // ns
#endif // guard

View File

@@ -8,16 +8,19 @@
*/
#include "service.h"
#include "blackmisc/simulation/xplane/aircraftmodelloaderxplane.h"
#include <XPLM/XPLMPlanes.h>
#include <XPLM/XPLMUtilities.h>
#include <QDebug>
#include <QTimer>
#include <QRegularExpression>
#include <QStringBuilder>
#include <QDir>
// clazy:excludeall=reserve-candidates
namespace XSwiftBus
{
CService::CService(CDBusConnection *connection) : CDBusObject(connection)
{
registerDBusObjectPath(XSWIFTBUS_SERVICE_INTERFACENAME, XSWIFTBUS_SERVICE_OBJECTPATH);
@@ -33,7 +36,7 @@ namespace XSwiftBus
char filename[256];
char path[512];
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
const auto model = BlackMisc::Simulation::XPlane::CAircraftModelLoaderXPlane::extractAcfProperties(path, QFileInfo(path));
const auto model = extractAcfProperties(path, QFileInfo(path));
emitAircraftModelChanged(path, filename, getAircraftLivery(), getAircraftIcaoCode(), model.getModelString(), model.getName(), getAircraftDescription());
}
@@ -82,7 +85,7 @@ namespace XSwiftBus
char filename[256];
char path[512];
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
const auto model = BlackMisc::Simulation::XPlane::CAircraftModelLoaderXPlane::extractAcfProperties(path, QFileInfo(path));
const auto model = extractAcfProperties(path, QFileInfo(path));
return model.getModelString();
}
@@ -91,7 +94,7 @@ namespace XSwiftBus
char filename[256];
char path[512];
XPLMGetNthAircraftModel(XPLM_USER_AIRCRAFT, filename, path);
const auto model = BlackMisc::Simulation::XPlane::CAircraftModelLoaderXPlane::extractAcfProperties(path, QFileInfo(path));
const auto model = extractAcfProperties(path, QFileInfo(path));
return model.getName();
}
@@ -138,8 +141,7 @@ namespace XSwiftBus
XPLMGetNavAidInfo(i, nullptr, &lat, &lon, nullptr, nullptr, nullptr, icao, nullptr, nullptr);
if (icao[0] != 0)
{
using namespace BlackMisc::Math;
m_airports.push_back(BlackMisc::Simulation::XPlane::CNavDataReference(i, lat, lon));
m_airports.emplace_back(i, lat, lon);
}
}
}
@@ -147,15 +149,14 @@ namespace XSwiftBus
void CService::updateAirportsInRange()
{
if (m_airports.isEmpty())
if (m_airports.empty())
{
readAirportsDatabase();
}
using namespace BlackMisc::Math;
using namespace BlackMisc::Geo;
std::vector<std::string> icaos, names;
std::vector<double> lats, lons, alts;
for (const auto &navref : m_airports.findClosest(20, CCoordinateGeodetic(getLatitude(), getLongitude(), 0)))
std::vector<CNavDataReference> closestAirports = findClosestAirports(20, getLatitude(), getLongitude());
for (const auto &navref : closestAirports)
{
float lat, lon, alt;
char icao[32], name[256];
@@ -661,4 +662,121 @@ namespace XSwiftBus
sendDBusMessage(signalAirportsInRangeUpdated);
}
std::vector<CNavDataReference> CService::findClosestAirports(int number, double latitude, double longitude)
{
CNavDataReference ref(0, latitude, longitude);
auto compareFunction = [ & ](const CNavDataReference & a, const CNavDataReference & b)
{
return calculateGreatCircleDistance(a, ref) < calculateGreatCircleDistance(b, ref);
};
auto closestAirports = m_airports;
std::partial_sort(closestAirports.begin(), closestAirports.begin() + number, closestAirports.end(), compareFunction);
closestAirports.resize(number);
return closestAirports;
}
QString descriptionForFlyableModel(const CAircraftModel &model)
{
if (!model.getName().isEmpty())
{
if (model.getDistributor().hasDescription() && !model.getName().contains(model.getDistributor().getDescription()))
{
return QStringLiteral("[ACF] ") % model.getName() % QStringLiteral(" by ") % model.getDistributor().getDescription();
}
else
{
return QStringLiteral("[ACF] ") % model.getName();
}
}
else if (model.hasAircraftDesignator())
{
if (model.getDistributor().hasDescription())
{
return QStringLiteral("[ACF] ") % model.getAircraftIcaoCodeDesignator() % QStringLiteral(" by ") % model.getDistributor().getDescription();
}
else
{
return QStringLiteral("[ACF] ") % model.getAircraftIcaoCodeDesignator();
}
}
return QStringLiteral("[ACF]");
}
QString stringForFlyableModel(const CAircraftModel &model, const QFileInfo &acfFile)
{
if (model.getDistributor().hasDescription())
{
if (!model.getName().isEmpty())
{
if (model.getName().contains(model.getDistributor().getDescription()))
{
return model.getName();
}
else
{
return model.getDistributor().getDescription() % ' ' % model.getName();
}
}
else if (model.hasAircraftDesignator())
{
return model.getDistributor().getDescription() % ' ' % model.getAircraftIcaoCodeDesignator();
}
}
return acfFile.dir().dirName() % ' ' % acfFile.baseName();
}
CAircraftModel CService::extractAcfProperties(const QString &filePath, const QFileInfo &fileInfo)
{
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")
{
while (!ts.atEnd())
{
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"))
{
const QString icao(tokens.at(2).toString());
model.setAircraftIcaoCode(icao);
}
else if (tokens.at(1) == QLatin1String("acf/_descrip"))
{
const QString desc(line.mid(tokens.at(2).position()));
model.setDescription("[ACF] " % desc);
}
else if (tokens.at(1) == QLatin1String("acf/_name"))
{
const QString name(line.mid(tokens.at(2).position()));
model.setName(name);
}
else if (tokens.at(1) == QLatin1String("acf/_studio"))
{
const CDistributor dist(line.mid(tokens.at(2).position()));
model.setDistributor(dist);
}
else if (tokens.at(1) == QLatin1String("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; }
const CDistributor dist(author);
model.setDistributor(dist);
}
}
}
file.close();
model.setModelString(stringForFlyableModel(model, fileInfo));
if (!model.hasDescription()) { model.setDescription(descriptionForFlyableModel(model)); }
return model;
}
}

View File

@@ -19,11 +19,12 @@
#include "dbusobject.h"
#include "datarefs.h"
#include "messages.h"
#include "blackmisc/simulation/xplane/navdatareference.h"
#include "navdatareference.h"
#include <XPLM/XPLMNavigation.h>
#include <QStringList>
#include <QObject>
#include <QList>
#include <QFileInfo>
class QTimer;
@@ -35,6 +36,68 @@ class QTimer;
namespace XSwiftBus
{
//! Simplified implementation of \sa BlackMisc::Simulation::CDistributor
class CDistributor
{
public:
CDistributor() = default;
CDistributor(const QString &distributor) : m_distributor(distributor) {}
bool hasDescription() const { return !m_description.isEmpty(); }
QString getDescription() const { return m_description; }
private:
QString m_distributor;
QString m_description;
};
//! Simplified implementation of \sa BlackMisc::Simulation::CAircraftModel
class CAircraftModel
{
public:
CAircraftModel() = default;
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasDescription
bool hasDescription() const { return !m_description.isEmpty(); }
//! \copydoc BlackMisc::Simulation::CAircraftModel::hasAircraftDesignator
bool hasAircraftDesignator() const { return !m_icao.isEmpty(); }
//! \copydoc BlackMisc::Simulation::CAircraftModel::getName
QString 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; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::getModelString
QString getModelString() const { return m_modelString; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setAircraftIcaoCode
void setAircraftIcaoCode(const QString &icao) { m_icao = icao; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setDescription
void setDescription(const QString &description) { m_description = description; }
//! \copydoc BlackMisc::Simulation::CAircraftModel::setName
void setName(const QString &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; }
private:
QString m_name;
QString m_icao;
QString m_description;
CDistributor m_distributor;
QString m_modelString;
};
/*!
* XSwiftBus service object which is accessible through DBus
*/
@@ -244,10 +307,14 @@ namespace XSwiftBus
const std::vector<double> &lats, const std::vector<double> &lons, const std::vector<double> &alts);
CMessageBoxControl m_messages { 128, 128, 16 };
BlackMisc::Simulation::XPlane::CNavDataReferenceList m_airports;
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);
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_descrip> m_descrip;

View File

@@ -14,7 +14,6 @@
#endif
#include "traffic.h"
#include "utils.h"
#include "blackmisc/verify.h"
#include "XPMPMultiplayer.h"
#include "XPMPPlaneRenderer.h"
#include <XPLM/XPLMProcessing.h>
@@ -22,6 +21,7 @@
#include <QDateTime>
#include <QDebug>
#include <QStringList>
#include <cassert>
#include <cstring>
#include <cmath>
@@ -218,8 +218,7 @@ namespace XSwiftBus
const QList<Plane *> planes = m_planesByCallsign.values();
for (Plane *plane : planes)
{
BLACK_VERIFY_X(plane, Q_FUNC_INFO, "Missing Plane");
if (!plane) { continue; }
assert(plane);
XPMPDestroyPlane(plane->id);
delete plane;
}
@@ -281,9 +280,7 @@ namespace XSwiftBus
const QList<Plane *> planes = m_planesByCallsign.values();
for (const Plane *plane : planes)
{
BLACK_VERIFY_X(plane, Q_FUNC_INFO, "Missing Plane");
if (!plane) { continue; }
assert(plane);
double lat = plane->position.lat;
double lon = plane->position.lon;
double elevation = plane->position.elevation;

View File

@@ -5,7 +5,6 @@ QT += core gui widgets dbus network
TEMPLATE = lib
CONFIG += shared plugin
CONFIG += blackmisc
INCLUDEPATH += $$EXTERNALSROOT/common/include/XPLM