mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Working on JSON encoding.
This commit is contained in:
parent
10875c5e61
commit
7db05f2c8e
2 changed files with 276 additions and 1 deletions
|
@ -1657,6 +1657,49 @@ const TypeStreamer* Bitstream::createInvalidTypeStreamer() {
|
|||
return streamer;
|
||||
}
|
||||
|
||||
void JSONWriter::addTypeStreamer(const TypeStreamer* streamer) {
|
||||
if (!_typeStreamerNames.contains(streamer->getName())) {
|
||||
_typeStreamerNames.insert(streamer->getName());
|
||||
|
||||
// start with a placeholder; then remove/replace with actual metadata
|
||||
int index = _typeStreamers.size();
|
||||
_typeStreamers.append(QJsonValue());
|
||||
QJsonValue metadata = streamer->getJSONMetadata(*this);
|
||||
if (metadata.isNull()) {
|
||||
_typeStreamers.removeAt(index);
|
||||
} else {
|
||||
_typeStreamers.replace(index, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JSONWriter::addObjectStreamer(const ObjectStreamer* streamer) {
|
||||
if (!_objectStreamerNames.contains(streamer->getName())) {
|
||||
_objectStreamerNames.insert(streamer->getName());
|
||||
|
||||
// start with a placeholder; then replace with actual metadata
|
||||
int index = _objectStreamers.size();
|
||||
_objectStreamers.append(QJsonValue());
|
||||
_objectStreamers.replace(index, streamer->getJSONMetadata(*this));
|
||||
}
|
||||
}
|
||||
|
||||
void JSONWriter::addSharedObject(const SharedObjectPointer& object) {
|
||||
if (!_sharedObjectIDs.contains(object->getID())) {
|
||||
_sharedObjectIDs.insert(object->getID());
|
||||
|
||||
// start with a placeholder; then replace with actual object
|
||||
int index = _sharedObjects.size();
|
||||
_sharedObjects.append(QJsonValue());
|
||||
|
||||
QJsonObject sharedObject;
|
||||
sharedObject.insert("id", object->getID());
|
||||
sharedObject.insert("originID", object->getOriginID());
|
||||
|
||||
_sharedObjects.replace(index, sharedObject);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectStreamer::ObjectStreamer(const QMetaObject* metaObject) :
|
||||
_metaObject(metaObject) {
|
||||
}
|
||||
|
@ -1699,6 +1742,33 @@ void MappedObjectStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
}
|
||||
}
|
||||
|
||||
QJsonObject MappedObjectStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(_metaObject->className()));
|
||||
QJsonArray properties;
|
||||
foreach (const StreamerPropertyPair& property, _properties) {
|
||||
QJsonObject object;
|
||||
writer.addTypeStreamer(property.first.data());
|
||||
object.insert("type", QString(property.first->getName()));
|
||||
object.insert("name", QString(property.second.name()));
|
||||
properties.append(object);
|
||||
}
|
||||
metadata.insert("properties", properties);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
QJsonObject MappedObjectStreamer::getJSONData(JSONWriter& writer, const QObject* object) const {
|
||||
QJsonObject data;
|
||||
writer.addObjectStreamer(this);
|
||||
data.insert("class", QString(_metaObject->className()));
|
||||
QJsonArray properties;
|
||||
foreach (const StreamerPropertyPair& property, _properties) {
|
||||
properties.append(property.first->getJSONData(writer, property.second.read(object)));
|
||||
}
|
||||
data.insert("properties", properties);
|
||||
return data;
|
||||
}
|
||||
|
||||
void MappedObjectStreamer::write(Bitstream& out, const QObject* object) const {
|
||||
foreach (const StreamerPropertyPair& property, _properties) {
|
||||
property.first->write(out, property.second.read(object));
|
||||
|
@ -1775,6 +1845,34 @@ void GenericObjectStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
}
|
||||
}
|
||||
|
||||
QJsonObject GenericObjectStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(_name));
|
||||
QJsonArray properties;
|
||||
foreach (const StreamerNamePair& property, _properties) {
|
||||
QJsonObject object;
|
||||
writer.addTypeStreamer(property.first.data());
|
||||
object.insert("type", QString(property.first->getName()));
|
||||
object.insert("name", QString(property.second));
|
||||
properties.append(object);
|
||||
}
|
||||
metadata.insert("properties", properties);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
QJsonObject GenericObjectStreamer::getJSONData(JSONWriter& writer, const QObject* object) const {
|
||||
QJsonObject data;
|
||||
writer.addObjectStreamer(this);
|
||||
data.insert("class", QString(_name));
|
||||
QJsonArray properties;
|
||||
const QVariantList& values = static_cast<const GenericSharedObject*>(object)->getValues();
|
||||
for (int i = 0; i < _properties.size(); i++) {
|
||||
properties.append(_properties.at(i).first->getJSONData(writer, values.at(i)));
|
||||
}
|
||||
data.insert("properties", properties);
|
||||
return data;
|
||||
}
|
||||
|
||||
void GenericObjectStreamer::write(Bitstream& out, const QObject* object) const {
|
||||
const QVariantList& values = static_cast<const GenericSharedObject*>(object)->getValues();
|
||||
for (int i = 0; i < _properties.size(); i++) {
|
||||
|
@ -1876,6 +1974,55 @@ void TypeStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
}
|
||||
}
|
||||
|
||||
QJsonValue TypeStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
Category category = getCategory();
|
||||
switch (category) {
|
||||
case STREAMABLE_CATEGORY: {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("STREAMABLE"));
|
||||
QJsonArray fields;
|
||||
foreach (const MetaField& metaField, getMetaFields()) {
|
||||
QJsonObject field;
|
||||
writer.addTypeStreamer(metaField.getStreamer());
|
||||
field.insert("type", QString(metaField.getStreamer()->getName()));
|
||||
field.insert("name", QString(metaField.getName()));
|
||||
fields.append(field);
|
||||
}
|
||||
metadata.insert("fields", fields);
|
||||
return metadata;
|
||||
}
|
||||
case LIST_CATEGORY:
|
||||
case SET_CATEGORY: {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString(category == LIST_CATEGORY ? "LIST" : "SET"));
|
||||
const TypeStreamer* valueStreamer = getValueStreamer();
|
||||
writer.addTypeStreamer(valueStreamer);
|
||||
metadata.insert("valueType", QString(valueStreamer->getName()));
|
||||
return metadata;
|
||||
}
|
||||
case MAP_CATEGORY: {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("MAP"));
|
||||
const TypeStreamer* keyStreamer = getKeyStreamer();
|
||||
writer.addTypeStreamer(keyStreamer);
|
||||
metadata.insert("keyType", QString(keyStreamer->getName()));
|
||||
const TypeStreamer* valueStreamer = getValueStreamer();
|
||||
writer.addTypeStreamer(valueStreamer);
|
||||
metadata.insert("valueType", QString(valueStreamer->getName()));
|
||||
return metadata;
|
||||
}
|
||||
default:
|
||||
return QJsonValue();
|
||||
}
|
||||
}
|
||||
|
||||
QJsonValue TypeStreamer::getJSONData(JSONWriter& writer, const QVariant& value) const {
|
||||
return QJsonValue();
|
||||
}
|
||||
|
||||
bool TypeStreamer::equal(const QVariant& first, const QVariant& second) const {
|
||||
return first == second;
|
||||
}
|
||||
|
@ -2045,6 +2192,22 @@ void EnumTypeStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
}
|
||||
}
|
||||
|
||||
QJsonValue EnumTypeStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("ENUM"));
|
||||
QJsonArray values;
|
||||
QMetaEnum metaEnum = getMetaEnum();
|
||||
for (int i = 0; i < metaEnum.keyCount(); i++) {
|
||||
QJsonObject value;
|
||||
value.insert("key", QString(metaEnum.key(i)));
|
||||
value.insert("value", metaEnum.value(i));
|
||||
values.append(value);
|
||||
}
|
||||
metadata.insert("values", values);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
TypeStreamer::Category EnumTypeStreamer::getCategory() const {
|
||||
return ENUM_CATEGORY;
|
||||
}
|
||||
|
@ -2194,6 +2357,21 @@ void GenericEnumTypeStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
}
|
||||
}
|
||||
|
||||
QJsonValue GenericEnumTypeStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("ENUM"));
|
||||
QJsonArray values;
|
||||
foreach (const NameIntPair& value, _values) {
|
||||
QJsonObject object;
|
||||
object.insert("key", QString(value.first));
|
||||
object.insert("value", value.second);
|
||||
values.append(object);
|
||||
}
|
||||
metadata.insert("values", values);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
void GenericEnumTypeStreamer::write(Bitstream& out, const QVariant& value) const {
|
||||
int intValue = value.toInt();
|
||||
out.write(&intValue, _bits);
|
||||
|
@ -2270,6 +2448,22 @@ void GenericStreamableTypeStreamer::writeMetadata(Bitstream& out, bool full) con
|
|||
}
|
||||
}
|
||||
|
||||
QJsonValue GenericStreamableTypeStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("STREAMABLE"));
|
||||
QJsonArray fields;
|
||||
foreach (const StreamerNamePair& field, _fields) {
|
||||
QJsonObject object;
|
||||
writer.addTypeStreamer(field.first.data());
|
||||
object.insert("type", QString(field.first->getName()));
|
||||
object.insert("name", QString(field.second));
|
||||
fields.append(object);
|
||||
}
|
||||
metadata.insert("fields", fields);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
void GenericStreamableTypeStreamer::write(Bitstream& out, const QVariant& value) const {
|
||||
QVariantList values = value.toList();
|
||||
for (int i = 0; i < _fields.size(); i++) {
|
||||
|
@ -2334,6 +2528,15 @@ void GenericListTypeStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
out << _valueStreamer.data();
|
||||
}
|
||||
|
||||
QJsonValue GenericListTypeStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("LIST"));
|
||||
writer.addTypeStreamer(_valueStreamer.data());
|
||||
metadata.insert("valueType", QString(_valueStreamer->getName()));
|
||||
return metadata;
|
||||
}
|
||||
|
||||
void GenericListTypeStreamer::write(Bitstream& out, const QVariant& value) const {
|
||||
QVariantList values = value.toList();
|
||||
out << values.size();
|
||||
|
@ -2376,6 +2579,15 @@ GenericSetTypeStreamer::GenericSetTypeStreamer(const QByteArray& name, const Typ
|
|||
GenericListTypeStreamer(name, valueStreamer) {
|
||||
}
|
||||
|
||||
QJsonValue GenericSetTypeStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("SET"));
|
||||
writer.addTypeStreamer(_valueStreamer.data());
|
||||
metadata.insert("valueType", QString(_valueStreamer->getName()));
|
||||
return metadata;
|
||||
}
|
||||
|
||||
TypeStreamer::Category GenericSetTypeStreamer::getCategory() const {
|
||||
return SET_CATEGORY;
|
||||
}
|
||||
|
@ -2437,6 +2649,17 @@ void GenericMapTypeStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
out << _keyStreamer.data() << _valueStreamer.data();
|
||||
}
|
||||
|
||||
QJsonValue GenericMapTypeStreamer::getJSONMetadata(JSONWriter& writer) const {
|
||||
QJsonObject metadata;
|
||||
metadata.insert("name", QString(getName()));
|
||||
metadata.insert("category", QString("MAP"));
|
||||
writer.addTypeStreamer(_keyStreamer.data());
|
||||
metadata.insert("keyType", QString(_keyStreamer->getName()));
|
||||
writer.addTypeStreamer(_valueStreamer.data());
|
||||
metadata.insert("valueType", QString(_valueStreamer->getName()));
|
||||
return metadata;
|
||||
}
|
||||
|
||||
void GenericMapTypeStreamer::write(Bitstream& out, const QVariant& value) const {
|
||||
QVariantPairList values = value.value<QVariantPairList>();
|
||||
out << values.size();
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#define hifi_Bitstream_h
|
||||
|
||||
#include <QHash>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QMetaProperty>
|
||||
#include <QMetaType>
|
||||
#include <QPointer>
|
||||
|
@ -766,6 +768,41 @@ template<class K, class V> inline Bitstream& Bitstream::operator>>(QHash<K, V>&
|
|||
return *this;
|
||||
}
|
||||
|
||||
/// Tracks state when writing to JSON.
|
||||
class JSONWriter {
|
||||
public:
|
||||
|
||||
void addTypeStreamer(const TypeStreamer* streamer);
|
||||
void addObjectStreamer(const ObjectStreamer* streamer);
|
||||
void addSharedObject(const SharedObjectPointer& object);
|
||||
|
||||
private:
|
||||
|
||||
QSet<QByteArray> _typeStreamerNames;
|
||||
QJsonArray _typeStreamers;
|
||||
|
||||
QSet<QByteArray> _objectStreamerNames;
|
||||
QJsonArray _objectStreamers;
|
||||
|
||||
QSet<int> _sharedObjectIDs;
|
||||
QJsonArray _sharedObjects;
|
||||
};
|
||||
|
||||
/// Tracks state when reading from JSON.
|
||||
class JSONReader {
|
||||
public:
|
||||
|
||||
TypeStreamerPointer getTypeStreamer(const QByteArray& name) const { return _typeStreamers.value(name); }
|
||||
ObjectStreamerPointer getObjectStreamer(const QByteArray& name) const { return _objectStreamers.value(name); }
|
||||
SharedObjectPointer getSharedObject(int id) const { return _sharedObjects.value(id); }
|
||||
|
||||
private:
|
||||
|
||||
QHash<QByteArray, TypeStreamerPointer> _typeStreamers;
|
||||
QHash<QByteArray, ObjectStreamerPointer> _objectStreamers;
|
||||
QHash<int, SharedObjectPointer> _sharedObjects;
|
||||
};
|
||||
|
||||
typedef QPair<TypeStreamerPointer, QMetaProperty> StreamerPropertyPair;
|
||||
|
||||
/// Contains the information required to stream an object.
|
||||
|
@ -780,6 +817,8 @@ public:
|
|||
virtual const char* getName() const = 0;
|
||||
virtual const QVector<StreamerPropertyPair>& getProperties() const;
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const = 0;
|
||||
virtual QJsonObject getJSONMetadata(JSONWriter& writer) const = 0;
|
||||
virtual QJsonObject getJSONData(JSONWriter& writer, const QObject* object) const = 0;
|
||||
virtual void write(Bitstream& out, const QObject* object) const = 0;
|
||||
virtual void writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const = 0;
|
||||
virtual QObject* read(Bitstream& in, QObject* object = NULL) const = 0;
|
||||
|
@ -802,6 +841,8 @@ public:
|
|||
virtual const char* getName() const;
|
||||
virtual const QVector<StreamerPropertyPair>& getProperties() const;
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual QJsonObject getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual QJsonObject getJSONData(JSONWriter& writer, const QObject* object) const;
|
||||
virtual void write(Bitstream& out, const QObject* object) const;
|
||||
virtual void writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const;
|
||||
virtual QObject* read(Bitstream& in, QObject* object = NULL) const;
|
||||
|
@ -822,6 +863,8 @@ public:
|
|||
|
||||
virtual const char* getName() const;
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual QJsonObject getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual QJsonObject getJSONData(JSONWriter& writer, const QObject* object) const;
|
||||
virtual void write(Bitstream& out, const QObject* object) const;
|
||||
virtual void writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const;
|
||||
virtual QObject* read(Bitstream& in, QObject* object = NULL) const;
|
||||
|
@ -913,6 +956,9 @@ public:
|
|||
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
|
||||
virtual QJsonValue getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual QJsonValue getJSONData(JSONWriter& writer, const QVariant& value) const;
|
||||
|
||||
virtual bool equal(const QVariant& first, const QVariant& second) const;
|
||||
|
||||
virtual void write(Bitstream& out, const QVariant& value) const;
|
||||
|
@ -990,6 +1036,7 @@ public:
|
|||
|
||||
virtual const char* getName() const;
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual QJsonValue getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual Category getCategory() const;
|
||||
virtual int getBits() const;
|
||||
virtual QMetaEnum getMetaEnum() const;
|
||||
|
@ -1051,6 +1098,7 @@ public:
|
|||
GenericEnumTypeStreamer(const QByteArray& name, const QVector<NameIntPair>& values, int bits, const QByteArray& hash);
|
||||
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual QJsonValue getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual void write(Bitstream& out, const QVariant& value) const;
|
||||
virtual QVariant read(Bitstream& in) const;
|
||||
virtual Category getCategory() const;
|
||||
|
@ -1099,6 +1147,7 @@ public:
|
|||
GenericStreamableTypeStreamer(const QByteArray& name, const QVector<StreamerNamePair>& fields, const QByteArray& hash);
|
||||
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual QJsonValue getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual void write(Bitstream& out, const QVariant& value) const;
|
||||
virtual QVariant read(Bitstream& in) const;
|
||||
virtual Category getCategory() const;
|
||||
|
@ -1169,11 +1218,12 @@ public:
|
|||
GenericListTypeStreamer(const QByteArray& name, const TypeStreamerPointer& valueStreamer);
|
||||
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual QJsonValue getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual void write(Bitstream& out, const QVariant& value) const;
|
||||
virtual QVariant read(Bitstream& in) const;
|
||||
virtual Category getCategory() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
TypeStreamerPointer _valueStreamer;
|
||||
};
|
||||
|
@ -1206,6 +1256,7 @@ public:
|
|||
|
||||
GenericSetTypeStreamer(const QByteArray& name, const TypeStreamerPointer& valueStreamer);
|
||||
|
||||
virtual QJsonValue getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual Category getCategory() const;
|
||||
};
|
||||
|
||||
|
@ -1250,6 +1301,7 @@ public:
|
|||
const TypeStreamerPointer& valueStreamer);
|
||||
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual QJsonValue getJSONMetadata(JSONWriter& writer) const;
|
||||
virtual void write(Bitstream& out, const QVariant& value) const;
|
||||
virtual QVariant read(Bitstream& in) const;
|
||||
virtual Category getCategory() const;
|
||||
|
|
Loading…
Reference in a new issue