From c44dba78cb3ad4458fe3abb75695967afb763c27 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 5 Jun 2014 15:32:55 -0700 Subject: [PATCH] Provide a reasonably painless way to stream enums that aren't object properties. --- libraries/metavoxels/src/Bitstream.h | 34 ++++++++++++++++++++++--- tests/metavoxels/src/MetavoxelTests.cpp | 7 +++-- tests/metavoxels/src/MetavoxelTests.h | 3 +++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index 146713910f..9945284775 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -1037,12 +1037,12 @@ public: }; /// Macro for registering simple type streamers. -#define REGISTER_SIMPLE_TYPE_STREAMER(x) static int x##Streamer = \ - Bitstream::registerTypeStreamer(qMetaTypeId(), new SimpleTypeStreamer()); +#define REGISTER_SIMPLE_TYPE_STREAMER(X) static int X##Streamer = \ + Bitstream::registerTypeStreamer(qMetaTypeId(), new SimpleTypeStreamer()); /// Macro for registering collection type streamers. -#define REGISTER_COLLECTION_TYPE_STREAMER(x) static int x##Streamer = \ - Bitstream::registerTypeStreamer(qMetaTypeId(), new CollectionTypeStreamer()); +#define REGISTER_COLLECTION_TYPE_STREAMER(X) static int x##Streamer = \ + Bitstream::registerTypeStreamer(qMetaTypeId(), new CollectionTypeStreamer()); /// Declares the metatype and the streaming operators. The last lines /// ensure that the generated file will be included in the link phase. @@ -1077,6 +1077,25 @@ public: _Pragma(STRINGIFY(unused(_TypePtr##X))) #endif +#define DECLARE_ENUM_METATYPE(S, N) Q_DECLARE_METATYPE(S::N) \ + Bitstream& operator<<(Bitstream& out, const S::N& obj); \ + Bitstream& operator>>(Bitstream& in, S::N& obj); \ + template<> inline void Bitstream::writeRawDelta(const S::N& value, const S::N& reference) { *this << value; } \ + template<> inline void Bitstream::readRawDelta(S::N& value, const S::N& reference) { *this >> value; } + +#define IMPLEMENT_ENUM_METATYPE(S, N) \ + static int S##N##MetaTypeId = registerEnumMetaType(S::staticMetaObject.enumerator( \ + S::staticMetaObject.indexOfEnumerator(#N))); \ + Bitstream& operator<<(Bitstream& out, const S::N& obj) { \ + static int bits = static_cast(Bitstream::getTypeStreamer(qMetaTypeId()))->getBits(); \ + return out.write(&obj, bits); \ + } \ + Bitstream& operator>>(Bitstream& in, S::N& obj) { \ + static int bits = static_cast(Bitstream::getTypeStreamer(qMetaTypeId()))->getBits(); \ + obj = (S::N)0; \ + return in.read(&obj, bits); \ + } + /// Registers a simple type and its streamer. template int registerSimpleMetaType() { int type = qRegisterMetaType(); @@ -1084,6 +1103,13 @@ template int registerSimpleMetaType() { return type; } +/// Registers an enum type and its streamer. +template int registerEnumMetaType(const QMetaEnum& metaEnum) { + int type = qRegisterMetaType(); + Bitstream::registerTypeStreamer(type, new EnumTypeStreamer(metaEnum)); + return type; +} + /// Registers a streamable type and its streamer. template int registerStreamableMetaType() { int type = qRegisterMetaType(); diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index 603f63b587..cb1b5c7900 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -20,6 +20,8 @@ REGISTER_META_OBJECT(TestSharedObjectA) REGISTER_META_OBJECT(TestSharedObjectB) +IMPLEMENT_ENUM_METATYPE(TestSharedObjectA, TestEnum) + MetavoxelTests::MetavoxelTests(int& argc, char** argv) : QCoreApplication(argc, argv) { } @@ -80,6 +82,7 @@ static TestMessageC createRandomMessageC() { message.bar = rand(); message.baz = randFloat(); message.bong.foo = createRandomBytes(); + message.bong.baz = getRandomTestEnum(); return message; } @@ -252,7 +255,7 @@ static QVariant createRandomMessage() { return QVariant::fromValue(message); } case 1: { - TestMessageB message = { createRandomBytes(), createRandomSharedObject() }; + TestMessageB message = { createRandomBytes(), createRandomSharedObject(), getRandomTestEnum() }; return QVariant::fromValue(message); } case 2: @@ -273,7 +276,7 @@ static bool messagesEqual(const QVariant& firstMessage, const QVariant& secondMe } else if (type == TestMessageB::Type) { TestMessageB first = firstMessage.value(); TestMessageB second = secondMessage.value(); - return first.foo == second.foo && equals(first.bar, second.bar); + return first.foo == second.foo && equals(first.bar, second.bar) && first.baz == second.baz; } else if (type == TestMessageC::Type) { return firstMessage.value() == secondMessage.value(); diff --git a/tests/metavoxels/src/MetavoxelTests.h b/tests/metavoxels/src/MetavoxelTests.h index 5e020b1e60..ffd1311f00 100644 --- a/tests/metavoxels/src/MetavoxelTests.h +++ b/tests/metavoxels/src/MetavoxelTests.h @@ -106,6 +106,8 @@ private: TestFlags _bong; }; +DECLARE_ENUM_METATYPE(TestSharedObjectA, TestEnum) + /// Another simple shared object. class TestSharedObjectB : public SharedObject { Q_OBJECT @@ -169,6 +171,7 @@ public: STREAM QByteArray foo; STREAM SharedObjectPointer bar; + STREAM TestSharedObjectA::TestEnum baz; }; DECLARE_STREAMABLE_METATYPE(TestMessageB)