mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-01 13:36:48 +08:00
The new compare is implemented using "multimethods" described in the book Advanced C++ Programming Styles and Idioms by James Coplien. First, the isA method is used to determine which of the values being compared is the most general. (For example, CLength is more general than CAltitude.) Then the compareImpl method is called on the most general value, with the other value as an argument. If there is not a direct inheritance relation between the two values (or they are the same class) then the comparison is invalid and a assert is triggered.
147 lines
3.6 KiB
C++
147 lines
3.6 KiB
C++
#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;
|
|
}
|
|
|
|
/*
|
|
* metaTypeId
|
|
*/
|
|
int CValueMap::getMetaTypeId() const
|
|
{
|
|
return qMetaTypeId<CValueMap>();
|
|
}
|
|
|
|
/*
|
|
* is a
|
|
*/
|
|
bool CValueMap::isA(int metaTypeId) const
|
|
{
|
|
if (metaTypeId == qMetaTypeId<CValueMap>()) { return true; }
|
|
|
|
return this->CValueObject::isA(metaTypeId);
|
|
}
|
|
|
|
/*
|
|
* Compare
|
|
*/
|
|
int CValueMap::compareImpl(const CValueObject &/*otherBase*/) const
|
|
{
|
|
qFatal("not implemented");
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* 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
|