From 8bf6c66327a081ea2d09362a047a31a3a1665550 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 27 Jan 2016 16:09:16 -0800 Subject: [PATCH] Add (de)serializer for QObject->JSON --- interface/src/Application.cpp | 2 + libraries/shared/src/shared/JSONHelpers.cpp | 72 +++++++++++++++++++-- libraries/shared/src/shared/JSONHelpers.h | 10 +-- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bf145d0e29..34486ca732 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -57,6 +57,8 @@ #include #include +#include + #include #include #include diff --git a/libraries/shared/src/shared/JSONHelpers.cpp b/libraries/shared/src/shared/JSONHelpers.cpp index 19d76ec132..3aab117370 100644 --- a/libraries/shared/src/shared/JSONHelpers.cpp +++ b/libraries/shared/src/shared/JSONHelpers.cpp @@ -12,12 +12,12 @@ #include #include +#include + +#include "../RegisteredMetaTypes.h" + template QJsonValue glmToJson(const T& t) { - static const T DEFAULT_VALUE = T(); - if (t == DEFAULT_VALUE) { - return QJsonValue(); - } QJsonArray result; for (auto i = 0; i < t.length(); ++i) { result.push_back(t[i]); @@ -46,6 +46,10 @@ QJsonValue toJsonValue(const vec3& v) { return glmToJson(v); } +QJsonValue toJsonValue(const vec4& v) { + return glmToJson(v); +} + quat quatFromJsonValue(const QJsonValue& q) { return glmFromJson(q); } @@ -57,3 +61,63 @@ vec3 vec3FromJsonValue(const QJsonValue& v) { return glmFromJson(v); } +vec4 vec4FromJsonValue(const QJsonValue& v) { + if (v.isDouble()) { + return vec4((float)v.toDouble()); + } + return glmFromJson(v); +} + +QJsonValue toJsonValue(const QObject& o) { + QJsonObject json{}; + + // Add all properties, see http://doc.qt.io/qt-5/qmetaobject.html#propertyCount + const auto& meta = o.metaObject(); + for (int i = meta->propertyOffset(); i < meta->propertyCount(); ++i) { + QString name = QString::fromLatin1(meta->property(i).name()); + auto type = meta->property(i).userType(); + QVariant variant{ meta->property(i).read(&o) }; + QJsonValue value; + + // User-registered types need explicit conversion + if (type == qMetaTypeId()) { + value = toJsonValue(variant.value()); + } else if (type == qMetaTypeId()) { + value = toJsonValue(variant.value()); + } else if (type == qMetaTypeId()) { + value = toJsonValue(variant.value()); + } else { + // Qt types are converted automatically + value = QJsonValue::fromVariant(variant); + } + + json.insert(name, value); + } + + // Add all children (recursively) + const auto children = o.children(); + for (const auto& child : children) { + QJsonObject childJson = toJsonValue(*child).toObject(); + if (!childJson.empty()) { + json.insert(child->objectName(), childJson); + } + } + + return json; +} + +void qObjectFromJsonValue(const QJsonValue& j, QObject& o) { + const QJsonObject object = j.toObject(); + for (auto it = object.begin(); it != object.end(); it++) { + std::string key = it.key().toStdString(); + if (it.value().isObject()) { + QVariant child = o.property(key.c_str()); + if (child.isValid()) { + QObject* object = child.value(); + qObjectFromJsonValue(it.value(), *object); + } + } else { + o.setProperty(key.c_str(), it.value()); + } + } +} diff --git a/libraries/shared/src/shared/JSONHelpers.h b/libraries/shared/src/shared/JSONHelpers.h index 0eda8ac94a..735d33b5a5 100644 --- a/libraries/shared/src/shared/JSONHelpers.h +++ b/libraries/shared/src/shared/JSONHelpers.h @@ -13,11 +13,13 @@ #include "../GLMHelpers.h" QJsonValue toJsonValue(const quat& q); - -QJsonValue toJsonValue(const vec3& q); +QJsonValue toJsonValue(const vec3& v); +QJsonValue toJsonValue(const vec4& v); +QJsonValue toJsonValue(const QObject& o); quat quatFromJsonValue(const QJsonValue& q); - -vec3 vec3FromJsonValue(const QJsonValue& q); +vec3 vec3FromJsonValue(const QJsonValue& v); +vec4 vec4FromJsonValue(const QJsonValue& v); +void qObjectFromJsonValue(const QJsonValue& j, QObject& o); #endif