mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 04:25:35 +08:00
541 lines
14 KiB
C++
541 lines
14 KiB
C++
/* Copyright (C) 2013
|
|
* 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 "blackmiscfreefunctions.h"
|
|
#include "avallclasses.h"
|
|
#include "pqallquantities.h"
|
|
#include "mathallclasses.h"
|
|
#include "geoallclasses.h"
|
|
#include "networkallclasses.h"
|
|
#include "audioallclasses.h"
|
|
#include "hwallclasses.h"
|
|
#include "settingsblackmiscclasses.h"
|
|
#include "propertyindex.h"
|
|
#include "indexvariantmap.h"
|
|
#include "namevariantpairlist.h"
|
|
#include "variant.h"
|
|
#include "statusmessagelist.h"
|
|
#include "iconlist.h"
|
|
#include <QtNetwork/QHostInfo>
|
|
#include <QProcessEnvironment>
|
|
#include <QSysInfo>
|
|
|
|
|
|
/*
|
|
* Metadata for PQs
|
|
*/
|
|
void BlackMisc::PhysicalQuantities::registerMetadata()
|
|
{
|
|
CMeasurementUnit::registerMetadata();
|
|
CAcceleration::registerMetadata();
|
|
CAngle::registerMetadata();
|
|
CFrequency::registerMetadata();
|
|
CLength::registerMetadata();
|
|
CMass::registerMetadata();
|
|
CPressure::registerMetadata();
|
|
CSpeed::registerMetadata();
|
|
CTemperature::registerMetadata();
|
|
CTime::registerMetadata();
|
|
CPqString::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for aviation
|
|
*/
|
|
void BlackMisc::Aviation::registerMetadata()
|
|
{
|
|
CComSystem::registerMetadata();
|
|
CNavSystem::registerMetadata();
|
|
CAdfSystem::registerMetadata();
|
|
CAltitude::registerMetadata();
|
|
CTransponder::registerMetadata();
|
|
CHeading::registerMetadata();
|
|
CTrack::registerMetadata();
|
|
CInformationMessage::registerMetadata();
|
|
CCallsign::registerMetadata();
|
|
CCallsignList::registerMetadata();
|
|
CAtcStation::registerMetadata();
|
|
CAtcStationList::registerMetadata();
|
|
CAircraft::registerMetadata();
|
|
CAircraftList::registerMetadata();
|
|
CAirport::registerMetadata();
|
|
CAirportList::registerMetadata();
|
|
CAircraftSituation::registerMetadata();
|
|
CAircraftIcao::registerMetadata();
|
|
CAirportIcao::registerMetadata();
|
|
CSelcal::registerMetadata();
|
|
CFlightPlan::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 Network
|
|
*/
|
|
void BlackMisc::Network::registerMetadata()
|
|
{
|
|
CUser::registerMetadata();
|
|
CUserList::registerMetadata();
|
|
CServer::registerMetadata();
|
|
CServerList::registerMetadata();
|
|
CTextMessage::registerMetadata();
|
|
CTextMessageList::registerMetadata();
|
|
CClient::registerMetadata();
|
|
CClientList::registerMetadata();
|
|
CAircraftModel::registerMetadata();
|
|
CVoiceCapabilities::registerMetadata();
|
|
CAircraftMapping::registerMetadata();
|
|
CAircraftMappingList::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for Settings
|
|
*/
|
|
void BlackMisc::Settings::registerMetadata()
|
|
{
|
|
CSettingsNetwork::registerMetadata();
|
|
CSettingsAudio::registerMetadata();
|
|
CSettingKeyboardHotkey::registerMetadata();
|
|
CSettingKeyboardHotkeyList::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for Audio
|
|
*/
|
|
void BlackMisc::Audio::registerMetadata()
|
|
{
|
|
CAudioDevice::registerMetadata();
|
|
CAudioDeviceList::registerMetadata();
|
|
CVoiceRoom::registerMetadata();
|
|
CVoiceRoomList::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for Hardware
|
|
*/
|
|
void BlackMisc::Hardware::registerMetadata()
|
|
{
|
|
CKeyboardKey::registerMetadata();
|
|
CKeyboardKeyList::registerMetadata();
|
|
}
|
|
|
|
/*
|
|
* Metadata for Blackmisc
|
|
*/
|
|
void BlackMisc::registerMetadata()
|
|
{
|
|
CPropertyIndex::registerMetadata();
|
|
CVariant::registerMetadata();
|
|
CPropertyIndex::registerMetadata();
|
|
CIndexVariantMap::registerMetadata();
|
|
CNameVariantPair::registerMetadata();
|
|
CNameVariantPairList::registerMetadata();
|
|
CStatusMessage::registerMetadata();
|
|
CStatusMessageList::registerMetadata();
|
|
CIcon::registerMetadata();
|
|
CIconList::registerMetadata();
|
|
CHotkeyFunction::registerMetadata();
|
|
|
|
// sub namespaces
|
|
PhysicalQuantities::registerMetadata();
|
|
Aviation::registerMetadata();
|
|
Math::registerMetadata();
|
|
Geo::registerMetadata();
|
|
Network::registerMetadata();
|
|
Settings::registerMetadata();
|
|
Audio::registerMetadata();
|
|
Hardware::registerMetadata();
|
|
|
|
// needed by XBus proxy class
|
|
qRegisterMetaType<CSequence<double>>();
|
|
qRegisterMetaType<CSequence<double>>("CDoubleSequence");
|
|
qDBusRegisterMetaType<CSequence<double>>();
|
|
}
|
|
|
|
/*
|
|
* 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)
|
|
{
|
|
int c = compare(*cs1, *cs2);
|
|
return c == 0;
|
|
}
|
|
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:
|
|
case QMetaType::QChar:
|
|
{
|
|
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;
|
|
}
|
|
case QMetaType::QPixmap:
|
|
{
|
|
QPixmap p1 = v1.value<QPixmap>();
|
|
QPixmap p2 = v2.value<QPixmap>();
|
|
if (p1.width() == p2.width()) return 0;
|
|
return p1.width() < p2.width() ? -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 compare(*cs1, *cs2);
|
|
}
|
|
}
|
|
|
|
// integer types, handling not as double for rounding issues
|
|
if (v1.type() == QVariant::Int)
|
|
{
|
|
int i1 = v1.value<int>();
|
|
int i2 = v2.value<int>();
|
|
if (i1 == i2) return 0;
|
|
return i1 < i2 ? -1 : 1;
|
|
}
|
|
else if (v1.type() == QVariant::UInt)
|
|
{
|
|
uint i1 = v1.value<uint>();
|
|
uint i2 = v2.value<uint>();
|
|
if (i1 == i2) return 0;
|
|
return i1 < i2 ? -1 : 1;
|
|
}
|
|
else if (v1.type() == QVariant::LongLong)
|
|
{
|
|
long long i1 = v1.value<long long>();
|
|
long long i2 = v2.value<long long>();
|
|
if (i1 == i2) return 0;
|
|
return i1 < i2 ? -1 : 1;
|
|
}
|
|
else if (v1.type() == QVariant::ULongLong)
|
|
{
|
|
unsigned long long i1 = v1.value<unsigned long long>();
|
|
unsigned long long i2 = v2.value<unsigned long long>();
|
|
if (i1 == i2) return 0;
|
|
return i1 < i2 ? -1 : 1;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
/*
|
|
* Add hash values
|
|
*/
|
|
uint BlackMisc::calculateHash(const QList<int> &values, const char *className)
|
|
{
|
|
QList<uint> list;
|
|
uint s = 0;
|
|
foreach(int i, values)
|
|
{
|
|
|
|
if (i >= 0)
|
|
{
|
|
list.append(static_cast<uint>(i));
|
|
}
|
|
else
|
|
{
|
|
list.append(static_cast<uint>(i));
|
|
list.append(s++);
|
|
}
|
|
}
|
|
return calculateHash(list, className);
|
|
}
|
|
|
|
|
|
/*
|
|
* 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:
|
|
{
|
|
const char *name = QMetaType::typeName(type);
|
|
qFatal("Type cannot be resolved: %s (%d)", name ? name : "", type);
|
|
}
|
|
}
|
|
return QVariant(); // suppress compiler warning
|
|
}
|
|
|
|
#ifdef Q_CC_MSVC
|
|
#include <crtdbg.h>
|
|
|
|
/*
|
|
* Heap size of an object
|
|
*/
|
|
size_t BlackMisc::heapSizeOf(const QMetaType &metaType)
|
|
{
|
|
metaType.destroy(metaType.create()); // ignore one-off allocations of a class being instantiated for the first time
|
|
_CrtMemState oldState, newState, diff;
|
|
oldState.lTotalCount = newState.lTotalCount = diff.lTotalCount = 0; // avoid compiler warning
|
|
diff.lSizes[_NORMAL_BLOCK] = 0;
|
|
_CrtMemCheckpoint(&oldState);
|
|
void *p = metaType.create();
|
|
_CrtMemCheckpoint(&newState);
|
|
metaType.destroy(p);
|
|
_CrtMemDifference(&diff, &oldState, &newState);
|
|
return diff.lSizes[_NORMAL_BLOCK];
|
|
}
|
|
|
|
/*
|
|
* Heap size of an object
|
|
*/
|
|
size_t BlackMisc::heapSizeOf(const QMetaObject &metaObject)
|
|
{
|
|
delete metaObject.newInstance(); //ignore one-off allocations of a class being instantiated for the first time
|
|
_CrtMemState oldState, newState, diff;
|
|
oldState.lTotalCount = newState.lTotalCount = diff.lTotalCount = 0; // avoid compiler warning
|
|
diff.lSizes[_NORMAL_BLOCK] = 0;
|
|
_CrtMemCheckpoint(&oldState);
|
|
QObject *obj = metaObject.newInstance();
|
|
_CrtMemCheckpoint(&newState);
|
|
delete obj;
|
|
_CrtMemDifference(&diff, &oldState, &newState);
|
|
return diff.lSizes[_NORMAL_BLOCK];
|
|
}
|
|
|
|
#else //!Q_CC_MSVC
|
|
|
|
/*
|
|
* Heap size of an object
|
|
*/
|
|
size_t BlackMisc::heapSizeOf(const QMetaType &)
|
|
{
|
|
qDebug() << "heapSizeOf not supported by your compiler toolchain";
|
|
return 0;
|
|
}
|
|
/*
|
|
* Heap size of an object
|
|
*/
|
|
size_t BlackMisc::heapSizeOf(const QMetaObject &)
|
|
{
|
|
qDebug() << "heapSizeOf not supported by your compiler toolchain";
|
|
return 0;
|
|
}
|
|
|
|
#endif //!Q_CC_MSVC
|
|
|
|
/*
|
|
* Dump all user types
|
|
*/
|
|
void BlackMisc::displayAllUserMetatypesTypes()
|
|
{
|
|
for (int mt = QMetaType::User; mt < QMetaType::User + 1000; mt++)
|
|
{
|
|
if (!QMetaType::isRegistered(mt)) continue;
|
|
QMetaType metaType(mt);
|
|
qDebug() << "type:" << mt << "name:" << QMetaType::typeName(mt) << QMetaType::sizeOf(mt) << BlackMisc::heapSizeOf(metaType);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Local host name
|
|
*/
|
|
const QString &BlackMisc::localHostName()
|
|
{
|
|
static const QString hostName = QHostInfo::localHostName();
|
|
return hostName;
|
|
}
|
|
|
|
/*
|
|
* Local host name
|
|
*/
|
|
const QString &BlackMisc::localHostNameEnvVariable()
|
|
{
|
|
static const QString hostName =
|
|
QProcessEnvironment::systemEnvironment().value("COMPUTERNAME",
|
|
QProcessEnvironment::systemEnvironment().value("HOSTNAME"));
|
|
return hostName;
|
|
}
|