mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +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 "mathallclasses.h"
|
||||
#include "geoallclasses.h"
|
||||
#include "valuemap.h"
|
||||
|
||||
/*
|
||||
* Metadata for PQs
|
||||
@@ -68,12 +69,24 @@ void BlackMisc::Geo::registerMetadata()
|
||||
*/
|
||||
void BlackMisc::registerMetadata()
|
||||
{
|
||||
// !! make sure the first id is correctly returned by
|
||||
// !! firstBlackMetaType
|
||||
CValueMap::registerMetadata();
|
||||
PhysicalQuantities::registerMetadata();
|
||||
Aviation::registerMetadata();
|
||||
Math::registerMetadata();
|
||||
Geo::registerMetadata();
|
||||
}
|
||||
|
||||
/*
|
||||
* First of our ids
|
||||
*/
|
||||
int BlackMisc::firstBlackMetaType()
|
||||
{
|
||||
// must be the first registered above
|
||||
return qMetaTypeId<CValueMap>();
|
||||
}
|
||||
|
||||
/*
|
||||
* Init resources
|
||||
*/
|
||||
@@ -279,3 +292,15 @@ QVariant BlackMisc::complexQtTypeFromDbusArgument(const QDBusArgument &argument,
|
||||
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();
|
||||
|
||||
/*!
|
||||
* 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
|
||||
*/
|
||||
@@ -125,6 +139,11 @@ namespace BlackMisc
|
||||
// TODO: To be removed if a better solution is found
|
||||
QVariant complexQtTypeFromDbusArgument(const QDBusArgument &argument, int type);
|
||||
|
||||
/*!
|
||||
* \brief displayAllUserTypes
|
||||
*/
|
||||
void displayAllUserMetatypesTypes();
|
||||
|
||||
/*!
|
||||
* \brief Add several hash 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();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
@@ -70,6 +99,65 @@ namespace BlackMisc
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -109,6 +109,38 @@ namespace BlackMisc
|
||||
*/
|
||||
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:
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
@@ -134,6 +166,13 @@ namespace BlackMisc
|
||||
*/
|
||||
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
|
||||
* \return
|
||||
@@ -155,6 +194,32 @@ namespace BlackMisc
|
||||
*/
|
||||
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
|
||||
* \param qv
|
||||
|
||||
Reference in New Issue
Block a user