diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6db1b26db7..ef0c2a588e 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/render/src/render/Task.h b/libraries/render/src/render/Task.h index 93f3681c1c..d090938b64 100644 --- a/libraries/render/src/render/Task.h +++ b/libraries/render/src/render/Task.h @@ -12,7 +12,12 @@ #ifndef hifi_render_Task_h #define hifi_render_Task_h -#include // QObject +#include + +#include +#include +#include +#include #include "Context.h" @@ -65,6 +70,11 @@ public: bool alwaysEnabled{ true }; bool enabled{ true }; + + Q_INVOKABLE QString toJSON() { return QJsonDocument(toJsonValue(*this).toObject()).toJson(QJsonDocument::Compact); } + +public slots: + void load(const QJsonValue& json) { qObjectFromJsonValue(json, *this); } }; class TaskConfig : public JobConfig { 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