From 9e151001e032ac78ef796e3318e3942bb527d3fc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 12 Jun 2014 18:47:18 -0700 Subject: [PATCH] More object streaming refactory. --- libraries/metavoxels/src/Bitstream.cpp | 392 ++++++++++++------------- libraries/metavoxels/src/Bitstream.h | 129 +++----- 2 files changed, 216 insertions(+), 305 deletions(-) diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index f1c927451b..760b1fc646 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -124,7 +124,7 @@ Bitstream::Bitstream(QDataStream& underlying, MetadataType metadataType, Generic _position(0), _metadataType(metadataType), _genericsMode(genericsMode), - _metaObjectStreamer(*this), + _objectStreamerStreamer(*this), _typeStreamerStreamer(*this), _attributeStreamer(*this), _scriptStringStreamer(*this), @@ -198,7 +198,7 @@ void Bitstream::reset() { } Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() { - WriteMappings mappings = { _metaObjectStreamer.getAndResetTransientOffsets(), + WriteMappings mappings = { _objectStreamerStreamer.getAndResetTransientOffsets(), _typeStreamerStreamer.getAndResetTransientOffsets(), _attributeStreamer.getAndResetTransientOffsets(), _scriptStringStreamer.getAndResetTransientOffsets(), @@ -207,7 +207,7 @@ Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() { } void Bitstream::persistWriteMappings(const WriteMappings& mappings) { - _metaObjectStreamer.persistTransientOffsets(mappings.metaObjectOffsets); + _objectStreamerStreamer.persistTransientOffsets(mappings.objectStreamerOffsets); _typeStreamerStreamer.persistTransientOffsets(mappings.typeStreamerOffsets); _attributeStreamer.persistTransientOffsets(mappings.attributeOffsets); _scriptStringStreamer.persistTransientOffsets(mappings.scriptStringOffsets); @@ -235,7 +235,7 @@ void Bitstream::persistAndResetWriteMappings() { } Bitstream::ReadMappings Bitstream::getAndResetReadMappings() { - ReadMappings mappings = { _metaObjectStreamer.getAndResetTransientValues(), + ReadMappings mappings = { _objectStreamerStreamer.getAndResetTransientValues(), _typeStreamerStreamer.getAndResetTransientValues(), _attributeStreamer.getAndResetTransientValues(), _scriptStringStreamer.getAndResetTransientValues(), @@ -244,7 +244,7 @@ Bitstream::ReadMappings Bitstream::getAndResetReadMappings() { } void Bitstream::persistReadMappings(const ReadMappings& mappings) { - _metaObjectStreamer.persistTransientValues(mappings.metaObjectValues); + _objectStreamerStreamer.persistTransientValues(mappings.objectStreamerValues); _typeStreamerStreamer.persistTransientValues(mappings.typeStreamerValues); _attributeStreamer.persistTransientValues(mappings.attributeValues); _scriptStringStreamer.persistTransientValues(mappings.scriptStringValues); @@ -310,20 +310,20 @@ void Bitstream::readRawDelta(QVariant& value, const QVariant& reference) { void Bitstream::writeRawDelta(const QObject* value, const QObject* reference) { if (!value) { - _metaObjectStreamer << NULL; + _objectStreamerStreamer << NULL; return; } const QMetaObject* metaObject = value->metaObject(); - _metaObjectStreamer << metaObject; - foreach (const PropertyWriter& propertyWriter, getPropertyWriters().value(metaObject)) { - propertyWriter.writeDelta(*this, value, reference); - } + const ObjectStreamer* streamer = (metaObject == &GenericSharedObject::staticMetaObject) ? + static_cast(value)->getStreamer().data() : getObjectStreamers().value(metaObject); + _objectStreamerStreamer << streamer; + streamer->writeRawDelta(*this, value, reference); } void Bitstream::readRawDelta(QObject*& value, const QObject* reference) { - ObjectReader objectReader; - _metaObjectStreamer >> objectReader; - value = objectReader.readDelta(*this, reference); + ObjectStreamerPointer streamer; + _objectStreamerStreamer >> streamer; + value = streamer ? streamer->readRawDelta(*this, reference) : NULL; } void Bitstream::writeRawDelta(const QScriptValue& value, const QScriptValue& reference) { @@ -814,38 +814,50 @@ Bitstream& Bitstream::operator>>(GenericValue& value) { Bitstream& Bitstream::operator<<(const QObject* object) { if (!object) { - _metaObjectStreamer << NULL; + _objectStreamerStreamer << NULL; return *this; } const QMetaObject* metaObject = object->metaObject(); - _metaObjectStreamer << metaObject; - foreach (const PropertyWriter& propertyWriter, getPropertyWriters().value(metaObject)) { - propertyWriter.write(*this, object); - } + const ObjectStreamer* streamer = (metaObject == &GenericSharedObject::staticMetaObject) ? + static_cast(object)->getStreamer().data() : getObjectStreamers().value(metaObject); + _objectStreamerStreamer << streamer; + streamer->write(*this, object); return *this; } Bitstream& Bitstream::operator>>(QObject*& object) { - ObjectReader objectReader; - _metaObjectStreamer >> objectReader; - object = objectReader.read(*this); + ObjectStreamerPointer streamer; + _objectStreamerStreamer >> streamer; + object = streamer ? streamer->read(*this) : NULL; return *this; } Bitstream& Bitstream::operator<<(const QMetaObject* metaObject) { - _metaObjectStreamer << metaObject; + _objectStreamerStreamer << getObjectStreamers().value(metaObject); return *this; } Bitstream& Bitstream::operator>>(const QMetaObject*& metaObject) { - ObjectReader objectReader; - _metaObjectStreamer >> objectReader; - metaObject = objectReader.getMetaObject(); + ObjectStreamerPointer streamer; + _objectStreamerStreamer >> streamer; + metaObject = streamer->getMetaObject(); return *this; } -Bitstream& Bitstream::operator>>(ObjectReader& objectReader) { - _metaObjectStreamer >> objectReader; +Bitstream& Bitstream::operator<<(const ObjectStreamer* streamer) { + _objectStreamerStreamer << streamer; + return *this; +} + +Bitstream& Bitstream::operator>>(const ObjectStreamer*& streamer) { + ObjectStreamerPointer objectStreamer; + _objectStreamerStreamer >> objectStreamer; + streamer = objectStreamer.data(); + return *this; +} + +Bitstream& Bitstream::operator>>(ObjectStreamerPointer& streamer) { + _objectStreamerStreamer >> streamer; return *this; } @@ -1075,55 +1087,53 @@ Bitstream& Bitstream::operator>>(SharedObjectPointer& object) { return *this; } -Bitstream& Bitstream::operator<(const QMetaObject* metaObject) { - if (!metaObject) { +Bitstream& Bitstream::operator<(const ObjectStreamer* streamer) { + if (!streamer) { return *this << QByteArray(); } - *this << QByteArray::fromRawData(metaObject->className(), strlen(metaObject->className())); - if (_metadataType == NO_METADATA) { - return *this; - } - const PropertyWriterVector& propertyWriters = getPropertyWriters().value(metaObject); - *this << propertyWriters.size(); - QCryptographicHash hash(QCryptographicHash::Md5); - foreach (const PropertyWriter& propertyWriter, propertyWriters) { - _typeStreamerStreamer << propertyWriter.getStreamer(); - const QMetaProperty& property = propertyWriter.getProperty(); - if (_metadataType == FULL_METADATA) { - *this << QByteArray::fromRawData(property.name(), strlen(property.name())); - } else { - hash.addData(property.name(), strlen(property.name()) + 1); - } - } - if (_metadataType == HASH_METADATA) { - QByteArray hashResult = hash.result(); - write(hashResult.constData(), hashResult.size() * BITS_IN_BYTE); + const char* name = streamer->getName(); + *this << QByteArray::fromRawData(name, strlen(name)); + if (_metadataType != NO_METADATA) { + streamer->writeMetadata(*this, _metadataType == FULL_METADATA); } return *this; } -Bitstream& Bitstream::operator>(ObjectReader& objectReader) { +Bitstream& Bitstream::operator>(ObjectStreamerPointer& streamer) { QByteArray className; *this >> className; if (className.isEmpty()) { - objectReader = ObjectReader(); + streamer = ObjectStreamerPointer(); return *this; } const QMetaObject* metaObject = _metaObjectSubstitutions.value(className); if (!metaObject) { metaObject = getMetaObjects().value(className); } - if (!metaObject) { - qWarning() << "Unknown class name: " << className << "\n"; + // start out with the streamer for the named class, if any + if (metaObject) { + streamer = getObjectStreamers().value(metaObject)->getSelf(); + } else { + streamer = ObjectStreamerPointer(); } if (_metadataType == NO_METADATA) { - objectReader = ObjectReader(className, metaObject, getPropertyReaders().value(metaObject)); + if (!metaObject) { + qWarning() << "Unknown class name:" << className; + } return *this; } - int storedPropertyCount; - *this >> storedPropertyCount; - PropertyReaderVector properties(storedPropertyCount); - for (int i = 0; i < storedPropertyCount; i++) { + if (_genericsMode == ALL_GENERICS) { + streamer = readGenericObjectStreamer(className); + return *this; + } + if (!metaObject && _genericsMode == FALLBACK_GENERICS) { + streamer = readGenericObjectStreamer(className); + return *this; + } + int propertyCount; + *this >> propertyCount; + QVector properties(propertyCount); + for (int i = 0; i < propertyCount; i++) { TypeStreamerPointer typeStreamer; *this >> typeStreamer; QMetaProperty property = QMetaProperty(); @@ -1134,23 +1144,22 @@ Bitstream& Bitstream::operator>(ObjectReader& objectReader) { property = metaObject->property(metaObject->indexOfProperty(propertyName)); } } - properties[i] = PropertyReader(typeStreamer, property); + properties[i] = StreamerPropertyPair(typeStreamer, property); } // for hash metadata, check the names/types of the properties as well as the name hash against our own class if (_metadataType == HASH_METADATA) { QCryptographicHash hash(QCryptographicHash::Md5); bool matches = true; if (metaObject) { - const PropertyWriterVector& propertyWriters = getPropertyWriters().value(metaObject); - if (propertyWriters.size() == properties.size()) { - for (int i = 0; i < propertyWriters.size(); i++) { - const PropertyWriter& propertyWriter = propertyWriters.at(i); - if (properties.at(i).getStreamer() != propertyWriter.getStreamer()) { + const QVector& localProperties = streamer->getProperties(); + if (localProperties.size() == properties.size()) { + for (int i = 0; i < localProperties.size(); i++) { + const StreamerPropertyPair& localProperty = localProperties.at(i); + if (localProperty.first != properties.at(i).first) { matches = false; break; } - const QMetaProperty& property = propertyWriter.getProperty(); - hash.addData(property.name(), strlen(property.name()) + 1); + hash.addData(localProperty.second.name(), strlen(localProperty.second.name()) + 1); } } else { matches = false; @@ -1160,11 +1169,24 @@ Bitstream& Bitstream::operator>(ObjectReader& objectReader) { QByteArray remoteHashResult(localHashResult.size(), 0); read(remoteHashResult.data(), remoteHashResult.size() * BITS_IN_BYTE); if (metaObject && matches && localHashResult == remoteHashResult) { - objectReader = ObjectReader(className, metaObject, getPropertyReaders().value(metaObject)); return *this; } + } else if (metaObject) { + const QVector& localProperties = streamer->getProperties(); + if (localProperties.size() != properties.size()) { + streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties)); + return *this; + } + for (int i = 0; i < localProperties.size(); i++) { + const StreamerPropertyPair& property = properties.at(i); + if (localProperties.at(i).first != property.first || property.second.propertyIndex() != i) { + streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties)); + return *this; + } + } + return *this; } - objectReader = ObjectReader(className, metaObject, properties); + streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties)); return *this; } @@ -1405,12 +1427,12 @@ Bitstream& Bitstream::operator>(SharedObjectPointer& object) { QPointer reference = _sharedObjectReferences.value(originID); QPointer& pointer = _weakSharedObjectHash[id]; if (pointer) { - ObjectReader objectReader; - _metaObjectStreamer >> objectReader; + ObjectStreamerPointer objectStreamer; + _objectStreamerStreamer >> objectStreamer; if (reference) { - objectReader.readDelta(*this, reference.data(), pointer.data()); + objectStreamer->readRawDelta(*this, reference.data(), pointer.data()); } else { - objectReader.read(*this, pointer.data()); + objectStreamer->read(*this, pointer.data()); } } else { QObject* rawObject; @@ -1445,6 +1467,31 @@ void Bitstream::clearSharedObject(QObject* object) { const int MD5_HASH_SIZE = 16; +ObjectStreamerPointer Bitstream::readGenericObjectStreamer(const QByteArray& name) { + int propertyCount; + *this >> propertyCount; + QVector properties(propertyCount); + QByteArray hash; + if (propertyCount > 0) { + for (int i = 0; i < propertyCount; i++) { + TypeStreamerPointer streamer; + *this >> streamer; + QByteArray name; + if (_metadataType == FULL_METADATA) { + *this >> name; + } + properties[i] = StreamerNamePair(streamer, name); + } + if (_metadataType == HASH_METADATA) { + hash.resize(MD5_HASH_SIZE); + read(hash.data(), hash.size() * BITS_IN_BYTE); + } + } + ObjectStreamerPointer streamer = ObjectStreamerPointer(new GenericObjectStreamer(name, properties, hash)); + static_cast(streamer.data())->_weakSelf = streamer; + return streamer; +} + TypeStreamerPointer Bitstream::readGenericTypeStreamer(const QByteArray& name, int category) { TypeStreamerPointer streamer; switch (category) { @@ -1528,6 +1575,40 @@ QMultiHash& Bitstream::getMetaObjectSubC return metaObjectSubClasses; } +const QHash& Bitstream::getObjectStreamers() { + static QHash objectStreamers = createObjectStreamers(); + return objectStreamers; +} + +QHash Bitstream::createObjectStreamers() { + QHash objectStreamers; + foreach (const QMetaObject* metaObject, getMetaObjects()) { + QVector properties; + for (int i = 0; i < metaObject->propertyCount(); i++) { + QMetaProperty property = metaObject->property(i); + if (!property.isStored()) { + continue; + } + const TypeStreamer* streamer; + if (property.isEnumType()) { + QMetaEnum metaEnum = property.enumerator(); + streamer = getEnumStreamers().value(ScopeNamePair( + QByteArray::fromRawData(metaEnum.scope(), strlen(metaEnum.scope())), + QByteArray::fromRawData(metaEnum.name(), strlen(metaEnum.name())))); + } else { + streamer = getTypeStreamers().value(property.userType()); + } + if (streamer) { + properties.append(StreamerPropertyPair(streamer->getSelf(), property)); + } + } + ObjectStreamerPointer streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties)); + streamer->_self = streamer; + objectStreamers.insert(metaObject, streamer.data()); + } + return objectStreamers; +} + QHash& Bitstream::getTypeStreamers() { static QHash typeStreamers; return typeStreamers; @@ -1577,69 +1658,17 @@ const TypeStreamer* Bitstream::createInvalidTypeStreamer() { return streamer; } -const QHash& Bitstream::getPropertyReaders() { - static QHash propertyReaders = createPropertyReaders(); - return propertyReaders; +ObjectStreamer::ObjectStreamer(const QMetaObject* metaObject) : + _metaObject(metaObject) { } -QHash Bitstream::createPropertyReaders() { - QHash propertyReaders; - foreach (const QMetaObject* metaObject, getMetaObjects()) { - PropertyReaderVector& readers = propertyReaders[metaObject]; - for (int i = 0; i < metaObject->propertyCount(); i++) { - QMetaProperty property = metaObject->property(i); - if (!property.isStored()) { - continue; - } - const TypeStreamer* streamer; - if (property.isEnumType()) { - QMetaEnum metaEnum = property.enumerator(); - streamer = getEnumStreamers().value(ScopeNamePair( - QByteArray::fromRawData(metaEnum.scope(), strlen(metaEnum.scope())), - QByteArray::fromRawData(metaEnum.name(), strlen(metaEnum.name())))); - } else { - streamer = getTypeStreamers().value(property.userType()); - } - if (streamer) { - readers.append(PropertyReader(streamer->getSelf(), property)); - } - } - } - return propertyReaders; +const QVector& ObjectStreamer::getProperties() const { + static QVector emptyProperties; + return emptyProperties; } -const QHash& Bitstream::getPropertyWriters() { - static QHash propertyWriters = createPropertyWriters(); - return propertyWriters; -} - -QHash Bitstream::createPropertyWriters() { - QHash propertyWriters; - foreach (const QMetaObject* metaObject, getMetaObjects()) { - PropertyWriterVector& writers = propertyWriters[metaObject]; - for (int i = 0; i < metaObject->propertyCount(); i++) { - QMetaProperty property = metaObject->property(i); - if (!property.isStored()) { - continue; - } - const TypeStreamer* streamer; - if (property.isEnumType()) { - QMetaEnum metaEnum = property.enumerator(); - streamer = getEnumStreamers().value(ScopeNamePair( - QByteArray::fromRawData(metaEnum.scope(), strlen(metaEnum.scope())), - QByteArray::fromRawData(metaEnum.name(), strlen(metaEnum.name())))); - } else { - streamer = getTypeStreamers().value(property.userType()); - } - if (streamer) { - writers.append(PropertyWriter(property, streamer)); - } - } - } - return propertyWriters; -} - -MappedObjectStreamer::MappedObjectStreamer(const QVector& properties) : +MappedObjectStreamer::MappedObjectStreamer(const QMetaObject* metaObject, const QVector& properties) : + ObjectStreamer(metaObject), _properties(properties) { } @@ -1647,6 +1676,10 @@ const char* MappedObjectStreamer::getName() const { return _metaObject->className(); } +const QVector& MappedObjectStreamer::getProperties() const { + return _properties; +} + void MappedObjectStreamer::writeMetadata(Bitstream& out, bool full) const { out << _properties.size(); if (_properties.isEmpty()) { @@ -1667,13 +1700,13 @@ void MappedObjectStreamer::writeMetadata(Bitstream& out, bool full) const { } } -void MappedObjectStreamer::write(Bitstream& out, QObject* object) const { +void MappedObjectStreamer::write(Bitstream& out, const QObject* object) const { foreach (const StreamerPropertyPair& property, _properties) { property.first->write(out, property.second.read(object)); } } -void MappedObjectStreamer::writeDelta(Bitstream& out, QObject* object, QObject* reference) const { +void MappedObjectStreamer::writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const { foreach (const StreamerPropertyPair& property, _properties) { property.first->writeDelta(out, property.second.read(object), (reference && reference->metaObject() == _metaObject) ? property.second.read(reference) : QVariant()); @@ -1693,14 +1726,14 @@ QObject* MappedObjectStreamer::read(Bitstream& in, QObject* object) const { return object; } -QObject* MappedObjectStreamer::readDelta(Bitstream& in, const QObject* reference, QObject* object) const { +QObject* MappedObjectStreamer::readRawDelta(Bitstream& in, const QObject* reference, QObject* object) const { if (!object && _metaObject) { object = _metaObject->newInstance(); } foreach (const StreamerPropertyPair& property, _properties) { QVariant value; - property.first->readDelta(in, value, (property.second.isValid() && reference) ? - property.second.read(reference) : QVariant()); + property.first->readDelta(in, value, (property.second.isValid() && reference && + reference->metaObject() == _metaObject) ? property.second.read(reference) : QVariant()); if (property.second.isValid() && object) { property.second.write(object, value); } @@ -1710,11 +1743,10 @@ QObject* MappedObjectStreamer::readDelta(Bitstream& in, const QObject* reference GenericObjectStreamer::GenericObjectStreamer(const QByteArray& name, const QVector& properties, const QByteArray& hash) : + ObjectStreamer(&GenericSharedObject::staticMetaObject), _name(name), _properties(properties), _hash(hash) { - - _metaObject = &GenericSharedObject::staticMetaObject; } const char* GenericObjectStreamer::getName() const { @@ -1744,17 +1776,22 @@ void GenericObjectStreamer::writeMetadata(Bitstream& out, bool full) const { } } -void GenericObjectStreamer::write(Bitstream& out, QObject* object) const { - const QVariantList& values = static_cast(object)->getValues(); +void GenericObjectStreamer::write(Bitstream& out, const QObject* object) const { + const QVariantList& values = static_cast(object)->getValues(); for (int i = 0; i < _properties.size(); i++) { _properties.at(i).first->write(out, values.at(i)); } } -void GenericObjectStreamer::writeDelta(Bitstream& out, QObject* object, QObject* reference) const { +void GenericObjectStreamer::writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const { + const GenericSharedObject* genericObject = static_cast(object); + const GenericSharedObject* genericReference = (reference && + reference->metaObject() == &GenericSharedObject::staticMetaObject) ? + static_cast(reference) : NULL; for (int i = 0; i < _properties.size(); i++) { - _properties.at(i).first->writeDelta(out, static_cast(object)->getValues().at(i), reference ? - static_cast(reference)->getValues().at(i) : QVariant()); + _properties.at(i).first->writeDelta(out, genericObject->getValues().at(i), + (genericReference && genericReference->getStreamer() == genericObject->getStreamer()) ? + genericReference->getValues().at(i) : QVariant()); } } @@ -1770,7 +1807,7 @@ QObject* GenericObjectStreamer::read(Bitstream& in, QObject* object) const { return object; } -QObject* GenericObjectStreamer::readDelta(Bitstream& in, const QObject* reference, QObject* object) const { +QObject* GenericObjectStreamer::readRawDelta(Bitstream& in, const QObject* reference, QObject* object) const { if (!object) { object = new GenericSharedObject(_weakSelf); } @@ -1786,75 +1823,6 @@ QObject* GenericObjectStreamer::readDelta(Bitstream& in, const QObject* referenc return object; } -ObjectReader::ObjectReader(const QByteArray& className, const QMetaObject* metaObject, - const PropertyReaderVector& properties) : - _className(className), - _metaObject(metaObject), - _properties(properties) { -} - -QObject* ObjectReader::read(Bitstream& in, QObject* object) const { - if (!object && _metaObject) { - object = _metaObject->newInstance(); - } - foreach (const PropertyReader& property, _properties) { - property.read(in, object); - } - return object; -} - -QObject* ObjectReader::readDelta(Bitstream& in, const QObject* reference, QObject* object) const { - if (!object && _metaObject) { - object = _metaObject->newInstance(); - } - foreach (const PropertyReader& property, _properties) { - property.readDelta(in, object, reference); - } - return object; -} - -uint qHash(const ObjectReader& objectReader, uint seed) { - return qHash(objectReader.getClassName(), seed); -} - -QDebug& operator<<(QDebug& debug, const ObjectReader& objectReader) { - return debug << objectReader.getClassName(); -} - -PropertyReader::PropertyReader(const TypeStreamerPointer& streamer, const QMetaProperty& property) : - _streamer(streamer), - _property(property) { -} - -void PropertyReader::read(Bitstream& in, QObject* object) const { - QVariant value = _streamer->read(in); - if (_property.isValid() && object) { - _property.write(object, value); - } -} - -void PropertyReader::readDelta(Bitstream& in, QObject* object, const QObject* reference) const { - QVariant value; - _streamer->readDelta(in, value, (_property.isValid() && reference) ? _property.read(reference) : QVariant()); - if (_property.isValid() && object) { - _property.write(object, value); - } -} - -PropertyWriter::PropertyWriter(const QMetaProperty& property, const TypeStreamer* streamer) : - _property(property), - _streamer(streamer) { -} - -void PropertyWriter::write(Bitstream& out, const QObject* object) const { - _streamer->write(out, _property.read(object)); -} - -void PropertyWriter::writeDelta(Bitstream& out, const QObject* object, const QObject* reference) const { - _streamer->writeDelta(out, _property.read(object), reference && object->metaObject() == reference->metaObject() ? - _property.read(reference) : QVariant()); -} - MetaField::MetaField(const QByteArray& name, const TypeStreamer* streamer) : _name(name), _streamer(streamer) { diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index 07e4b94568..10c28b9821 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -39,8 +39,6 @@ class GenericValue; class ObjectReader; class ObjectStreamer; class OwnedAttributeValue; -class PropertyReader; -class PropertyWriter; class TypeStreamer; typedef SharedObjectPointerTemplate AttributePointer; @@ -51,8 +49,6 @@ typedef QSharedPointer ObjectStreamerPointer; typedef QWeakPointer WeakObjectStreamerPointer; typedef QSharedPointer TypeStreamerPointer; typedef QWeakPointer WeakTypeStreamerPointer; -typedef QVector PropertyReaderVector; -typedef QVector PropertyWriterVector; typedef QPair QVariantPair; typedef QList QVariantPairList; @@ -207,7 +203,7 @@ public: class WriteMappings { public: - QHash metaObjectOffsets; + QHash objectStreamerOffsets; QHash typeStreamerOffsets; QHash attributeOffsets; QHash scriptStringOffsets; @@ -216,7 +212,7 @@ public: class ReadMappings { public: - QHash metaObjectValues; + QHash objectStreamerValues; QHash typeStreamerValues; QHash attributeValues; QHash scriptStringValues; @@ -403,7 +399,10 @@ public: Bitstream& operator<<(const QMetaObject* metaObject); Bitstream& operator>>(const QMetaObject*& metaObject); - Bitstream& operator>>(ObjectReader& objectReader); + + Bitstream& operator<<(const ObjectStreamer* streamer); + Bitstream& operator>>(const ObjectStreamer*& streamer); + Bitstream& operator>>(ObjectStreamerPointer& streamer); Bitstream& operator<<(const TypeStreamer* streamer); Bitstream& operator>>(const TypeStreamer*& streamer); @@ -421,11 +420,11 @@ public: Bitstream& operator<<(const SharedObjectPointer& object); Bitstream& operator>>(SharedObjectPointer& object); - Bitstream& operator<(const QMetaObject* metaObject); - Bitstream& operator>(ObjectReader& objectReader); + Bitstream& operator<(const ObjectStreamer* streamer); + Bitstream& operator>(ObjectStreamerPointer& streamer); Bitstream& operator<(const TypeStreamer* streamer); - Bitstream& operator>(TypeStreamerPointer& reader); + Bitstream& operator>(TypeStreamerPointer& streamer); Bitstream& operator<(const AttributePointer& attribute); Bitstream& operator>(AttributePointer& attribute); @@ -446,6 +445,7 @@ private slots: private: + ObjectStreamerPointer readGenericObjectStreamer(const QByteArray& name); TypeStreamerPointer readGenericTypeStreamer(const QByteArray& name, int category); QDataStream& _underlying; @@ -455,7 +455,7 @@ private: MetadataType _metadataType; GenericsMode _genericsMode; - RepeatedValueStreamer _metaObjectStreamer; + RepeatedValueStreamer _objectStreamerStreamer; RepeatedValueStreamer _typeStreamerStreamer; RepeatedValueStreamer _attributeStreamer; RepeatedValueStreamer _scriptStringStreamer; @@ -472,6 +472,9 @@ private: static QMultiHash& getMetaObjectSubClasses(); static QHash& getTypeStreamers(); + static const QHash& getObjectStreamers(); + static QHash createObjectStreamers(); + static const QHash& getEnumStreamers(); static QHash createEnumStreamers(); @@ -480,12 +483,6 @@ private: static const TypeStreamer* getInvalidTypeStreamer(); static const TypeStreamer* createInvalidTypeStreamer(); - - static const QHash& getPropertyReaders(); - static QHash createPropertyReaders(); - - static const QHash& getPropertyWriters(); - static QHash createPropertyWriters(); }; template inline void Bitstream::writeDelta(const T& value, const T& reference) { @@ -769,37 +766,46 @@ template inline Bitstream& Bitstream::operator>>(QHash& return *this; } +typedef QPair StreamerPropertyPair; + /// Contains the information required to stream an object. class ObjectStreamer { public: - virtual const char* getName() const = 0; + ObjectStreamer(const QMetaObject* metaObject); + + const QMetaObject* getMetaObject() const { return _metaObject; } + const ObjectStreamerPointer& getSelf() const { return _self; } + + virtual const char* getName() const = 0; + virtual const QVector& getProperties() const; virtual void writeMetadata(Bitstream& out, bool full) const = 0; - virtual void write(Bitstream& out, QObject* object) const = 0; - virtual void writeDelta(Bitstream& out, QObject* object, QObject* reference) 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; - virtual QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const = 0; + virtual QObject* readRawDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const = 0; protected: + + friend class Bitstream; const QMetaObject* _metaObject; ObjectStreamerPointer _self; }; -typedef QPair StreamerPropertyPair; - /// A streamer that maps to a local class. class MappedObjectStreamer : public ObjectStreamer { public: - MappedObjectStreamer(const QVector& properties); + MappedObjectStreamer(const QMetaObject* metaObject, const QVector& properties); virtual const char* getName() const; + virtual const QVector& getProperties() const; virtual void writeMetadata(Bitstream& out, bool full) const; - virtual void write(Bitstream& out, QObject* object) const; - virtual void writeDelta(Bitstream& out, QObject* object, QObject* reference) 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; - virtual QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const; + virtual QObject* readRawDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const; private: @@ -816,10 +822,10 @@ public: virtual const char* getName() const; virtual void writeMetadata(Bitstream& out, bool full) const; - virtual void write(Bitstream& out, QObject* object) const; - virtual void writeDelta(Bitstream& out, QObject* object, QObject* reference) 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; - virtual QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const; + virtual QObject* readRawDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const; private: @@ -831,69 +837,6 @@ private: QByteArray _hash; }; -/// Contains the information required to read an object from the stream. -class ObjectReader { -public: - - ObjectReader(const QByteArray& className = QByteArray(), const QMetaObject* metaObject = NULL, - const QVector& properties = QVector()); - - const QByteArray& getClassName() const { return _className; } - const QMetaObject* getMetaObject() const { return _metaObject; } - - QObject* read(Bitstream& in, QObject* object = NULL) const; - QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const; - - bool operator==(const ObjectReader& other) const { return _className == other._className; } - bool operator!=(const ObjectReader& other) const { return _className != other._className; } - -private: - - QByteArray _className; - const QMetaObject* _metaObject; - QVector _properties; -}; - -uint qHash(const ObjectReader& objectReader, uint seed = 0); - -QDebug& operator<<(QDebug& debug, const ObjectReader& objectReader); - -/// Contains the information required to read an object property from the stream and apply it. -class PropertyReader { -public: - - PropertyReader(const TypeStreamerPointer& streamer = TypeStreamerPointer(), - const QMetaProperty& property = QMetaProperty()); - - const TypeStreamerPointer& getStreamer() const { return _streamer; } - - void read(Bitstream& in, QObject* object) const; - void readDelta(Bitstream& in, QObject* object, const QObject* reference) const; - -private: - - TypeStreamerPointer _streamer; - QMetaProperty _property; -}; - -/// Contains the information required to obtain an object property and write it to the stream. -class PropertyWriter { -public: - - PropertyWriter(const QMetaProperty& property = QMetaProperty(), const TypeStreamer* streamer = NULL); - - const QMetaProperty& getProperty() const { return _property; } - const TypeStreamer* getStreamer() const { return _streamer; } - - void write(Bitstream& out, const QObject* object) const; - void writeDelta(Bitstream& out, const QObject* object, const QObject* reference) const; - -private: - - QMetaProperty _property; - const TypeStreamer* _streamer; -}; - /// Describes a metatype field. class MetaField { public: