mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
282 lines
7.1 KiB
C++
282 lines
7.1 KiB
C++
/* Copyright (C) 2013 VATSIM Community / contributors
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "blackmiscfreefunctions.h"
|
|
#include "avallclasses.h"
|
|
#include "pqallquantities.h"
|
|
#include "mathallclasses.h"
|
|
#include "geoallclasses.h"
|
|
|
|
/*
|
|
* Metadata for PQs
|
|
*/
|
|
void BlackMisc::PhysicalQuantities::registerMetadata()
|
|
{
|
|
CAcceleration::registerMetadata();
|
|
CAngle::registerMetadata();
|
|
CFrequency::registerMetadata();
|
|
CLength::registerMetadata();
|
|
CMass::registerMetadata();
|
|
CPressure::registerMetadata();
|
|
CSpeed::registerMetadata();
|
|
CTemperature::registerMetadata();
|
|
CTime::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for aviation
|
|
*/
|
|
void BlackMisc::Aviation::registerMetadata()
|
|
{
|
|
CComSystem::registerMetadata();
|
|
CNavSystem::registerMetadata();
|
|
CAdfSystem::registerMetadata();
|
|
CAltitude::registerMetadata();
|
|
CTransponder::registerMetadata();
|
|
CHeading::registerMetadata();
|
|
CTrack::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for Math
|
|
*/
|
|
void BlackMisc::Math::registerMetadata()
|
|
{
|
|
CMatrix3x3::registerMetadata();
|
|
CMatrix3x1::registerMetadata();
|
|
CMatrix1x3::registerMetadata();
|
|
CVector3D::registerMetadata();
|
|
}
|
|
|
|
|
|
/*
|
|
* Metadata for Geo
|
|
*/
|
|
void BlackMisc::Geo::registerMetadata()
|
|
{
|
|
CCoordinateEcef::registerMetadata();
|
|
CCoordinateNed::registerMetadata();
|
|
CCoordinateGeodetic::registerMetadata();
|
|
CLatitude::registerMetadata();
|
|
CLongitude::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for Blackmisc
|
|
*/
|
|
void BlackMisc::registerMetadata()
|
|
{
|
|
PhysicalQuantities::registerMetadata();
|
|
Aviation::registerMetadata();
|
|
Math::registerMetadata();
|
|
Geo::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Init resources
|
|
*/
|
|
void BlackMisc::initResources()
|
|
{
|
|
initBlackMiscResources();
|
|
}
|
|
|
|
/*
|
|
* Stupid extension bo be able to compare 2 QVariants
|
|
*/
|
|
bool BlackMisc::equalQVariants(const QVariant &v1, const QVariant &v2)
|
|
{
|
|
// prephase, shortcuts
|
|
if (v1 == v2) return true; // compares on primitives or on address
|
|
if (!v1.isValid() || !v2.isValid()) return false;
|
|
if (v1.type() != v2.type()) return false;
|
|
if (v1.userType() != v2.userType()) return false;
|
|
|
|
// I have same types now
|
|
const CValueObject *cs1 = CValueObject::fromQVariant(v1);
|
|
const CValueObject *cs2 = CValueObject::fromQVariant(v2);
|
|
if (cs1 && cs2)
|
|
{
|
|
uint h1 = cs1->getValueHash();
|
|
uint h2 = cs2->getValueHash();
|
|
return h1 == h2;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Compare values
|
|
*/
|
|
int BlackMisc:: compareQVariants(const QVariant &v1, const QVariant &v2)
|
|
{
|
|
if (v1 == v2) return 0; // compares on primitives or on address
|
|
|
|
if (!v1.isValid() || !v2.isValid()) qFatal("Invalid variants");
|
|
if (v1.type() != v2.type()) qFatal("Mismatching types");
|
|
if (v1.userType() != v2.userType()) qFatal("Mismatching user types");
|
|
|
|
switch (v1.type())
|
|
{
|
|
case QMetaType::QString:
|
|
{
|
|
QString s1 = v1.value<QString>();
|
|
QString s2 = v2.value<QString>();
|
|
return s1.compare(s2);
|
|
}
|
|
case QMetaType::QDateTime:
|
|
{
|
|
QDateTime dt1 = v1.value<QDateTime>();
|
|
QDateTime dt2 = v2.value<QDateTime>();
|
|
if (dt1 == dt2) return 0;
|
|
return dt1 < dt2 ? -1 : 1;
|
|
}
|
|
case QMetaType::QDate:
|
|
{
|
|
QDate d1 = v1.value<QDate>();
|
|
QDate d2 = v2.value<QDate>();
|
|
if (d1 == d2) return 0;
|
|
return d1 < d2 ? -1 : 1;
|
|
}
|
|
case QMetaType::QTime:
|
|
{
|
|
QTime t1 = v1.value<QTime>();
|
|
QTime t2 = v2.value<QTime>();
|
|
if (t1 == t2) return 0;
|
|
return t1 < t2 ? -1 : 1;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// BlackObject
|
|
if (v1.type() == QVariant::UserType)
|
|
{
|
|
const CValueObject *cs1 = CValueObject::fromQVariant(v1);
|
|
const CValueObject *cs2 = CValueObject::fromQVariant(v2);
|
|
if (cs1 && cs2)
|
|
{
|
|
return cs1->compare(v2); // Note, that I have to compare against QVariant
|
|
}
|
|
}
|
|
|
|
// all kind of numeric values
|
|
if (v1.canConvert<double>())
|
|
{
|
|
double d1 = v1.value<double>();
|
|
double d2 = v2.value<double>();
|
|
if (d1 == d2) return 0;
|
|
return d1 < d2 ? -1 : 1;
|
|
}
|
|
|
|
qFatal("Unknown type for compare");
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* To string
|
|
*/
|
|
QString BlackMisc::qVariantToString(const QVariant &qv, bool i18n)
|
|
{
|
|
if (qv.type() != QVariant::UserType) return qv.toString();
|
|
const CValueObject *s = CValueObject::fromQVariant(qv);
|
|
if (s)
|
|
{
|
|
return s->toQString(i18n);
|
|
}
|
|
else
|
|
{
|
|
return "unknown";
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Add hash values
|
|
*/
|
|
uint BlackMisc::calculateHash(const QList<uint> &values, const char *className)
|
|
{
|
|
// http://stackoverflow.com/questions/113511/hash-code-implementation/113600#113600
|
|
if (values.isEmpty()) return 0;
|
|
uint hash = values.first();
|
|
for (int i = 1; i < values.size(); i++)
|
|
{
|
|
hash = 37 * hash + values.at(i);
|
|
}
|
|
|
|
// same values, but different class?
|
|
if (className)
|
|
{
|
|
hash = 37 * hash + qHash(QString(className));
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
/*
|
|
* Fix QVariant if it comes from DBus and contains QDBusArgument
|
|
*/
|
|
QVariant BlackMisc::fixQVariantFromDbusArgument(const QVariant &variant, int localUserType)
|
|
{
|
|
if (variant.canConvert<QDBusArgument>())
|
|
{
|
|
// complex, user type
|
|
// it has to be made sure, that the cast works
|
|
const QDBusArgument arg = variant.value<QDBusArgument>();
|
|
QVariant fixedVariant;
|
|
if (localUserType < static_cast<int>(QVariant::UserType))
|
|
{
|
|
// complex Qt type, e.g. QDateTime
|
|
fixedVariant = BlackMisc::complexQtTypeFromDbusArgument(arg, localUserType);
|
|
}
|
|
else
|
|
{
|
|
// http://qt-project.org/doc/qt-5.0/qtcore/qmetatype.html#create
|
|
void *obByMetaId = QMetaType::create(localUserType);
|
|
|
|
// own types, send as QDBusArgument
|
|
CValueObject *streamable = static_cast<CValueObject *>(obByMetaId);
|
|
arg >> (*streamable);
|
|
fixedVariant = streamable->toQVariant();
|
|
QMetaType::destroy(localUserType, obByMetaId);
|
|
}
|
|
return fixedVariant;
|
|
}
|
|
else
|
|
{
|
|
return variant;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Return QVariant based on QDBusArgument
|
|
*/
|
|
QVariant BlackMisc::complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type)
|
|
{
|
|
// QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
|
|
|
|
switch (type)
|
|
{
|
|
case QMetaType::QDateTime:
|
|
{
|
|
QDateTime dt;
|
|
argument >> dt;
|
|
return QVariant::fromValue(dt);
|
|
}
|
|
case QMetaType::QDate:
|
|
{
|
|
QDate date;
|
|
argument >> date;
|
|
return QVariant::fromValue(date);
|
|
}
|
|
case QMetaType::QTime:
|
|
{
|
|
QTime time;
|
|
argument >> time;
|
|
return QVariant::fromValue(time);
|
|
}
|
|
default:
|
|
qFatal("Type cannot be resolved");
|
|
}
|
|
return QVariant(); // suppress compiler warning
|
|
}
|
|
|