Files
pilotclient/src/blackmisc/blackmiscfreefunctions.cpp

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
}