Working on streaming types.

This commit is contained in:
Andrzej Kapolka 2013-12-31 11:34:10 -08:00
parent ecd9c9f41d
commit f9043c3cb9
3 changed files with 83 additions and 13 deletions

View file

@ -52,6 +52,7 @@ int Bitstream::registerMetaObject(const char* className, const QMetaObject* meta
} }
int Bitstream::registerTypeStreamer(int type, TypeStreamer* streamer) { int Bitstream::registerTypeStreamer(int type, TypeStreamer* streamer) {
streamer->setType(type);
getTypeStreamers().insert(type, streamer); getTypeStreamers().insert(type, streamer);
return 0; return 0;
} }
@ -61,6 +62,7 @@ Bitstream::Bitstream(QDataStream& underlying) :
_byte(0), _byte(0),
_position(0), _position(0),
_metaObjectStreamer(*this), _metaObjectStreamer(*this),
_typeStreamerStreamer(*this),
_attributeStreamer(*this) { _attributeStreamer(*this) {
} }
@ -116,23 +118,27 @@ void Bitstream::reset() {
Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() { Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() {
WriteMappings mappings = { _metaObjectStreamer.getAndResetTransientOffsets(), WriteMappings mappings = { _metaObjectStreamer.getAndResetTransientOffsets(),
_typeStreamerStreamer.getAndResetTransientOffsets(),
_attributeStreamer.getAndResetTransientOffsets() }; _attributeStreamer.getAndResetTransientOffsets() };
return mappings; return mappings;
} }
void Bitstream::persistWriteMappings(const WriteMappings& mappings) { void Bitstream::persistWriteMappings(const WriteMappings& mappings) {
_metaObjectStreamer.persistTransientOffsets(mappings.metaObjectOffsets); _metaObjectStreamer.persistTransientOffsets(mappings.metaObjectOffsets);
_typeStreamerStreamer.persistTransientOffsets(mappings.typeStreamerOffsets);
_attributeStreamer.persistTransientOffsets(mappings.attributeOffsets); _attributeStreamer.persistTransientOffsets(mappings.attributeOffsets);
} }
Bitstream::ReadMappings Bitstream::getAndResetReadMappings() { Bitstream::ReadMappings Bitstream::getAndResetReadMappings() {
ReadMappings mappings = { _metaObjectStreamer.getAndResetTransientValues(), ReadMappings mappings = { _metaObjectStreamer.getAndResetTransientValues(),
_typeStreamerStreamer.getAndResetTransientValues(),
_attributeStreamer.getAndResetTransientValues() }; _attributeStreamer.getAndResetTransientValues() };
return mappings; return mappings;
} }
void Bitstream::persistReadMappings(const ReadMappings& mappings) { void Bitstream::persistReadMappings(const ReadMappings& mappings) {
_metaObjectStreamer.persistTransientValues(mappings.metaObjectValues); _metaObjectStreamer.persistTransientValues(mappings.metaObjectValues);
_typeStreamerStreamer.persistTransientValues(mappings.typeStreamerValues);
_attributeStreamer.persistTransientValues(mappings.attributeValues); _attributeStreamer.persistTransientValues(mappings.attributeValues);
} }
@ -189,25 +195,26 @@ Bitstream& Bitstream::operator>>(QString& string) {
} }
Bitstream& Bitstream::operator<<(const QVariant& value) { Bitstream& Bitstream::operator<<(const QVariant& value) {
*this << value.userType(); const TypeStreamer* streamer = getTypeStreamers().value(value.userType());
TypeStreamer* streamer = getTypeStreamers().value(value.userType());
if (streamer) { if (streamer) {
_typeStreamerStreamer << streamer;
streamer->write(*this, value); streamer->write(*this, value);
} else {
qWarning() << "Non-streamable type: " << value.typeName() << "\n";
} }
return *this; return *this;
} }
Bitstream& Bitstream::operator>>(QVariant& value) { Bitstream& Bitstream::operator>>(QVariant& value) {
int type; const TypeStreamer* streamer;
*this >> type; _typeStreamerStreamer >> streamer;
TypeStreamer* streamer = getTypeStreamers().value(type);
if (streamer) { if (streamer) {
value = streamer->read(*this); value = streamer->read(*this);
} }
return *this; return *this;
} }
Bitstream& Bitstream::operator<<(QObject* object) { Bitstream& Bitstream::operator<<(const QObject* object) {
if (!object) { if (!object) {
_metaObjectStreamer << NULL; _metaObjectStreamer << NULL;
return *this; return *this;
@ -219,7 +226,7 @@ Bitstream& Bitstream::operator<<(QObject* object) {
if (!property.isStored(object)) { if (!property.isStored(object)) {
continue; continue;
} }
TypeStreamer* streamer = getTypeStreamers().value(property.userType()); const TypeStreamer* streamer = getTypeStreamers().value(property.userType());
if (streamer) { if (streamer) {
streamer->write(*this, property.read(object)); streamer->write(*this, property.read(object));
} }
@ -240,7 +247,7 @@ Bitstream& Bitstream::operator>>(QObject*& object) {
if (!property.isStored(object)) { if (!property.isStored(object)) {
continue; continue;
} }
TypeStreamer* streamer = getTypeStreamers().value(property.userType()); const TypeStreamer* streamer = getTypeStreamers().value(property.userType());
if (streamer) { if (streamer) {
property.write(object, streamer->read(*this)); property.write(object, streamer->read(*this));
} }
@ -262,7 +269,22 @@ Bitstream& Bitstream::operator>>(const QMetaObject*& metaObject) {
} }
metaObject = getMetaObjects().value(className); metaObject = getMetaObjects().value(className);
if (!metaObject) { 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; return *this;
} }
@ -283,8 +305,8 @@ QHash<QByteArray, const QMetaObject*>& Bitstream::getMetaObjects() {
return metaObjects; return metaObjects;
} }
QHash<int, TypeStreamer*>& Bitstream::getTypeStreamers() { QHash<int, const TypeStreamer*>& Bitstream::getTypeStreamers() {
static QHash<int, TypeStreamer*> typeStreamers; static QHash<int, const TypeStreamer*> typeStreamers;
return typeStreamers; return typeStreamers;
} }

View file

@ -154,12 +154,14 @@ public:
class WriteMappings { class WriteMappings {
public: public:
QHash<const QMetaObject*, int> metaObjectOffsets; QHash<const QMetaObject*, int> metaObjectOffsets;
QHash<const TypeStreamer*, int> typeStreamerOffsets;
QHash<AttributePointer, int> attributeOffsets; QHash<AttributePointer, int> attributeOffsets;
}; };
class ReadMappings { class ReadMappings {
public: public:
QHash<int, const QMetaObject*> metaObjectValues; QHash<int, const QMetaObject*> metaObjectValues;
QHash<int, const TypeStreamer*> typeStreamerValues;
QHash<int, AttributePointer> attributeValues; QHash<int, AttributePointer> attributeValues;
}; };
@ -220,12 +222,15 @@ public:
Bitstream& operator<<(const QVariant& value); Bitstream& operator<<(const QVariant& value);
Bitstream& operator>>(QVariant& value); Bitstream& operator>>(QVariant& value);
Bitstream& operator<<(QObject* object); Bitstream& operator<<(const QObject* object);
Bitstream& operator>>(QObject*& object); Bitstream& operator>>(QObject*& object);
Bitstream& operator<<(const QMetaObject* metaObject); Bitstream& operator<<(const QMetaObject* metaObject);
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<<(const AttributePointer& attribute);
Bitstream& operator>>(AttributePointer& attribute); Bitstream& operator>>(AttributePointer& attribute);
@ -236,10 +241,11 @@ private:
int _position; int _position;
RepeatedValueStreamer<const QMetaObject*> _metaObjectStreamer; RepeatedValueStreamer<const QMetaObject*> _metaObjectStreamer;
RepeatedValueStreamer<const TypeStreamer*> _typeStreamerStreamer;
RepeatedValueStreamer<AttributePointer> _attributeStreamer; RepeatedValueStreamer<AttributePointer> _attributeStreamer;
static QHash<QByteArray, const QMetaObject*>& getMetaObjects(); static QHash<QByteArray, const QMetaObject*>& getMetaObjects();
static QHash<int, TypeStreamer*>& getTypeStreamers(); static QHash<int, const TypeStreamer*>& getTypeStreamers();
}; };
/// Macro for registering streamable meta-objects. /// Macro for registering streamable meta-objects.
@ -249,8 +255,15 @@ private:
class TypeStreamer { class TypeStreamer {
public: public:
void setType(int type) { _type = type; }
int getType() const { return _type; }
virtual void write(Bitstream& out, const QVariant& value) const = 0; virtual void write(Bitstream& out, const QVariant& value) const = 0;
virtual QVariant read(Bitstream& in) const = 0; virtual QVariant read(Bitstream& in) const = 0;
private:
int _type;
}; };
/// A streamer that works with Bitstream's operators. /// A streamer that works with Bitstream's operators.
@ -265,4 +278,16 @@ public:
#define REGISTER_SIMPLE_TYPE_STREAMER(x) static int x##Streamer = \ #define REGISTER_SIMPLE_TYPE_STREAMER(x) static int x##Streamer = \
Bitstream::registerTypeStreamer(QMetaType::type(#x), new SimpleTypeStreamer<x>()); Bitstream::registerTypeStreamer(QMetaType::type(#x), new SimpleTypeStreamer<x>());
/// 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<class T> int registerStreamableMetaType() {
int type = qRegisterMetaType<T>();
Bitstream::registerTypeStreamer(type, new SimpleTypeStreamer<T>());
return type;
}
#endif /* defined(__interface__Bitstream__) */ #endif /* defined(__interface__Bitstream__) */

View file

@ -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__) */