From f9043c3cb954dfbfce26a777a0264f4c54dcfbf0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 31 Dec 2013 11:34:10 -0800 Subject: [PATCH] Working on streaming types. --- libraries/metavoxels/src/Bitstream.cpp | 44 +++++++++++++++----- libraries/metavoxels/src/Bitstream.h | 29 ++++++++++++- libraries/metavoxels/src/MetavoxelMessages.h | 23 ++++++++++ 3 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 libraries/metavoxels/src/MetavoxelMessages.h diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index 70f03cb604..8fdeb1c1fc 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -52,6 +52,7 @@ int Bitstream::registerMetaObject(const char* className, const QMetaObject* meta } int Bitstream::registerTypeStreamer(int type, TypeStreamer* streamer) { + streamer->setType(type); getTypeStreamers().insert(type, streamer); return 0; } @@ -61,6 +62,7 @@ Bitstream::Bitstream(QDataStream& underlying) : _byte(0), _position(0), _metaObjectStreamer(*this), + _typeStreamerStreamer(*this), _attributeStreamer(*this) { } @@ -116,23 +118,27 @@ void Bitstream::reset() { Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() { WriteMappings mappings = { _metaObjectStreamer.getAndResetTransientOffsets(), + _typeStreamerStreamer.getAndResetTransientOffsets(), _attributeStreamer.getAndResetTransientOffsets() }; return mappings; } void Bitstream::persistWriteMappings(const WriteMappings& mappings) { _metaObjectStreamer.persistTransientOffsets(mappings.metaObjectOffsets); + _typeStreamerStreamer.persistTransientOffsets(mappings.typeStreamerOffsets); _attributeStreamer.persistTransientOffsets(mappings.attributeOffsets); } Bitstream::ReadMappings Bitstream::getAndResetReadMappings() { ReadMappings mappings = { _metaObjectStreamer.getAndResetTransientValues(), + _typeStreamerStreamer.getAndResetTransientValues(), _attributeStreamer.getAndResetTransientValues() }; return mappings; } void Bitstream::persistReadMappings(const ReadMappings& mappings) { _metaObjectStreamer.persistTransientValues(mappings.metaObjectValues); + _typeStreamerStreamer.persistTransientValues(mappings.typeStreamerValues); _attributeStreamer.persistTransientValues(mappings.attributeValues); } @@ -189,25 +195,26 @@ Bitstream& Bitstream::operator>>(QString& string) { } Bitstream& Bitstream::operator<<(const QVariant& value) { - *this << value.userType(); - TypeStreamer* streamer = getTypeStreamers().value(value.userType()); + const TypeStreamer* streamer = getTypeStreamers().value(value.userType()); if (streamer) { + _typeStreamerStreamer << streamer; streamer->write(*this, value); + } else { + qWarning() << "Non-streamable type: " << value.typeName() << "\n"; } return *this; } Bitstream& Bitstream::operator>>(QVariant& value) { - int type; - *this >> type; - TypeStreamer* streamer = getTypeStreamers().value(type); + const TypeStreamer* streamer; + _typeStreamerStreamer >> streamer; if (streamer) { value = streamer->read(*this); } return *this; } -Bitstream& Bitstream::operator<<(QObject* object) { +Bitstream& Bitstream::operator<<(const QObject* object) { if (!object) { _metaObjectStreamer << NULL; return *this; @@ -219,7 +226,7 @@ Bitstream& Bitstream::operator<<(QObject* object) { if (!property.isStored(object)) { continue; } - TypeStreamer* streamer = getTypeStreamers().value(property.userType()); + const TypeStreamer* streamer = getTypeStreamers().value(property.userType()); if (streamer) { streamer->write(*this, property.read(object)); } @@ -240,7 +247,7 @@ Bitstream& Bitstream::operator>>(QObject*& object) { if (!property.isStored(object)) { continue; } - TypeStreamer* streamer = getTypeStreamers().value(property.userType()); + const TypeStreamer* streamer = getTypeStreamers().value(property.userType()); if (streamer) { property.write(object, streamer->read(*this)); } @@ -262,7 +269,22 @@ Bitstream& Bitstream::operator>>(const QMetaObject*& metaObject) { } metaObject = getMetaObjects().value(className); if (!metaObject) { - qDebug() << "Unknown class name: " << className << "\n"; + qWarning() << "Unknown class name: " << className << "\n"; + } + return *this; +} + +Bitstream& Bitstream::operator<<(const TypeStreamer* streamer) { + const char* typeName = QMetaType::typeName(streamer->getType()); + return *this << QByteArray::fromRawData(typeName, strlen(typeName)); +} + +Bitstream& Bitstream::operator>>(const TypeStreamer*& streamer) { + QByteArray typeName; + *this >> typeName; + streamer = getTypeStreamers().value(QMetaType::type(typeName.constData())); + if (!streamer) { + qWarning() << "Unknown type name: " << typeName << "\n"; } return *this; } @@ -283,8 +305,8 @@ QHash& Bitstream::getMetaObjects() { return metaObjects; } -QHash& Bitstream::getTypeStreamers() { - static QHash typeStreamers; +QHash& Bitstream::getTypeStreamers() { + static QHash typeStreamers; return typeStreamers; } diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index 48c5e297ce..d86bad67cc 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -154,12 +154,14 @@ public: class WriteMappings { public: QHash metaObjectOffsets; + QHash typeStreamerOffsets; QHash attributeOffsets; }; class ReadMappings { public: QHash metaObjectValues; + QHash typeStreamerValues; QHash attributeValues; }; @@ -220,12 +222,15 @@ public: Bitstream& operator<<(const QVariant& value); Bitstream& operator>>(QVariant& value); - Bitstream& operator<<(QObject* object); + Bitstream& operator<<(const QObject* object); Bitstream& operator>>(QObject*& object); Bitstream& operator<<(const QMetaObject* metaObject); Bitstream& operator>>(const QMetaObject*& metaObject); + Bitstream& operator<<(const TypeStreamer* streamer); + Bitstream& operator>>(const TypeStreamer*& streamer); + Bitstream& operator<<(const AttributePointer& attribute); Bitstream& operator>>(AttributePointer& attribute); @@ -236,10 +241,11 @@ private: int _position; RepeatedValueStreamer _metaObjectStreamer; + RepeatedValueStreamer _typeStreamerStreamer; RepeatedValueStreamer _attributeStreamer; static QHash& getMetaObjects(); - static QHash& getTypeStreamers(); + static QHash& getTypeStreamers(); }; /// Macro for registering streamable meta-objects. @@ -249,8 +255,15 @@ private: class TypeStreamer { public: + void setType(int type) { _type = type; } + int getType() const { return _type; } + virtual void write(Bitstream& out, const QVariant& value) const = 0; virtual QVariant read(Bitstream& in) const = 0; + +private: + + int _type; }; /// A streamer that works with Bitstream's operators. @@ -265,4 +278,16 @@ public: #define REGISTER_SIMPLE_TYPE_STREAMER(x) static int x##Streamer = \ Bitstream::registerTypeStreamer(QMetaType::type(#x), new SimpleTypeStreamer()); +/// Declares the metatype and the streaming operators. +#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \ + Bitstream& operator<<(Bitstream& out, const X& obj); \ + Bitstream& operator>>(Bitstream& in, X& obj); + +/// Registers a streamable type and its streamer. +template int registerStreamableMetaType() { + int type = qRegisterMetaType(); + Bitstream::registerTypeStreamer(type, new SimpleTypeStreamer()); + return type; +} + #endif /* defined(__interface__Bitstream__) */ diff --git a/libraries/metavoxels/src/MetavoxelMessages.h b/libraries/metavoxels/src/MetavoxelMessages.h new file mode 100644 index 0000000000..389d8b68bf --- /dev/null +++ b/libraries/metavoxels/src/MetavoxelMessages.h @@ -0,0 +1,23 @@ +// +// MetavoxelMessages.h +// metavoxels +// +// Created by Andrzej Kapolka on 12/31/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __interface__MetavoxelMessages__ +#define __interface__MetavoxelMessages__ + +#include "Bitstream.h" + +/// A message containing the position of a client. +class ClientPositionMessage { +public: + + int test; +}; + +DECLARE_STREAMABLE_METATYPE(ClientPositionMessage) + +#endif /* defined(__interface__MetavoxelMessages__) */