From 9aa152f43ff01938c5b8e87105426541c2357ba3 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 10 Jun 2014 18:29:21 -0700 Subject: [PATCH] More TypeReader refactoring progress. --- libraries/metavoxels/src/Bitstream.cpp | 157 ++++++++++++++++++++++++- libraries/metavoxels/src/Bitstream.h | 60 +++++++++- 2 files changed, 213 insertions(+), 4 deletions(-) diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index ca6cd5dd83..83ec86013c 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -1950,11 +1950,22 @@ QVariant TypeStreamer::read(Bitstream& in) const { } void TypeStreamer::writeDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const { - // nothing by default + if (value == reference) { + out << false; + } else { + out << true; + writeRawDelta(out, value, reference); + } } void TypeStreamer::readDelta(Bitstream& in, QVariant& value, const QVariant& reference) const { - value = reference; + bool changed; + in >> changed; + if (changed) { + readRawDelta(in, value, reference); + } else { + value = reference; + } } void TypeStreamer::writeRawDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const { @@ -2151,6 +2162,30 @@ void EnumTypeStreamer::setEnumValue(QVariant& object, int value, const QHash& mappings) : + _baseStreamer(baseStreamer), + _bits(bits), + _mappings(mappings) { +} + +QVariant MappedEnumTypeStreamer::read(Bitstream& in) const { + QVariant object = _baseStreamer ? QVariant(_baseStreamer->getType(), 0) : QVariant(); + int value = 0; + in.read(&value, _bits); + if (_baseStreamer) { + _baseStreamer->setEnumValue(object, value, _mappings); + } + return object; +} + +void MappedEnumTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const { + int value = 0; + in.read(&value, _bits); + if (_baseStreamer) { + _baseStreamer->setEnumValue(object, value, _mappings); + } +} + GenericValue::GenericValue(const TypeStreamerPointer& streamer, const QVariant& value) : _streamer(streamer), _value(value) { @@ -2163,3 +2198,121 @@ bool GenericValue::operator==(const GenericValue& other) const { const TypeStreamer* GenericTypeStreamer::getStreamerToWrite(const QVariant& value) const { return value.value().getStreamer().data(); } + +MappedListTypeStreamer::MappedListTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer) : + _baseStreamer(baseStreamer), + _valueStreamer(valueStreamer) { +} + +QVariant MappedListTypeStreamer::read(Bitstream& in) const { + QVariant object = _baseStreamer ? QVariant(_baseStreamer->getType(), 0) : QVariant(); + int size; + in >> size; + for (int i = 0; i < size; i++) { + QVariant value = _valueStreamer->read(in); + if (_baseStreamer) { + _baseStreamer->insert(object, value); + } + } + return object; +} + +void MappedListTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const { + object = reference; + int size, referenceSize; + in >> size >> referenceSize; + if (_baseStreamer) { + if (size < referenceSize) { + _baseStreamer->prune(object, size); + } + for (int i = 0; i < size; i++) { + if (i < referenceSize) { + QVariant value; + _valueStreamer->readDelta(in, value, _baseStreamer->getValue(reference, i)); + _baseStreamer->setValue(object, i, value); + } else { + _baseStreamer->insert(object, _valueStreamer->read(in)); + } + } + } else { + for (int i = 0; i < size; i++) { + if (i < referenceSize) { + QVariant value; + _valueStreamer->readDelta(in, value, QVariant()); + } else { + _valueStreamer->read(in); + } + } + } +} + +MappedSetTypeStreamer::MappedSetTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer) : + MappedListTypeStreamer(baseStreamer, valueStreamer) { +} + +void MappedSetTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const { + object = reference; + int addedOrRemoved; + in >> addedOrRemoved; + for (int i = 0; i < addedOrRemoved; i++) { + QVariant value = _valueStreamer->read(in); + if (_baseStreamer && !_baseStreamer->remove(object, value)) { + _baseStreamer->insert(object, value); + } + } +} + +MappedMapTypeStreamer::MappedMapTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& keyStreamer, + const TypeStreamerPointer& valueStreamer) : + _baseStreamer(baseStreamer), + _keyStreamer(keyStreamer), + _valueStreamer(valueStreamer) { +} + +QVariant MappedMapTypeStreamer::read(Bitstream& in) const { + QVariant object = _baseStreamer ? QVariant(_baseStreamer->getType(), 0) : QVariant(); + int size; + in >> size; + for (int i = 0; i < size; i++) { + QVariant key = _keyStreamer->read(in); + QVariant value = _valueStreamer->read(in); + if (_baseStreamer) { + _baseStreamer->insert(object, key, value); + } + } + return object; +} + +void MappedMapTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const { + object = reference; + int added; + in >> added; + for (int i = 0; i < added; i++) { + QVariant key = _keyStreamer->read(in); + QVariant value = _valueStreamer->read(in); + if (_baseStreamer) { + _baseStreamer->insert(object, key, value); + } + } + int modified; + in >> modified; + for (int i = 0; i < modified; i++) { + QVariant key = _keyStreamer->read(in); + QVariant value; + if (_baseStreamer) { + _valueStreamer->readDelta(in, value, _baseStreamer->getValue(reference, key)); + _baseStreamer->insert(object, key, value); + } else { + _valueStreamer->readDelta(in, value, QVariant()); + } + } + int removed; + in >> removed; + for (int i = 0; i < removed; i++) { + QVariant key = _keyStreamer->read(in); + if (_baseStreamer) { + _baseStreamer->remove(object, key); + } + } +} + diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index dadfe52911..cd7a0439aa 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -47,6 +47,7 @@ class TypeStreamer; typedef SharedObjectPointerTemplate AttributePointer; typedef QPair ScopeNamePair; +typedef QSharedPointer TypeStreamerPointer; typedef QVector PropertyReaderVector; typedef QVector PropertyWriterVector; @@ -904,8 +905,6 @@ Q_DECLARE_METATYPE(const QMetaObject*) /// Macro for registering streamable meta-objects. #define REGISTER_META_OBJECT(x) static int x##Registration = Bitstream::registerMetaObject(#x, &x::staticMetaObject); -typedef QSharedPointer TypeStreamerPointer; - /// Interface for objects that can write values to and read values from bitstreams. class TypeStreamer { public: @@ -1014,6 +1013,22 @@ private: int _bits; }; +/// A streamer class for enums that maps to a local type. +class MappedEnumTypeStreamer : public TypeStreamer { +public: + + MappedEnumTypeStreamer(const TypeStreamer* baseStreamer, int bits, const QHash& mappings); + + virtual QVariant read(Bitstream& in) const; + virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const; + +private: + + const TypeStreamer* _baseStreamer; + int _bits; + QHash _mappings; +}; + /// Contains a value along with a pointer to its streamer. class GenericValue { public: @@ -1089,6 +1104,21 @@ public: static_cast*>(object.data())->replace(index, value.value()); } }; +/// A streamer for lists that maps to a local type. +class MappedListTypeStreamer : public TypeStreamer { +public: + + MappedListTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer); + + virtual QVariant read(Bitstream& in) const; + virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const; + +protected: + + const TypeStreamer* _baseStreamer; + TypeStreamerPointer _valueStreamer; +}; + /// A streamer for set types. template class CollectionTypeStreamer > : public SimpleTypeStreamer > { public: @@ -1101,6 +1131,15 @@ public: return static_cast*>(object.data())->remove(key.value()); } }; +/// A streamer for sets that maps to a local type. +class MappedSetTypeStreamer : public MappedListTypeStreamer { +public: + + MappedSetTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer); + + virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const; +}; + /// A streamer for hash types. template class CollectionTypeStreamer > : public SimpleTypeStreamer > { public: @@ -1116,6 +1155,23 @@ public: return QVariant::fromValue(static_cast*>(object.constData())->value(key.value())); } }; +/// A streamer for maps that maps to a local type. +class MappedMapTypeStreamer : public TypeStreamer { +public: + + MappedMapTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& keyStreamer, + const TypeStreamerPointer& valueStreamer); + + virtual QVariant read(Bitstream& in) const; + virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const; + +private: + + const TypeStreamer* _baseStreamer; + TypeStreamerPointer _keyStreamer; + TypeStreamerPointer _valueStreamer; +}; + /// Macro for registering simple type streamers. #define REGISTER_SIMPLE_TYPE_STREAMER(X) static int X##Streamer = \ Bitstream::registerTypeStreamer(qMetaTypeId(), new SimpleTypeStreamer());