Add (de)serializer for QObject->JSON

This commit is contained in:
Zach Pomerantz 2016-01-27 16:09:16 -08:00
parent 725f9e29a3
commit 8bf6c66327
3 changed files with 76 additions and 8 deletions

View file

@ -57,6 +57,8 @@
#include <gl/Config.h>
#include <gl/QOpenGLContextWrapper.h>
#include <shared/JSONHelpers.h>
#include <ResourceScriptingInterface.h>
#include <AccountManager.h>
#include <AddressManager.h>

View file

@ -12,12 +12,12 @@
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
#include <QtCore/qmetaobject.h>
#include "../RegisteredMetaTypes.h"
template <typename T>
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<quat>(q);
}
@ -57,3 +61,63 @@ vec3 vec3FromJsonValue(const QJsonValue& v) {
return glmFromJson<vec3>(v);
}
vec4 vec4FromJsonValue(const QJsonValue& v) {
if (v.isDouble()) {
return vec4((float)v.toDouble());
}
return glmFromJson<vec4>(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<quat>()) {
value = toJsonValue(variant.value<quat>());
} else if (type == qMetaTypeId<vec3>()) {
value = toJsonValue(variant.value<vec3>());
} else if (type == qMetaTypeId<vec4>()) {
value = toJsonValue(variant.value<vec4>());
} 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<QObject*>();
qObjectFromJsonValue(it.value(), *object);
}
} else {
o.setProperty(key.c_str(), it.value());
}
}
}

View file

@ -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