From 155b957cee0e6749a53dedc2891d18a6c9c7aace Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Fri, 14 Nov 2014 00:12:47 +0000 Subject: [PATCH] refs #247 CVariant can inherit from CValueObjectStdTuple. But if valueobject.h includes variant.h then it would create a circular dependency. --- samples/blackmiscdbus/servicetool.cpp | 4 +- .../components/infowindowcomponent.cpp | 2 +- src/blackmisc/blackmiscfreefunctions.cpp | 7 +- src/blackmisc/namevariantpair.cpp | 2 +- src/blackmisc/propertyindexvariantmap.cpp | 2 +- src/blackmisc/setnetwork.cpp | 2 +- src/blackmisc/valueobject.cpp | 8 ++ src/blackmisc/valueobject.h | 6 +- src/blackmisc/valueobject_policy.h | 10 +- src/blackmisc/variant.cpp | 51 +++---- src/blackmisc/variant.h | 126 ++++++------------ 11 files changed, 88 insertions(+), 132 deletions(-) diff --git a/samples/blackmiscdbus/servicetool.cpp b/samples/blackmiscdbus/servicetool.cpp index fa121219c..89207c08d 100644 --- a/samples/blackmiscdbus/servicetool.cpp +++ b/samples/blackmiscdbus/servicetool.cpp @@ -374,9 +374,9 @@ namespace BlackMiscTest qDebug() << "Pinged client list via interface" << clients.size() << clients; CVariant cv = CVariant::fromValue(clients); - qDebug() << "cv" << cv.toString(); + qDebug() << "cv" << cv.toQString(); cv = testserviceInterface.pingCVariant(client); - qDebug() << "Pinged CVariant via interface" << cv.toString(); + qDebug() << "Pinged CVariant via interface" << cv.toQString(); // test variant lists with different types wrapped in QVariant qDebug() << "----------------- variant tests ----------------"; diff --git a/src/blackgui/components/infowindowcomponent.cpp b/src/blackgui/components/infowindowcomponent.cpp index a911a7b4e..64ccd7e01 100644 --- a/src/blackgui/components/infowindowcomponent.cpp +++ b/src/blackgui/components/infowindowcomponent.cpp @@ -115,7 +115,7 @@ namespace BlackGui else if (variant.canConvert()) this->displayStatusMessage(variant.value(), displayTimeMs); else - this->displayStringMessage(variant.toString(), displayTimeMs); + this->displayStringMessage(variant.toQString(), displayTimeMs); } /* diff --git a/src/blackmisc/blackmiscfreefunctions.cpp b/src/blackmisc/blackmiscfreefunctions.cpp index 9843f988a..bd89a81d8 100644 --- a/src/blackmisc/blackmiscfreefunctions.cpp +++ b/src/blackmisc/blackmiscfreefunctions.cpp @@ -353,11 +353,8 @@ QVariant BlackMisc::fixQVariantFromDbusArgument(const QVariant &variant, int loc } } } - else - { - qWarning() << "fixQVariantFromDbusArgument called with unsupported type"; - return variant; - } + qWarning() << "fixQVariantFromDbusArgument called with unsupported type"; + return variant; } /* diff --git a/src/blackmisc/namevariantpair.cpp b/src/blackmisc/namevariantpair.cpp index a6b8328fe..91135798b 100644 --- a/src/blackmisc/namevariantpair.cpp +++ b/src/blackmisc/namevariantpair.cpp @@ -43,7 +43,7 @@ namespace BlackMisc QString CNameVariantPair::convertToQString(bool i18n) const { QString s(this->m_name); - s.append(" ").append(this->m_variant.toString(i18n)); + s.append(" ").append(this->m_variant.toQString(i18n)); return s; } diff --git a/src/blackmisc/propertyindexvariantmap.cpp b/src/blackmisc/propertyindexvariantmap.cpp index 7bd5b17bc..ec9366283 100644 --- a/src/blackmisc/propertyindexvariantmap.cpp +++ b/src/blackmisc/propertyindexvariantmap.cpp @@ -60,7 +60,7 @@ namespace BlackMisc s.append('{').append(index.toQString(i18n)).append(": "); s.append("(").append(QString::number(v.userType())).append(") "); - QString vs = v.toString(i18n); + QString vs = v.toQString(i18n); s.append(vs); s.append('}'); } diff --git a/src/blackmisc/setnetwork.cpp b/src/blackmisc/setnetwork.cpp index 3c9e0f26a..b1351a4b6 100644 --- a/src/blackmisc/setnetwork.cpp +++ b/src/blackmisc/setnetwork.cpp @@ -92,7 +92,7 @@ namespace BlackMisc { if (command == CSettingUtilities::CmdUpdate()) { - QString v = value.toString(); + QString v = value.toQString(); changedFlag = (v != this->m_bookingServiceUrl); this->m_bookingServiceUrl = v; return CLogMessage(CLogCategory::settingsUpdate()).info("booking URL%1 changed") << (changedFlag ? "" : " not"); diff --git a/src/blackmisc/valueobject.cpp b/src/blackmisc/valueobject.cpp index 104da67d7..8085d37a6 100644 --- a/src/blackmisc/valueobject.cpp +++ b/src/blackmisc/valueobject.cpp @@ -259,6 +259,14 @@ namespace BlackMisc return argument; } + /* + * to CVariant + */ + CVariant CValueObject::toCVariant() const + { + return CVariant(this->toQVariant()); + } + /* * Implementations of pure virtual functions */ diff --git a/src/blackmisc/valueobject.h b/src/blackmisc/valueobject.h index 20cbcb96c..f9c5ff754 100644 --- a/src/blackmisc/valueobject.h +++ b/src/blackmisc/valueobject.h @@ -15,7 +15,6 @@ #include "dbus.h" #include "tuple.h" #include "json.h" -#include "variant.h" #include "blackmiscfreefunctions.h" #include "valueobject_private.h" #include "valueobject_policy.h" @@ -37,6 +36,7 @@ namespace BlackMisc class CPropertyIndexList; class CPropertyIndexVariantMap; class CIcon; + class CVariant; namespace PhysicalQuantities { @@ -175,8 +175,8 @@ namespace BlackMisc //! Virtual method to return QVariant, used with DBus QVariant lists virtual QVariant toQVariant() const = 0; - //! Virtual method to return CVariant - virtual CVariant toCVariant() const { return CVariant(this->toQVariant()); } + //! Method to return CVariant + CVariant toCVariant() const; //! Equals another CValueObject in QVariant? virtual bool equalsQVariant(const QVariant &qVariant) const; diff --git a/src/blackmisc/valueobject_policy.h b/src/blackmisc/valueobject_policy.h index 3339d987c..0f3caadac 100644 --- a/src/blackmisc/valueobject_policy.h +++ b/src/blackmisc/valueobject_policy.h @@ -38,12 +38,20 @@ namespace BlackMisc namespace MetaType { + //! CValueObjectStdTuple registerMetadata policy which only registers with QMetaType and QtDBus + struct QMetaTypeAndDBusOnly + { + //! Register with QMetaType + template + static void registerImpl() { qRegisterMetaType(); qDBusRegisterMetaType(); } + }; + //! CValueObjectStdTuple default registerMetadata policy struct Default { //! Register with QMetaType template - static void registerImpl() { qRegisterMetaType(); qDBusRegisterMetaType(); maybeRegisterMetaValueType(); } + static void registerImpl() { QMetaTypeAndDBusOnly::registerImpl(); maybeRegisterMetaValueType(); } private: template diff --git a/src/blackmisc/variant.cpp b/src/blackmisc/variant.cpp index f09aeb4a2..18c71de64 100644 --- a/src/blackmisc/variant.cpp +++ b/src/blackmisc/variant.cpp @@ -8,7 +8,6 @@ */ #include "variant.h" -#include "valueobject.h" #include "blackmiscfreefunctions.h" #include #include @@ -26,13 +25,7 @@ namespace BlackMisc return v.value(); } - void CVariant::registerMetadata() - { - qRegisterMetaType(); - qDBusRegisterMetaType(); - } - - QString CVariant::toString(bool i18n) const + QString CVariant::convertToQString(bool i18n) const { auto *meta = getValueObjectMetaInfo(); if (meta) @@ -42,22 +35,24 @@ namespace BlackMisc return m_v.toString(); } - int BlackMisc::compare(const CVariant &a, const CVariant &b) + int CVariant::compareImpl(const CValueObject &otherBase) const { - if (a.userType() < b.userType()) { return -1; } - if (a.userType() > b.userType()) { return 1; } - auto *metaA = a.getValueObjectMetaInfo(); - auto *metaB = b.getValueObjectMetaInfo(); - if (metaA && metaB) + const auto &other = static_cast(otherBase); + + if (userType() < other.userType()) { return -1; } + if (userType() > other.userType()) { return 1; } + auto *meta = getValueObjectMetaInfo(); + auto *otherMeta = other.getValueObjectMetaInfo(); + if (meta && otherMeta) { const void *casted = nullptr; - if ((casted = metaA->upCastTo(a.data(), metaB->getMetaTypeId()))) + if ((casted = meta->upCastTo(data(), otherMeta->getMetaTypeId()))) { - return metaB->compare(casted, b.data()); + return otherMeta->compare(casted, other.data()); } - else if ((casted = metaB->upCastTo(b.data(), metaA->getMetaTypeId()))) + else if ((casted = otherMeta->upCastTo(other.data(), meta->getMetaTypeId()))) { - return metaA->compare(a.data(), casted); + return meta->compare(data(), casted); } else { @@ -65,8 +60,8 @@ namespace BlackMisc return 0; } } - if (a.m_v < b.m_v) { return -1; } - if (a.m_v > b.m_v) { return 1; } + if (m_v < other.m_v) { return -1; } + if (m_v > other.m_v) { return 1; } return 0; } @@ -106,7 +101,7 @@ namespace BlackMisc return json; } - void CVariant::fromJson(const QJsonObject &json) + void CVariant::convertFromJson(const QJsonObject &json) { QString typeName = json.value("type").toString(); int typeId = QMetaType::type(qPrintable(typeName)); @@ -179,23 +174,17 @@ namespace BlackMisc } } - QDBusArgument &operator <<(QDBusArgument &arg, const CVariant &var) + void CVariant::marshallToDbus(QDBusArgument &arg) const { - arg.beginStructure(); - arg << QString(var.typeName()) << QDBusVariant(var.toQVariant()); - arg.endStructure(); - return arg; + arg << QString(typeName()) << QDBusVariant(getQVariant()); } - const QDBusArgument &operator >>(const QDBusArgument &arg, CVariant &var) + void CVariant::unmarshallFromDbus(const QDBusArgument &arg) { QString typeName; QDBusVariant dbusVar; - arg.beginStructure(); arg >> typeName >> dbusVar; - arg.endStructure(); - var = fixQVariantFromDbusArgument(dbusVar.variant(), QMetaType::type(qPrintable(typeName))); - return arg; + *this = fixQVariantFromDbusArgument(dbusVar.variant(), QMetaType::type(qPrintable(typeName))); } } // namespace diff --git a/src/blackmisc/variant.h b/src/blackmisc/variant.h index 1b9789999..d8f43d051 100644 --- a/src/blackmisc/variant.h +++ b/src/blackmisc/variant.h @@ -12,6 +12,7 @@ #ifndef BLACKMISC_VARIANT_H #define BLACKMISC_VARIANT_H +#include "valueobject.h" #include #include #include @@ -23,22 +24,35 @@ class QDBusArgument; namespace BlackMisc { + class CVariant; + + //! \private + template <> struct CValueObjectStdTuplePolicy : public CValueObjectStdTuplePolicy<> + { + using MetaType = Policy::MetaType::QMetaTypeAndDBusOnly; + using Equals = Policy::Equals::OwnEquals; + using LessThan = Policy::LessThan::OwnLessThan; + using Compare = Policy::Compare::Own; + using Hash = Policy::Hash::Own; + using DBus = Policy::DBus::Own; + using Json = Policy::Json::Own; + }; /*! * Wrapper around QVariant which provides transparent access to CValueObject methods * of the contained object if it is registered with BlackMisc::registerMetaValueType. */ - class CVariant + class CVariant : public CValueObjectStdTuple { public: //! Default constructor. CVariant() {} //! Copy constructor. - CVariant(const CVariant &other) : m_v(other.m_v) {} + CVariant(const CVariant &other) : CValueObjectStdTuple(other), m_v(other.m_v) {} //! Move constructor. - CVariant(CVariant &&other) : m_v(std::move(other.m_v)) {} + CVariant(CVariant &&other) : CValueObjectStdTuple(std::move(other)), m_v(std::move(other.m_v)) {} //! Construct from a QVariant. CVariant(const QVariant &var) : m_v(var) {} @@ -52,8 +66,8 @@ namespace BlackMisc //! Construct a variant from the given type and opaque pointer. CVariant(int typeId, const void *copy) : m_v(typeId, copy) {} - //! Value hash - uint getValueHash() const; + //! \copydoc CValueObject::getValueHash + virtual uint getValueHash() const override; //! Change the internal QVariant. void reset(const QVariant &var) { m_v = var; } @@ -98,7 +112,13 @@ namespace BlackMisc template T to() const { return m_v.value(); } //! Return the internal QVariant. - const QVariant &toQVariant() const { return m_v; } + const QVariant &getQVariant() const { return m_v; } + + //! \copydoc CValueObject::toQVariant + virtual QVariant toQVariant() const override { return getQVariant(); } + + //! \copydoc CValueObject::convertFromQVariant + virtual void convertFromQVariant(const QVariant &v) override { m_v = v; } //! True if this variant can be converted to the type with the given metatype ID. bool canConvert(int typeId) const { return m_v.canConvert(typeId); } @@ -109,8 +129,8 @@ namespace BlackMisc //! Convert this variant to the type with the given metatype ID and return true if successful. bool convert(int typeId) { return m_v.convert(typeId); } - //! Convert this variant to a QString. - QString toString(bool i18n = false) const; + //! \copydoc CValueObject::convertToQString + virtual QString convertToQString(bool i18n = false) const override; //! Convert this variant to a bool. bool toBool() const { return m_v.toBool(); } @@ -142,35 +162,26 @@ namespace BlackMisc //! Return the metatype ID of the value in this variant. int userType() const { return m_v.userType(); } - //! To JSON - QJsonObject toJson() const; + //! \copydoc CValueObject::toJson + virtual QJsonObject toJson() const override; - //! From JSON - void fromJson(const QJsonObject &json); + //! \copydoc CValueObject::convertFromJson + virtual void convertFromJson(const QJsonObject &json) override; + + //! \copydoc CValueObject::marshallToDbus + virtual void marshallToDbus(QDBusArgument &argument) const override; + + //! \copydoc CValueObject::unmarshallFromDbus + virtual void unmarshallFromDbus(const QDBusArgument &argument) override; //! Equal operator. friend bool operator ==(const CVariant &a, const CVariant &b) { return compare(a, b) == 0; } - //! Not equal operator. - friend bool operator !=(const CVariant &a, const CVariant &b) { return !(a == b); } - //! Less than operator. friend bool operator <(const CVariant &a, const CVariant &b) { return compare(a, b) < 0; } - //! Less than or equal operator. - friend bool operator <=(const CVariant &a, const CVariant &b) { return !(b < a); } - - //! Greater than operator. - friend bool operator >(const CVariant &a, const CVariant &b) { return b < a; } - - //! Greater than or equal operator. - friend bool operator >=(const CVariant &a, const CVariant &b) { return !(a < b); } - - //! Arbitrary comparison - friend int compare(const CVariant &a, const CVariant &b); - - //! Register metadata. - static void registerMetadata(); + //! \copydoc CValueObject::compareImpl + virtual int compareImpl(const CValueObject &other) const override; private: QVariant m_v; @@ -180,63 +191,6 @@ namespace BlackMisc const void *data() const { return m_v.data(); } }; - //! Marshall a variant to DBus. - QDBusArgument &operator <<(QDBusArgument &arg, const CVariant &var); - - //! Unmarshall a variant from DBus. - const QDBusArgument &operator >>(const QDBusArgument &arg, CVariant &var); - - //! Non member, non friend operator >> for JSON - inline QJsonArray &operator<<(QJsonArray &json, const BlackMisc::CVariant &variant) - { - json.append(variant.toJson()); - return json; - } - - /*! - * \brief Non member, non friend operator << for JSON - * \param json - * \param value as pair name/value - * \return - */ - inline QJsonObject &operator<<(QJsonObject &json, const std::pair &value) - { - json.insert(value.first, QJsonValue(value.second.toJson())); - return json; - } - - //! Non member, non friend operator >> for JSON - inline const QJsonObject &operator>>(const QJsonObject &json, BlackMisc::CVariant &variant) - { - variant.fromJson(json); - return json; - } - - //! Non member, non friend operator >> for JSON - inline const QJsonValue &operator>>(const QJsonValue &json, BlackMisc::CVariant &variant) - { - variant.fromJson(json.toObject()); - return json; - } - - //! Non member, non friend operator >> for JSON - inline const QJsonValueRef &operator>>(const QJsonValueRef &json, BlackMisc::CVariant &variant) - { - variant.fromJson(json.toObject()); - return json; - } - - //! qHash overload, needed for storing CVariant with tupel system - inline uint qHash(const BlackMisc::CVariant &value, uint seed = 0) - { - return ::qHash(value.getValueHash(), seed); - } - - // Needed so that our qHash overload doesn't hide the qHash overloads in the global namespace. - // This will be safe as long as no global qHash has the same signature as ours. - // Alternative would be to qualify all our invokations of the global qHash as ::qHash. - using ::qHash; - } // namespace Q_DECLARE_METATYPE(BlackMisc::CVariant)