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) {
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<QByteArray, const QMetaObject*>& Bitstream::getMetaObjects() {
return metaObjects;
}
QHash<int, TypeStreamer*>& Bitstream::getTypeStreamers() {
static QHash<int, TypeStreamer*> typeStreamers;
QHash<int, const TypeStreamer*>& Bitstream::getTypeStreamers() {
static QHash<int, const TypeStreamer*> typeStreamers;
return typeStreamers;
}

View file

@ -154,12 +154,14 @@ public:
class WriteMappings {
public:
QHash<const QMetaObject*, int> metaObjectOffsets;
QHash<const TypeStreamer*, int> typeStreamerOffsets;
QHash<AttributePointer, int> attributeOffsets;
};
class ReadMappings {
public:
QHash<int, const QMetaObject*> metaObjectValues;
QHash<int, const TypeStreamer*> typeStreamerValues;
QHash<int, AttributePointer> 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<const QMetaObject*> _metaObjectStreamer;
RepeatedValueStreamer<const TypeStreamer*> _typeStreamerStreamer;
RepeatedValueStreamer<AttributePointer> _attributeStreamer;
static QHash<QByteArray, const QMetaObject*>& getMetaObjects();
static QHash<int, TypeStreamer*>& getTypeStreamers();
static QHash<int, const TypeStreamer*>& 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<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__) */

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