From d569802fbcf54640a319090074d82b91c8923762 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 17 Mar 2014 17:21:46 -0700 Subject: [PATCH] More metadata fixes. --- libraries/metavoxels/src/Bitstream.cpp | 29 +++++++++--------- libraries/metavoxels/src/Bitstream.h | 2 +- tests/metavoxels/src/MetavoxelTests.cpp | 39 ++++++++++++++++++++----- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index c2688e7607..68f1e19dc4 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -31,6 +31,7 @@ REGISTER_SIMPLE_TYPE_STREAMER(QString) REGISTER_SIMPLE_TYPE_STREAMER(QUrl) REGISTER_SIMPLE_TYPE_STREAMER(QVariantList) REGISTER_SIMPLE_TYPE_STREAMER(QVariantHash) +REGISTER_SIMPLE_TYPE_STREAMER(SharedObjectPointer) // some types don't quite work with our macro static int vec3Streamer = Bitstream::registerTypeStreamer(qMetaTypeId(), new SimpleTypeStreamer()); @@ -630,29 +631,31 @@ Bitstream& Bitstream::operator>(TypeReader& reader) { // for hash metadata, check the names/types of the fields as well as the name hash against our own class if (_metadataType == HASH_METADATA) { QCryptographicHash hash(QCryptographicHash::Md5); + bool matches = true; if (streamer) { const QVector& localFields = streamer->getMetaFields(); if (fieldCount != localFields.size()) { - reader = TypeReader(typeName, streamer, false, fields); - return *this; - } - if (fieldCount == 0) { - reader = TypeReader(typeName, streamer); - return *this; - } - for (int i = 0; i < fieldCount; i++) { - const MetaField& localField = localFields.at(i); - if (!fields.at(i).getReader().matchesExactly(localField.getStreamer())) { - reader = TypeReader(typeName, streamer, false, fields); + matches = false; + + } else { + if (fieldCount == 0) { + reader = TypeReader(typeName, streamer); return *this; } - hash.addData(localField.getName().constData(), localField.getName().size() + 1); + for (int i = 0; i < fieldCount; i++) { + const MetaField& localField = localFields.at(i); + if (!fields.at(i).getReader().matchesExactly(localField.getStreamer())) { + matches = false; + break; + } + hash.addData(localField.getName().constData(), localField.getName().size() + 1); + } } } QByteArray localHashResult = hash.result(); QByteArray remoteHashResult(localHashResult.size(), 0); read(remoteHashResult.data(), remoteHashResult.size() * BITS_IN_BYTE); - if (streamer && localHashResult == remoteHashResult) { + if (streamer && matches && localHashResult == remoteHashResult) { // since everything is the same, we can use the default streamer reader = TypeReader(typeName, streamer); return *this; diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index b51bee3a25..2ed265b6ed 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -589,7 +589,7 @@ public: /// Macro for registering simple type streamers. #define REGISTER_SIMPLE_TYPE_STREAMER(x) static int x##Streamer = \ - Bitstream::registerTypeStreamer(QMetaType::type(#x), new SimpleTypeStreamer()); + Bitstream::registerTypeStreamer(qMetaTypeId(), new SimpleTypeStreamer()); /// Declares the metatype and the streaming operators. The last lines /// ensure that the generated file will be included in the link phase. diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index a178215fbc..a1b79319b5 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -48,6 +48,15 @@ static QByteArray createRandomBytes() { return createRandomBytes(MIN_BYTES, MAX_BYTES); } +static TestMessageC createRandomMessageC() { + TestMessageC message; + message.foo = randomBoolean(); + message.bar = rand(); + message.baz = randFloat(); + message.bong.foo = createRandomBytes(); + return message; +} + static bool testSerialization(Bitstream::MetadataType metadataType) { QByteArray array; QDataStream outStream(&array, QIODevice::WriteOnly); @@ -56,6 +65,8 @@ static bool testSerialization(Bitstream::MetadataType metadataType) { out << testObjectWrittenA; SharedObjectPointer testObjectWrittenB = new TestSharedObjectB(randFloat(), createRandomBytes()); out << testObjectWrittenB; + TestMessageC messageWritten = createRandomMessageC(); + out << QVariant::fromValue(messageWritten); QByteArray endWritten = "end"; out << endWritten; out.flush(); @@ -64,8 +75,9 @@ static bool testSerialization(Bitstream::MetadataType metadataType) { Bitstream in(inStream, metadataType); in.addMetaObjectSubstitution("TestSharedObjectA", &TestSharedObjectB::staticMetaObject); in.addMetaObjectSubstitution("TestSharedObjectB", &TestSharedObjectA::staticMetaObject); - SharedObjectPointer testObjectReadA, testObjectReadB; - in >> testObjectReadA >> testObjectReadB; + in.addTypeSubstitution("TestMessageC", TestMessageA::Type); + SharedObjectPointer testObjectReadA; + in >> testObjectReadA; if (!testObjectReadA || testObjectReadA->metaObject() != &TestSharedObjectB::staticMetaObject) { qDebug() << "Wrong class for A" << testObjectReadA << metadataType; @@ -76,8 +88,11 @@ static bool testSerialization(Bitstream::MetadataType metadataType) { QDebug debug = qDebug() << "Failed to transfer shared field from A to B"; testObjectWrittenA->dump(debug); testObjectReadA->dump(debug); + return true; } + SharedObjectPointer testObjectReadB; + in >> testObjectReadB; if (!testObjectReadB || testObjectReadB->metaObject() != &TestSharedObjectA::staticMetaObject) { qDebug() << "Wrong class for B" << testObjectReadB << metadataType; return true; @@ -87,6 +102,19 @@ static bool testSerialization(Bitstream::MetadataType metadataType) { QDebug debug = qDebug() << "Failed to transfer shared field from B to A"; testObjectWrittenB->dump(debug); testObjectReadB->dump(debug); + return true; + } + + QVariant messageRead; + in >> messageRead; + if (!messageRead.isValid() || messageRead.userType() != TestMessageA::Type) { + qDebug() << "Wrong type for message" << messageRead; + return true; + } + if (metadataType == Bitstream::FULL_METADATA && messageWritten.foo != messageRead.value().foo) { + QDebug debug = qDebug() << "Failed to transfer shared field between messages" << + messageWritten.foo << messageRead.value().foo; + return true; } QByteArray endRead; @@ -192,12 +220,7 @@ static QVariant createRandomMessage() { } case 2: default: { - TestMessageC message; - message.foo = randomBoolean(); - message.bar = rand(); - message.baz = randFloat(); - message.bong.foo = createRandomBytes(); - return QVariant::fromValue(message); + return QVariant::fromValue(createRandomMessageC()); } } }