From 2fec0a9db603e09e7314a4221e761141a57b127d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 6 Jun 2014 15:50:28 -0700 Subject: [PATCH] Fixes for Windows. --- libraries/metavoxels/src/Bitstream.cpp | 87 ++++++++++++++++---------- libraries/metavoxels/src/Bitstream.h | 27 ++++---- 2 files changed, 71 insertions(+), 43 deletions(-) diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index bc187d9f3d..6f4af8ed5f 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -79,10 +79,6 @@ IDStreamer& IDStreamer::operator>>(int& value) { return *this; } -static QByteArray getEnumName(const QMetaEnum& metaEnum) { - return QByteArray(metaEnum.scope()) + "::" + metaEnum.name(); -} - int Bitstream::registerMetaObject(const char* className, const QMetaObject* metaObject) { getMetaObjects().insert(className, metaObject); @@ -90,16 +86,6 @@ int Bitstream::registerMetaObject(const char* className, const QMetaObject* meta for (const QMetaObject* superClass = metaObject; superClass; superClass = superClass->superClass()) { getMetaObjectSubClasses().insert(superClass, metaObject); } - - // register the streamers for all enumerators - for (int i = 0; i < metaObject->enumeratorCount(); i++) { - QMetaEnum metaEnum = metaObject->enumerator(i); - const TypeStreamer*& streamer = getEnumStreamers()[QPair(metaEnum.scope(), metaEnum.name())]; - if (!streamer) { - getEnumStreamersByName().insert(getEnumName(metaEnum), streamer = new EnumTypeStreamer(metaEnum)); - } - } - return 0; } @@ -1030,12 +1016,34 @@ QHash& Bitstream::getTypeStreamers() { } QHash, const TypeStreamer*>& Bitstream::getEnumStreamers() { - static QHash, const TypeStreamer*> enumStreamers; + static QHash, const TypeStreamer*> enumStreamers = createEnumStreamers(); + return enumStreamers; +} + +QHash, const TypeStreamer*> Bitstream::createEnumStreamers() { + QHash, const TypeStreamer*> enumStreamers; + foreach (const QMetaObject* metaObject, getMetaObjects()) { + for (int i = 0; i < metaObject->enumeratorCount(); i++) { + QMetaEnum metaEnum = metaObject->enumerator(i); + const TypeStreamer*& streamer = enumStreamers[QPair(metaEnum.scope(), metaEnum.name())]; + if (!streamer) { + streamer = new EnumTypeStreamer(metaEnum); + } + } + } return enumStreamers; } QHash& Bitstream::getEnumStreamersByName() { - static QHash enumStreamersByName; + static QHash enumStreamersByName = createEnumStreamersByName(); + return enumStreamersByName; +} + +QHash Bitstream::createEnumStreamersByName() { + QHash enumStreamersByName; + foreach (const TypeStreamer* streamer, getEnumStreamers()) { + enumStreamersByName.insert(streamer->getName(), streamer); + } return enumStreamersByName; } @@ -1462,17 +1470,21 @@ QDebug& operator<<(QDebug& debug, const QMetaObject* metaObject) { return debug << (metaObject ? metaObject->className() : "null"); } +EnumTypeStreamer::EnumTypeStreamer(const QMetaObject* metaObject, const char* name) : + _metaObject(metaObject), + _enumName(name), + _name(QByteArray(metaObject->className()) + "::" + name), + _bits(-1) { + + setType(QMetaType::Int); +} + EnumTypeStreamer::EnumTypeStreamer(const QMetaEnum& metaEnum) : + _name(QByteArray(metaEnum.scope()) + "::" + metaEnum.name()), _metaEnum(metaEnum), - _name(getEnumName(metaEnum)) { - - setType(QMetaType::Int); - - int highestValue = 0; - for (int j = 0; j < metaEnum.keyCount(); j++) { - highestValue = qMax(highestValue, metaEnum.value(j)); - } - _bits = getBitsForHighestValue(highestValue); + _bits(-1) { + + setType(QMetaType::Int); } const char* EnumTypeStreamer::getName() const { @@ -1484,10 +1496,21 @@ TypeReader::Type EnumTypeStreamer::getReaderType() const { } int EnumTypeStreamer::getBits() const { + if (_bits == -1) { + int highestValue = 0; + QMetaEnum metaEnum = getMetaEnum(); + for (int j = 0; j < metaEnum.keyCount(); j++) { + highestValue = qMax(highestValue, metaEnum.value(j)); + } + const_cast(this)->_bits = getBitsForHighestValue(highestValue); + } return _bits; } QMetaEnum EnumTypeStreamer::getMetaEnum() const { + if (!_metaEnum.isValid()) { + const_cast(this)->_metaEnum = _metaObject->enumerator(_metaObject->indexOfEnumerator(_enumName)); + } return _metaEnum; } @@ -1497,12 +1520,12 @@ bool EnumTypeStreamer::equal(const QVariant& first, const QVariant& second) cons void EnumTypeStreamer::write(Bitstream& out, const QVariant& value) const { int intValue = value.toInt(); - out.write(&intValue, _bits); + out.write(&intValue, getBits()); } QVariant EnumTypeStreamer::read(Bitstream& in) const { int intValue = 0; - in.read(&intValue, _bits); + in.read(&intValue, getBits()); return intValue; } @@ -1512,7 +1535,7 @@ void EnumTypeStreamer::writeDelta(Bitstream& out, const QVariant& value, const Q out << false; } else { out << true; - out.write(&intValue, _bits); + out.write(&intValue, getBits()); } } @@ -1521,7 +1544,7 @@ void EnumTypeStreamer::readDelta(Bitstream& in, QVariant& value, const QVariant& in >> changed; if (changed) { int intValue = 0; - in.read(&intValue, _bits); + in.read(&intValue, getBits()); value = intValue; } else { value = reference; @@ -1530,17 +1553,17 @@ void EnumTypeStreamer::readDelta(Bitstream& in, QVariant& value, const QVariant& void EnumTypeStreamer::writeRawDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const { int intValue = value.toInt(); - out.write(&intValue, _bits); + out.write(&intValue, getBits()); } void EnumTypeStreamer::readRawDelta(Bitstream& in, QVariant& value, const QVariant& reference) const { int intValue = 0; - in.read(&intValue, _bits); + in.read(&intValue, getBits()); value = intValue; } void EnumTypeStreamer::setEnumValue(QVariant& object, int value, const QHash& mappings) const { - if (_metaEnum.isFlag()) { + if (getMetaEnum().isFlag()) { int combined = 0; for (QHash::const_iterator it = mappings.constBegin(); it != mappings.constEnd(); it++) { if (value & it.key()) { diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index caf0adf7fc..b0c33754f9 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -427,7 +427,9 @@ private: static QMultiHash& getMetaObjectSubClasses(); static QHash& getTypeStreamers(); static QHash, const TypeStreamer*>& getEnumStreamers(); + static QHash, const TypeStreamer*> createEnumStreamers(); static QHash& getEnumStreamersByName(); + static QHash createEnumStreamersByName(); static QVector getPropertyReaders(const QMetaObject* metaObject); }; @@ -938,8 +940,9 @@ public: class EnumTypeStreamer : public TypeStreamer { public: + EnumTypeStreamer(const QMetaObject* metaObject, const char* name); EnumTypeStreamer(const QMetaEnum& metaEnum); - + virtual const char* getName() const; virtual TypeReader::Type getReaderType() const; virtual int getBits() const; @@ -955,8 +958,10 @@ public: private: - QMetaEnum _metaEnum; + const QMetaObject* _metaObject; + const char* _enumName; QByteArray _name; + QMetaEnum _metaEnum; int _bits; }; @@ -1084,14 +1089,15 @@ public: template<> inline void Bitstream::readRawDelta(S::N& value, const S::N& reference) { *this >> value; } #define IMPLEMENT_ENUM_METATYPE(S, N) \ - static int S##N##Bits = registerEnumMetaType(S::staticMetaObject.enumerator( \ - S::staticMetaObject.indexOfEnumerator(#N))); \ + static int S##N##MetaTypeId = registerEnumMetaType(&S::staticMetaObject, #N); \ Bitstream& operator<<(Bitstream& out, const S::N& obj) { \ - return out.write(&obj, S##N##Bits); \ + static int bits = Bitstream::getTypeStreamer(qMetaTypeId())->getBits(); \ + return out.write(&obj, bits); \ } \ Bitstream& operator>>(Bitstream& in, S::N& obj) { \ + static int bits = Bitstream::getTypeStreamer(qMetaTypeId())->getBits(); \ obj = (S::N)0; \ - return in.read(&obj, S##N##Bits); \ + return in.read(&obj, bits); \ } /// Registers a simple type and its streamer. @@ -1103,12 +1109,11 @@ template int registerSimpleMetaType() { } /// Registers an enum type and its streamer. -/// \return the number of bits required to stream the enum -template int registerEnumMetaType(const QMetaEnum& metaEnum) { +/// \return the metatype id +template int registerEnumMetaType(const QMetaObject* metaObject, const char* name) { int type = qRegisterMetaType(); - EnumTypeStreamer* streamer = new EnumTypeStreamer(metaEnum); - Bitstream::registerTypeStreamer(type, streamer); - return streamer->getBits(); + Bitstream::registerTypeStreamer(type, new EnumTypeStreamer(metaObject, name)); + return type; } /// Registers a streamable type and its streamer.