diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 34e3614716..334711ea16 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index 070ad550d8..888681c4c9 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -903,7 +903,29 @@ void TypeReader::readDelta(Bitstream& in, QVariant& object, const QVariant& refe object = reference; int size, referenceSize; in >> size >> referenceSize; - + if (_streamer) { + if (size < referenceSize) { + _streamer->prune(object, size); + } + for (int i = 0; i < size; i++) { + if (i < referenceSize) { + QVariant value; + _valueReader->readDelta(in, value, _streamer->getValue(reference, i)); + _streamer->setValue(object, i, value); + } else { + _streamer->insert(object, _valueReader->read(in)); + } + } + } else { + for (int i = 0; i < size; i++) { + if (i < referenceSize) { + QVariant value; + _valueReader->readDelta(in, value, QVariant()); + } else { + _valueReader->read(in); + } + } + } break; } case SET_TYPE: { @@ -933,7 +955,13 @@ void TypeReader::readDelta(Bitstream& in, QVariant& object, const QVariant& refe in >> modified; for (int i = 0; i < modified; i++) { QVariant key = _keyReader->read(in); - + QVariant value; + if (_streamer) { + _valueReader->readDelta(in, value, _streamer->getValue(reference, key)); + _streamer->insert(object, key, value); + } else { + _valueReader->readDelta(in, value, QVariant()); + } } int removed; in >> removed; @@ -966,12 +994,18 @@ FieldReader::FieldReader(const TypeReader& reader, int index) : void FieldReader::read(Bitstream& in, const TypeStreamer* streamer, QVariant& object) const { QVariant value = _reader.read(in); if (_index != -1 && streamer) { - streamer->setField(_index, object, value); + streamer->setField(object, _index, value); } } void FieldReader::readDelta(Bitstream& in, const TypeStreamer* streamer, QVariant& object, const QVariant& reference) const { - // TODO: field delta + QVariant value; + if (_index != -1 && streamer) { + _reader.readDelta(in, value, streamer->getField(reference, _index)); + streamer->setField(object, _index, value); + } else { + _reader.readDelta(in, value, QVariant()); + } } ObjectReader::ObjectReader(const QByteArray& className, const QMetaObject* metaObject, @@ -1024,10 +1058,14 @@ int TypeStreamer::getFieldIndex(const QByteArray& name) const { return -1; } -void TypeStreamer::setField(int index, QVariant& object, const QVariant& value) const { +void TypeStreamer::setField(QVariant& object, int index, const QVariant& value) const { // nothing by default } +QVariant TypeStreamer::getField(const QVariant& object, int index) const { + return QVariant(); +} + TypeReader::Type TypeStreamer::getReaderType() const { return TypeReader::SIMPLE_TYPE; } @@ -1051,3 +1089,19 @@ void TypeStreamer::insert(QVariant& object, const QVariant& key, const QVariant& bool TypeStreamer::remove(QVariant& object, const QVariant& key) const { return false; } + +QVariant TypeStreamer::getValue(const QVariant& object, const QVariant& key) const { + return QVariant(); +} + +void TypeStreamer::prune(QVariant& object, int size) const { + // nothing by default +} + +QVariant TypeStreamer::getValue(const QVariant& object, int index) const { + return QVariant(); +} + +void TypeStreamer::setValue(QVariant& object, int index, const QVariant& value) const { + // nothing by default +} diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index cfee647d28..4aac34ab1f 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -271,14 +271,17 @@ public: template void writeDelta(const T& value, const T& reference); template void readDelta(T& value, const T& reference); - template void writeDelta(const QList& value, const QList& reference); - template void readDelta(QList& value, const QList& reference); + template void writeRawDelta(const T& value, const T& reference); + template void readRawDelta(T& value, const T& reference); - template void writeDelta(const QSet& value, const QSet& reference); - template void readDelta(QSet& value, const QSet& reference); + template void writeRawDelta(const QList& value, const QList& reference); + template void readRawDelta(QList& value, const QList& reference); - template void writeDelta(const QHash& value, const QHash& reference); - template void readDelta(QHash& value, const QHash& reference); + template void writeRawDelta(const QSet& value, const QSet& reference); + template void readRawDelta(QSet& value, const QSet& reference); + + template void writeRawDelta(const QHash& value, const QHash& reference); + template void readRawDelta(QHash& value, const QHash& reference); Bitstream& operator<<(bool value); Bitstream& operator>>(bool& value); @@ -395,7 +398,7 @@ template inline void Bitstream::writeDelta(const T& value, const T& ref *this << false; } else { *this << true; - *this << value; + writeRawDelta(value, reference); } } @@ -403,18 +406,29 @@ template inline void Bitstream::readDelta(T& value, const T& reference) bool changed; *this >> changed; if (changed) { - *this >> value; + readRawDelta(value, reference); } else { value = reference; } } -template inline void Bitstream::writeDelta(const QList& value, const QList& reference) { - if (value == reference) { - *this << false; - return; - } - *this << true; +template<> inline void Bitstream::writeDelta(const bool& value, const bool& reference) { + *this << value; +} + +template<> inline void Bitstream::readDelta(bool& value, const bool& reference) { + *this >> value; +} + +template inline void Bitstream::writeRawDelta(const T& value, const T& reference) { + *this << value; +} + +template inline void Bitstream::readRawDelta(T& value, const T& reference) { + *this >> value; +} + +template inline void Bitstream::writeRawDelta(const QList& value, const QList& reference) { *this << value.size(); *this << reference.size(); for (int i = 0; i < value.size(); i++) { @@ -426,13 +440,8 @@ template inline void Bitstream::writeDelta(const QList& value, const } } -template inline void Bitstream::readDelta(QList& value, const QList& reference) { +template inline void Bitstream::readRawDelta(QList& value, const QList& reference) { value = reference; - bool changed; - *this >> changed; - if (!changed) { - return; - } int size, referenceSize; *this >> size >> referenceSize; if (size < value.size()) { @@ -449,12 +458,7 @@ template inline void Bitstream::readDelta(QList& value, const QList< } } -template inline void Bitstream::writeDelta(const QSet& value, const QSet& reference) { - if (value == reference) { - *this << false; - return; - } - *this << true; +template inline void Bitstream::writeRawDelta(const QSet& value, const QSet& reference) { int addedOrRemoved = 0; foreach (const T& element, value) { if (!reference.contains(element)) { @@ -479,13 +483,8 @@ template inline void Bitstream::writeDelta(const QSet& value, const } } -template inline void Bitstream::readDelta(QSet& value, const QSet& reference) { +template inline void Bitstream::readRawDelta(QSet& value, const QSet& reference) { value = reference; - bool changed; - *this >> changed; - if (!changed) { - return; - } int addedOrRemoved; *this >> addedOrRemoved; for (int i = 0; i < addedOrRemoved; i++) { @@ -497,12 +496,7 @@ template inline void Bitstream::readDelta(QSet& value, const QSet } } -template inline void Bitstream::writeDelta(const QHash& value, const QHash& reference) { - if (value == reference) { - *this << false; - return; - } - *this << true; +template inline void Bitstream::writeRawDelta(const QHash& value, const QHash& reference) { int added = 0; int modified = 0; for (typename QHash::const_iterator it = value.constBegin(); it != value.constEnd(); it++) { @@ -542,13 +536,8 @@ template inline void Bitstream::writeDelta(const QHash& } } -template inline void Bitstream::readDelta(QHash& value, const QHash& reference) { +template inline void Bitstream::readRawDelta(QHash& value, const QHash& reference) { value = reference; - bool changed; - *this >> changed; - if (!changed) { - return; - } int added; *this >> added; for (int i = 0; i < added; i++) { @@ -774,7 +763,8 @@ public: virtual const QVector& getMetaFields() const; virtual int getFieldIndex(const QByteArray& name) const; - virtual void setField(int index, QVariant& object, const QVariant& value) const; + virtual void setField(QVariant& object, int index, const QVariant& value) const; + virtual QVariant getField(const QVariant& object, int index) const; virtual TypeReader::Type getReaderType() const; @@ -784,6 +774,12 @@ public: virtual void insert(QVariant& object, const QVariant& value) const; virtual void insert(QVariant& object, const QVariant& key, const QVariant& value) const; virtual bool remove(QVariant& object, const QVariant& key) const; + + virtual QVariant getValue(const QVariant& object, const QVariant& key) const; + + virtual void prune(QVariant& object, int size) const; + virtual QVariant getValue(const QVariant& object, int index) const; + virtual void setValue(QVariant& object, int index, const QVariant& value) const; private: @@ -809,8 +805,10 @@ public: virtual TypeReader::Type getReaderType() const { return TypeReader::STREAMABLE_TYPE; } virtual const QVector& getMetaFields() const { return T::getMetaFields(); } virtual int getFieldIndex(const QByteArray& name) const { return T::getFieldIndex(name); } - virtual void setField(int index, QVariant& object, const QVariant& value) const { + virtual void setField(QVariant& object, int index, const QVariant& value) const { static_cast(object.data())->setField(index, value); } + virtual QVariant getField(const QVariant& object, int index) const { + return static_cast(object.constData())->getField(index); } }; /// Base template for collection streamers. @@ -825,6 +823,12 @@ public: virtual const TypeStreamer* getValueStreamer() const { return Bitstream::getTypeStreamer(qMetaTypeId()); } virtual void insert(QVariant& object, const QVariant& value) const { static_cast*>(object.data())->append(value.value()); } + virtual void prune(QVariant& object, int size) const { + QList* list = static_cast*>(object.data()); list->erase(list->begin() + size, list->end()); } + virtual QVariant getValue(const QVariant& object, int index) const { + return QVariant::fromValue(static_cast*>(object.constData()).at(index)); } + virtual void setValue(QVariant& object, int index, const QVariant& value) const { + static_cast*>(object.data())->replace(index, value.value()); } }; /// A streamer for set types. @@ -850,6 +854,8 @@ public: static_cast*>(object.data())->insert(key.value(), value.value()); } virtual bool remove(QVariant& object, const QVariant& key) const { return static_cast*>(object.data())->remove(key.value()); } + virtual QVariant getValue(const QVariant& object, const QVariant& key) const { + return QVariant::fromValue(static_cast*>(object.constData())->value(key.value())); } }; /// Macro for registering simple type streamers. @@ -866,8 +872,8 @@ public: #define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \ Bitstream& operator<<(Bitstream& out, const X& obj); \ Bitstream& operator>>(Bitstream& in, X& obj); \ - template<> void Bitstream::writeDelta(const X& value, const X& reference); \ - template<> void Bitstream::readDelta(X& value, const X& reference); \ + template<> void Bitstream::writeRawDelta(const X& value, const X& reference); \ + template<> void Bitstream::readRawDelta(X& value, const X& reference); \ bool operator==(const X& first, const X& second); \ bool operator!=(const X& first, const X& second); \ static const int* _TypePtr##X = &X::Type; @@ -875,8 +881,8 @@ public: #define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \ Bitstream& operator<<(Bitstream& out, const X& obj); \ Bitstream& operator>>(Bitstream& in, X& obj); \ - template<> void Bitstream::writeDelta(const X& value, const X& reference); \ - template<> void Bitstream::readDelta(X& value, const X& reference); \ + template<> void Bitstream::writeRawDelta(const X& value, const X& reference); \ + template<> void Bitstream::readRawDelta(X& value, const X& reference); \ bool operator==(const X& first, const X& second); \ bool operator!=(const X& first, const X& second); \ __attribute__((unused)) static const int* _TypePtr##X = &X::Type; @@ -885,8 +891,8 @@ public: #define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \ Bitstream& operator<<(Bitstream& out, const X& obj); \ Bitstream& operator>>(Bitstream& in, X& obj); \ - template<> void Bitstream::writeDelta(const X& value, const X& reference); \ - template<> void Bitstream::readDelta(X& value, const X& reference); \ + template<> void Bitstream::writeRawDelta(const X& value, const X& reference); \ + template<> void Bitstream::readRawDelta(X& value, const X& reference); \ bool operator==(const X& first, const X& second); \ bool operator!=(const X& first, const X& second); \ static const int* _TypePtr##X = &X::Type; \ @@ -906,6 +912,7 @@ template int registerStreamableMetaType() { static const QVector& getMetaFields(); \ static int getFieldIndex(const QByteArray& name); \ void setField(int index, const QVariant& value); \ + QVariant getField(int index) const; \ private: \ static QHash createFieldIndices(); diff --git a/tools/mtc/src/main.cpp b/tools/mtc/src/main.cpp index 861b7310b8..9c77851961 100644 --- a/tools/mtc/src/main.cpp +++ b/tools/mtc/src/main.cpp @@ -152,6 +152,25 @@ void generateOutput (QTextStream& out, const QList& streamables) { out << " }\n"; out << "}\n"; + out << "QVariant " << name << "::getField(int index) const {\n"; + if (!str.clazz.bases.isEmpty()) { + out << " int nextIndex;\n"; + } + foreach (const QString& base, str.clazz.bases) { + out << " if ((nextIndex = index - " << base << "::getMetaFields().size()) < 0) {\n"; + out << " return " << base << "::getField(index);\n"; + out << " }\n"; + out << " index = nextIndex;\n"; + } + out << " switch (index) {\n"; + for (int i = 0; i < str.fields.size(); i++) { + out << " case " << i << ":\n"; + out << " return QVariant::fromValue(this->" << str.fields.at(i).name << ");\n"; + } + out << " }\n"; + out << " return QVariant();\n"; + out << "}\n"; + out << "Bitstream& operator<<(Bitstream& out, const " << name << "& obj) {\n"; foreach (const QString& base, str.clazz.bases) { out << " out << static_cast(obj);\n"; @@ -172,14 +191,9 @@ void generateOutput (QTextStream& out, const QList& streamables) { out << " return in;\n"; out << "}\n"; - out << "template<> void Bitstream::writeDelta(const " << name << "& value, const " << name << "& reference) {\n"; - out << " if (value == reference) {\n"; - out << " *this << false;\n"; - out << " return;\n"; - out << " }\n"; - out << " *this << true;\n"; + out << "template<> void Bitstream::writeRawDelta(const " << name << "& value, const " << name << "& reference) {\n"; foreach (const QString& base, str.clazz.bases) { - out << " writeDelta(static_cast(value), static_cast(value), static_cast(reference));\n"; } foreach (const Field& field, str.fields) { @@ -187,15 +201,9 @@ void generateOutput (QTextStream& out, const QList& streamables) { } out << "}\n"; - out << "template<> void Bitstream::readDelta(" << name << "& value, const " << name << "& reference) {\n"; - out << " bool changed;\n"; - out << " *this >> changed;\n"; - out << " if (!changed) {\n"; - out << " value = reference;\n"; - out << " return;\n"; - out << " }\n"; + out << "template<> void Bitstream::readRawDelta(" << name << "& value, const " << name << "& reference) {\n"; foreach (const QString& base, str.clazz.bases) { - out << " readDelta(static_cast<" << base << "&>(value), static_cast(value), static_cast(reference));\n"; } foreach (const Field& field, str.fields) {