mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-21 04:45:31 +08:00
CValueMap generic representation of a value object as a map of QVariants
refs #81
This commit is contained in:
committed by
Mathew Sutcliffe
parent
a280d239e6
commit
bf1837b414
@@ -8,6 +8,7 @@
|
|||||||
#include "pqallquantities.h"
|
#include "pqallquantities.h"
|
||||||
#include "mathallclasses.h"
|
#include "mathallclasses.h"
|
||||||
#include "geoallclasses.h"
|
#include "geoallclasses.h"
|
||||||
|
#include "valuemap.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Metadata for PQs
|
* Metadata for PQs
|
||||||
@@ -68,12 +69,24 @@ void BlackMisc::Geo::registerMetadata()
|
|||||||
*/
|
*/
|
||||||
void BlackMisc::registerMetadata()
|
void BlackMisc::registerMetadata()
|
||||||
{
|
{
|
||||||
|
// !! make sure the first id is correctly returned by
|
||||||
|
// !! firstBlackMetaType
|
||||||
|
CValueMap::registerMetadata();
|
||||||
PhysicalQuantities::registerMetadata();
|
PhysicalQuantities::registerMetadata();
|
||||||
Aviation::registerMetadata();
|
Aviation::registerMetadata();
|
||||||
Math::registerMetadata();
|
Math::registerMetadata();
|
||||||
Geo::registerMetadata();
|
Geo::registerMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First of our ids
|
||||||
|
*/
|
||||||
|
int BlackMisc::firstBlackMetaType()
|
||||||
|
{
|
||||||
|
// must be the first registered above
|
||||||
|
return qMetaTypeId<CValueMap>();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init resources
|
* Init resources
|
||||||
*/
|
*/
|
||||||
@@ -279,3 +292,15 @@ QVariant BlackMisc::complexQtTypeFromDbusArgument(const QDBusArgument &argument,
|
|||||||
return QVariant(); // suppress compiler warning
|
return QVariant(); // suppress compiler warning
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,6 +77,20 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
void registerMetadata();
|
void registerMetadata();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Deals with the issue that the BlackMisc metatype does not always start with
|
||||||
|
* the same id, e.g. with GUI enabled:
|
||||||
|
* type: 1024 name: QPaintBufferCacheEntry
|
||||||
|
* type: 1025 .... some classes I cannot foresee
|
||||||
|
* type: 1027 name: BlackMisc::CValueMap
|
||||||
|
*
|
||||||
|
* This is important when marshalling Variants via DBus among different
|
||||||
|
* binaries, as the offset has to be considered
|
||||||
|
*
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
int firstBlackMetaType();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Init resources
|
* \brief Init resources
|
||||||
*/
|
*/
|
||||||
@@ -125,6 +139,11 @@ namespace BlackMisc
|
|||||||
// TODO: To be removed if a better solution is found
|
// TODO: To be removed if a better solution is found
|
||||||
QVariant complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type);
|
QVariant complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief displayAllUserTypes
|
||||||
|
*/
|
||||||
|
void displayAllUserMetatypesTypes();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Add several hash values
|
* \brief Add several hash values
|
||||||
* \param values
|
* \param values
|
||||||
|
|||||||
119
src/blackmisc/valuemap.cpp
Normal file
119
src/blackmisc/valuemap.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include "valuemap.h"
|
||||||
|
#include "blackmiscfreefunctions.h"
|
||||||
|
#include "avaltitude.h"
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
CValueMap::CValueMap(bool wildcard) : m_wildcard(wildcard) {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constructor single value
|
||||||
|
*/
|
||||||
|
CValueMap::CValueMap(int index, const QVariant &value)
|
||||||
|
{
|
||||||
|
this->addValue(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert to string
|
||||||
|
*/
|
||||||
|
QString CValueMap::convertToQString(bool i18n) const
|
||||||
|
{
|
||||||
|
if (this->isEmpty()) return "{}";
|
||||||
|
QString s;
|
||||||
|
foreach(int index, this->m_values.keys())
|
||||||
|
{
|
||||||
|
QVariant qv = this->m_values.value(index);
|
||||||
|
s.isEmpty() ? s.append("{") : s.append(", ");
|
||||||
|
s.append('{').append(QString::number(index)).append(": ");
|
||||||
|
s.append("(").append(QString::number(qv.userType())).append(") ");
|
||||||
|
QString qvs = BlackMisc::qVariantToString(qv, i18n);
|
||||||
|
s.append(qvs);
|
||||||
|
s.append('}');
|
||||||
|
}
|
||||||
|
s = s.append("}");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Marshall to DBus
|
||||||
|
*/
|
||||||
|
void CValueMap::marshallToDbus(QDBusArgument &argument) const
|
||||||
|
{
|
||||||
|
// remark, tried both sending as QDbusVariant and QVariant
|
||||||
|
// does not make a difference
|
||||||
|
QList<int> unifiedBlackTypeIds;
|
||||||
|
QList<QDBusVariant> dbusVariants;
|
||||||
|
foreach(QVariant qv, m_values.values())
|
||||||
|
{
|
||||||
|
unifiedBlackTypeIds << qv.userType() - BlackMisc::firstBlackMetaType();
|
||||||
|
dbusVariants << QDBusVariant(qv);
|
||||||
|
}
|
||||||
|
argument << this->m_values.keys(); // indexes
|
||||||
|
argument << dbusVariants;
|
||||||
|
argument << unifiedBlackTypeIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unmarshall from DBus
|
||||||
|
*/
|
||||||
|
void CValueMap::unmarshallFromDbus(const QDBusArgument &argument)
|
||||||
|
{
|
||||||
|
QList<int> indexes;
|
||||||
|
QList<QDBusVariant> values;
|
||||||
|
QList<int> unifiedBlackTypeIds;
|
||||||
|
argument >> indexes;
|
||||||
|
argument >> values;
|
||||||
|
argument >> unifiedBlackTypeIds;
|
||||||
|
QMap<int, QVariant> newMap;
|
||||||
|
for (int i = 0; i < indexes.size(); i++)
|
||||||
|
{
|
||||||
|
QVariant qv = values.at(i).variant();
|
||||||
|
int index = indexes.at(i);
|
||||||
|
if (qv.canConvert<QDBusArgument>())
|
||||||
|
{
|
||||||
|
int userType = unifiedBlackTypeIds.at(i) + BlackMisc::firstBlackMetaType();
|
||||||
|
QVariant concrete = BlackMisc::fixQVariantFromDbusArgument(qv, userType);
|
||||||
|
newMap.insert(index, concrete);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// value already OK
|
||||||
|
newMap.insert(index, qv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// replace values in one step
|
||||||
|
this->m_values.clear();
|
||||||
|
this->m_values.unite(newMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add value
|
||||||
|
*/
|
||||||
|
void CValueMap::addValue(int index, const QVariant &value)
|
||||||
|
{
|
||||||
|
this->m_values.insert(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register metadata
|
||||||
|
*/
|
||||||
|
void CValueMap::registerMetadata()
|
||||||
|
{
|
||||||
|
qRegisterMetaType<CValueMap>();
|
||||||
|
qDBusRegisterMetaType<CValueMap>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hash
|
||||||
|
*/
|
||||||
|
uint CValueMap::getValueHash() const
|
||||||
|
{
|
||||||
|
return qHash(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
150
src/blackmisc/valuemap.h
Normal file
150
src/blackmisc/valuemap.h
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
/* Copyright (C) 2013 VATSIM Community / authors
|
||||||
|
* 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/. */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "valueobject.h"
|
||||||
|
#include <QVariantMap>
|
||||||
|
#include <QDBusArgument>
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_VALUEMAP_H
|
||||||
|
#define BLACKMISC_VALUEMAP_H
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Value map
|
||||||
|
*/
|
||||||
|
class CValueMap : public CValueObject
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructor
|
||||||
|
* \param wildcard when used in search, for setting values irrelevant
|
||||||
|
*/
|
||||||
|
CValueMap(bool wildcard = false);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Single value constructor
|
||||||
|
* \param index
|
||||||
|
* \param value
|
||||||
|
*/
|
||||||
|
CValueMap(int index, const QVariant &value);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief QVariant, required for DBus QVariant lists
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
virtual QVariant toQVariant() const
|
||||||
|
{
|
||||||
|
return QVariant::fromValue(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructor
|
||||||
|
*/
|
||||||
|
virtual ~CValueMap() {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Add a value
|
||||||
|
* \param index
|
||||||
|
* \param value
|
||||||
|
*/
|
||||||
|
void addValue(int index, const QVariant &value);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Add a value as non QVariant
|
||||||
|
* \param index
|
||||||
|
* \param value
|
||||||
|
*/
|
||||||
|
template<class T> void addValue(int index, const T &value)
|
||||||
|
{
|
||||||
|
this->m_values.insert(index, QVariant::fromValue(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Is empty
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool isEmpty() const { return this->m_values.isEmpty(); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Value
|
||||||
|
* \param index
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
QVariant value(int index) const { return this->m_values.value(index); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Indexes
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
QList<int> indexes() const { return this->m_values.keys(); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief values
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
QList<QVariant> values() const { return this->m_values.values(); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Wildcard, only relevant when used in search
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool isWildcard() const { return this->m_wildcard; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief clear
|
||||||
|
*/
|
||||||
|
void clear() { this->m_values.clear(); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Map
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
const QMap<int, QVariant> &map() const { return this->m_values; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Value hash
|
||||||
|
*/
|
||||||
|
virtual uint getValueHash() const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Metadata
|
||||||
|
*/
|
||||||
|
static void registerMetadata();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QMap<int, QVariant> m_values; /*!< values */
|
||||||
|
bool m_wildcard;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Meaningful string representation
|
||||||
|
* \param i18n
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
virtual QString convertToQString(bool i18n = false) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Stream to DBus <<
|
||||||
|
* \param argument
|
||||||
|
*/
|
||||||
|
virtual void marshallToDbus(QDBusArgument &argument) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Stream from DBus >>
|
||||||
|
* \param argument
|
||||||
|
*/
|
||||||
|
virtual void unmarshallFromDbus(const QDBusArgument &argument);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(BlackMisc::CValueMap)
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
@@ -43,6 +43,35 @@ namespace BlackMisc
|
|||||||
return this->convertToQString();
|
return this->convertToQString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setter for property by index
|
||||||
|
*/
|
||||||
|
void CValueObject::setPropertyByIndex(const QVariant & /** variant **/, int /** index **/)
|
||||||
|
{
|
||||||
|
// not all classes have to implement this
|
||||||
|
qFatal("Property by index setter not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By index
|
||||||
|
*/
|
||||||
|
QVariant CValueObject::propertyByIndex(int /** index **/) const
|
||||||
|
{
|
||||||
|
// not all classes have to implement this
|
||||||
|
qFatal("Property by index not implemented");
|
||||||
|
return QVariant("boom"); // avoid compiler warning
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By index as string
|
||||||
|
*/
|
||||||
|
QString CValueObject::propertyByIndexAsString(int /** index **/, bool /** i18n **/) const
|
||||||
|
{
|
||||||
|
// not all classes have to implement this
|
||||||
|
qFatal("Property by index as string not implemented");
|
||||||
|
return QString("boom"); // avoid compiler warning
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return backing streamable object (if any)
|
* Return backing streamable object (if any)
|
||||||
*/
|
*/
|
||||||
@@ -70,6 +99,65 @@ namespace BlackMisc
|
|||||||
return -1; // avoid compiler warning
|
return -1; // avoid compiler warning
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Variant map
|
||||||
|
*/
|
||||||
|
int CValueObject::apply(const BlackMisc::CValueMap &valueMap)
|
||||||
|
{
|
||||||
|
if (valueMap.isEmpty()) return 0;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
QMap<int, QVariant>::const_iterator it;
|
||||||
|
const QMap<int, QVariant> &map = valueMap.map();
|
||||||
|
for (it = map.begin(); it != map.end(); ++it)
|
||||||
|
{
|
||||||
|
this->setPropertyByIndex(it.value(), it.key());
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare with value map
|
||||||
|
*/
|
||||||
|
bool operator==(const CValueMap &valueMap, const CValueObject &uc)
|
||||||
|
{
|
||||||
|
if (valueMap.isEmpty()) return valueMap.isWildcard();
|
||||||
|
QMap<int, QVariant>::const_iterator it;
|
||||||
|
const QMap<int, QVariant> &map = valueMap.map();
|
||||||
|
for (it = map.begin(); it != map.end(); ++it)
|
||||||
|
{
|
||||||
|
// QVariant cannot be compared directly
|
||||||
|
QVariant p = uc.propertyByIndex(it.key()); // from value object
|
||||||
|
QVariant v = it.value(); // from map
|
||||||
|
if (!BlackMisc::equalQVariants(p, v)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare with value map
|
||||||
|
*/
|
||||||
|
bool operator!=(const CValueMap &valueMap, const CValueObject &uc)
|
||||||
|
{
|
||||||
|
return !(valueMap == uc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare with value map
|
||||||
|
*/
|
||||||
|
bool operator==(const CValueObject &uc, const CValueMap &valueMap)
|
||||||
|
{
|
||||||
|
return valueMap == uc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compare with value map
|
||||||
|
*/
|
||||||
|
bool operator!=(const CValueObject &uc, const CValueMap &valueMap)
|
||||||
|
{
|
||||||
|
return !(valueMap == uc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* from DBus
|
* from DBus
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -109,6 +109,38 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
friend QDBusArgument &operator<<(QDBusArgument &argument, const CValueObject &uc);
|
friend QDBusArgument &operator<<(QDBusArgument &argument, const CValueObject &uc);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator == with value map
|
||||||
|
* \param valueMap
|
||||||
|
* \param uc
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
friend bool operator==(const CValueMap &valueMap, const CValueObject &uc);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator != with value map
|
||||||
|
* \param valueMap
|
||||||
|
* \param uc
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
friend bool operator!=(const CValueMap &valueMap, const CValueObject &uc);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator == with value map
|
||||||
|
* \param uc
|
||||||
|
* \param valueMap
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
friend bool operator==(const CValueObject &uc, const CValueMap &valueMap);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator != with value map
|
||||||
|
* \param uc
|
||||||
|
* \param valueMap
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
friend bool operator!=(const CValueObject &uc, const CValueMap &valueMap);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief Virtual destructor
|
* \brief Virtual destructor
|
||||||
@@ -134,6 +166,13 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
std::string toStdString(bool i18n = false) const;
|
std::string toStdString(bool i18n = false) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Update by variant map
|
||||||
|
* \param valueMap
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
int apply(const BlackMisc::CValueMap &valueMap);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Value hash, allows comparisons between QVariants
|
* \brief Value hash, allows comparisons between QVariants
|
||||||
* \return
|
* \return
|
||||||
@@ -155,6 +194,32 @@ namespace BlackMisc
|
|||||||
*/
|
*/
|
||||||
virtual QVariant toQVariant() const = 0;
|
virtual QVariant toQVariant() const = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set property by index
|
||||||
|
* \remarks Intentionally not abstract, avoiding all classes need to implement this method
|
||||||
|
* \param index
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
virtual void setPropertyByIndex(const QVariant &variant, int index);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Property by index
|
||||||
|
* \remarks Intentionally not abstract, avoiding all classes need to implement this method
|
||||||
|
* \param index
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
virtual QVariant propertyByIndex(int index) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Property by index as String
|
||||||
|
* \remarks Intentionally not abstract, avoiding all classes need to implement this method
|
||||||
|
|
||||||
|
* \param index
|
||||||
|
* \param i18n
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
virtual QString propertyByIndexAsString(int index, bool i18n = false) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The stored object as CValueObject
|
* \brief The stored object as CValueObject
|
||||||
* \param qv
|
* \param qv
|
||||||
|
|||||||
Reference in New Issue
Block a user