mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-16 12:00:11 +02:00
More streaming work.
This commit is contained in:
parent
de175e97b6
commit
b7f0057fe9
5 changed files with 142 additions and 34 deletions
|
@ -11,7 +11,12 @@
|
|||
#include "AttributeRegistry.h"
|
||||
#include "MetavoxelData.h"
|
||||
|
||||
AttributeRegistry AttributeRegistry::_instance;
|
||||
REGISTER_META_OBJECT(QRgbAttribute)
|
||||
|
||||
AttributeRegistry* AttributeRegistry::getInstance() {
|
||||
static AttributeRegistry registry;
|
||||
return ®istry;
|
||||
}
|
||||
|
||||
AttributeRegistry::AttributeRegistry() :
|
||||
_guideAttribute(registerAttribute(new PolymorphicAttribute("guide", PolymorphicDataPointer(new DefaultMetavoxelGuide())))),
|
||||
|
@ -36,7 +41,7 @@ AttributePointer AttributeRegistry::registerAttribute(AttributePointer attribute
|
|||
}
|
||||
|
||||
QScriptValue AttributeRegistry::getAttribute(QScriptContext* context, QScriptEngine* engine) {
|
||||
return engine->newQObject(_instance.getAttribute(context->argument(0).toString()).data(), QScriptEngine::QtOwnership,
|
||||
return engine->newQObject(getInstance()->getAttribute(context->argument(0).toString()).data(), QScriptEngine::QtOwnership,
|
||||
QScriptEngine::PreferExistingWrapperObject);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class AttributeRegistry {
|
|||
public:
|
||||
|
||||
/// Returns a pointer to the singleton registry instance.
|
||||
static AttributeRegistry* getInstance() { return &_instance; }
|
||||
static AttributeRegistry* getInstance();
|
||||
|
||||
AttributeRegistry();
|
||||
|
||||
|
@ -65,8 +65,6 @@ private:
|
|||
|
||||
static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine);
|
||||
|
||||
static AttributeRegistry _instance;
|
||||
|
||||
QHash<QString, AttributePointer> _attributes;
|
||||
AttributePointer _guideAttribute;
|
||||
AttributePointer _colorAttribute;
|
||||
|
@ -170,7 +168,7 @@ public:
|
|||
|
||||
virtual void* getDefaultValue() const { return encodeInline(_defaultValue); }
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
T _defaultValue;
|
||||
};
|
||||
|
@ -211,9 +209,12 @@ template<class T, int bits> inline bool SimpleInlineAttribute<T, bits>::merge(vo
|
|||
|
||||
/// Provides appropriate averaging for RGBA values.
|
||||
class QRgbAttribute : public InlineAttribute<QRgb> {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int defaultValue MEMBER _defaultValue)
|
||||
|
||||
public:
|
||||
|
||||
QRgbAttribute(const QString& name, QRgb defaultValue = QRgb());
|
||||
Q_INVOKABLE QRgbAttribute(const QString& name = QString(), QRgb defaultValue = QRgb());
|
||||
|
||||
virtual bool merge(void*& parent, void* children[]) const;
|
||||
|
||||
|
|
|
@ -12,21 +12,30 @@
|
|||
#include <QMetaProperty>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "AttributeRegistry.h"
|
||||
#include "Bitstream.h"
|
||||
|
||||
QHash<QByteArray, const QMetaObject*> Bitstream::_metaObjects;
|
||||
QHash<int, TypeStreamer*> Bitstream::_typeStreamers;
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(QByteArray)
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(QString)
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(bool)
|
||||
REGISTER_SIMPLE_TYPE_STREAMER(int)
|
||||
|
||||
void Bitstream::registerMetaObject(const QByteArray& name, const QMetaObject* metaObject) {
|
||||
_metaObjects.insert(name, metaObject);
|
||||
int Bitstream::registerMetaObject(const char* className, const QMetaObject* metaObject) {
|
||||
getMetaObjects().insert(className, metaObject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Bitstream::registerTypeStreamer(int type, TypeStreamer* streamer) {
|
||||
_typeStreamers.insert(type, streamer);
|
||||
int Bitstream::registerTypeStreamer(int type, TypeStreamer* streamer) {
|
||||
getTypeStreamers().insert(type, streamer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bitstream::Bitstream(QDataStream& underlying) :
|
||||
_underlying(underlying), _byte(0), _position(0), _classNameStreamer(*this) {
|
||||
_underlying(underlying),
|
||||
_byte(0),
|
||||
_position(0),
|
||||
_classNameStreamer(*this),
|
||||
_attributeStreamer(*this) {
|
||||
}
|
||||
|
||||
const int BITS_IN_BYTE = 8;
|
||||
|
@ -94,37 +103,63 @@ Bitstream& Bitstream::operator>>(bool& value) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(qint32 value) {
|
||||
Bitstream& Bitstream::operator<<(int value) {
|
||||
return write(&value, 32);
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(qint32& value) {
|
||||
return read(&value, 32);
|
||||
Bitstream& Bitstream::operator>>(int& value) {
|
||||
qint32 sizedValue;
|
||||
read(&sizedValue, 32);
|
||||
value = sizedValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const QByteArray& string) {
|
||||
*this << (qint32)string.size();
|
||||
*this << string.size();
|
||||
return write(string.constData(), string.size() * BITS_IN_BYTE);
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(QByteArray& string) {
|
||||
qint32 size;
|
||||
int size;
|
||||
*this >> size;
|
||||
return read(string.data(), size * BITS_IN_BYTE);
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const QString& string) {
|
||||
*this << (qint32)string.size();
|
||||
*this << string.size();
|
||||
return write(string.constData(), string.size() * sizeof(QChar) * BITS_IN_BYTE);
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(QString& string) {
|
||||
qint32 size;
|
||||
int size;
|
||||
*this >> size;
|
||||
return read(string.data(), size * sizeof(QChar) * BITS_IN_BYTE);
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const QVariant& value) {
|
||||
*this << value.userType();
|
||||
TypeStreamer* streamer = getTypeStreamers().value(value.userType());
|
||||
if (streamer) {
|
||||
streamer->write(*this, value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(QVariant& value) {
|
||||
int type;
|
||||
*this >> type;
|
||||
TypeStreamer* streamer = getTypeStreamers().value(type);
|
||||
if (streamer) {
|
||||
value = streamer->read(*this);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(QObject* object) {
|
||||
if (!object) {
|
||||
_classNameStreamer << QByteArray();
|
||||
return *this;
|
||||
}
|
||||
const QMetaObject* metaObject = object->metaObject();
|
||||
_classNameStreamer << QByteArray::fromRawData(metaObject->className(), strlen(metaObject->className()));
|
||||
for (int i = 0; i < metaObject->propertyCount(); i++) {
|
||||
|
@ -132,7 +167,7 @@ Bitstream& Bitstream::operator<<(QObject* object) {
|
|||
if (!property.isStored(object)) {
|
||||
continue;
|
||||
}
|
||||
TypeStreamer* streamer = _typeStreamers.value(property.userType());
|
||||
TypeStreamer* streamer = getTypeStreamers().value(property.userType());
|
||||
if (streamer) {
|
||||
streamer->write(*this, property.read(object));
|
||||
}
|
||||
|
@ -143,7 +178,11 @@ Bitstream& Bitstream::operator<<(QObject* object) {
|
|||
Bitstream& Bitstream::operator>>(QObject*& object) {
|
||||
QByteArray className;
|
||||
_classNameStreamer >> className;
|
||||
const QMetaObject* metaObject = _metaObjects.value(className);
|
||||
if (className.isEmpty()) {
|
||||
object = NULL;
|
||||
return *this;
|
||||
}
|
||||
const QMetaObject* metaObject = getMetaObjects().value(className);
|
||||
if (metaObject) {
|
||||
object = metaObject->newInstance();
|
||||
for (int i = 0; i < metaObject->propertyCount(); i++) {
|
||||
|
@ -151,7 +190,7 @@ Bitstream& Bitstream::operator>>(QObject*& object) {
|
|||
if (!property.isStored(object)) {
|
||||
continue;
|
||||
}
|
||||
TypeStreamer* streamer = _typeStreamers.value(property.userType());
|
||||
TypeStreamer* streamer = getTypeStreamers().value(property.userType());
|
||||
if (streamer) {
|
||||
property.write(object, streamer->read(*this));
|
||||
}
|
||||
|
@ -162,6 +201,27 @@ Bitstream& Bitstream::operator>>(QObject*& object) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const AttributePointer& attribute) {
|
||||
return *this << (QObject*)attribute.data();
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(AttributePointer& attribute) {
|
||||
QObject* object;
|
||||
*this >> object;
|
||||
attribute = AttributeRegistry::getInstance()->registerAttribute(static_cast<Attribute*>(object));
|
||||
return *this;
|
||||
}
|
||||
|
||||
QHash<QByteArray, const QMetaObject*>& Bitstream::getMetaObjects() {
|
||||
static QHash<QByteArray, const QMetaObject*> metaObjects;
|
||||
return metaObjects;
|
||||
}
|
||||
|
||||
QHash<int, TypeStreamer*>& Bitstream::getTypeStreamers() {
|
||||
static QHash<int, TypeStreamer*> typeStreamers;
|
||||
return typeStreamers;
|
||||
}
|
||||
|
||||
IDStreamer::IDStreamer(Bitstream& stream) :
|
||||
_stream(stream),
|
||||
_bits(1) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#define __interface__Bitstream__
|
||||
|
||||
#include <QHash>
|
||||
#include <QMetaType>
|
||||
#include <QSharedPointer>
|
||||
#include <QVariant>
|
||||
|
||||
class QByteArray;
|
||||
|
@ -17,9 +19,12 @@ class QDataStream;
|
|||
class QMetaObject;
|
||||
class QObject;
|
||||
|
||||
class Attribute;
|
||||
class Bitstream;
|
||||
class TypeStreamer;
|
||||
|
||||
typedef QSharedPointer<Attribute> AttributePointer;
|
||||
|
||||
/// Streams integer identifiers that conform to the following pattern: each ID encountered in the stream is either one that
|
||||
/// has been sent (received) before, or is one more than the highest previously encountered ID (starting at zero). This allows
|
||||
/// us to use the minimum number of bits to encode the IDs.
|
||||
|
@ -87,10 +92,12 @@ class Bitstream {
|
|||
public:
|
||||
|
||||
/// Registers a metaobject under its name so that instances of it can be streamed.
|
||||
static void registerMetaObject(const QByteArray& name, const QMetaObject* metaObject);
|
||||
/// \return zero; the function only returns a value so that it can be used in static initialization
|
||||
static int registerMetaObject(const char* className, const QMetaObject* metaObject);
|
||||
|
||||
/// Registers a streamer for the specified Qt-registered type.
|
||||
static void registerTypeStreamer(int type, TypeStreamer* streamer);
|
||||
/// \return zero; the function only returns a value so that it can be used in static initialization
|
||||
static int registerTypeStreamer(int type, TypeStreamer* streamer);
|
||||
|
||||
/// Creates a new bitstream. Note: the stream may be used for reading or writing, but not both.
|
||||
Bitstream(QDataStream& underlying);
|
||||
|
@ -108,11 +115,14 @@ public:
|
|||
/// Flushes any unwritten bits to the underlying stream.
|
||||
void flush();
|
||||
|
||||
/// Returns a reference to the attribute streamer.
|
||||
RepeatedValueStreamer<AttributePointer>& getAttributeStreamer() { return _attributeStreamer; }
|
||||
|
||||
Bitstream& operator<<(bool value);
|
||||
Bitstream& operator>>(bool& value);
|
||||
|
||||
Bitstream& operator<<(qint32 value);
|
||||
Bitstream& operator>>(qint32& value);
|
||||
Bitstream& operator<<(int value);
|
||||
Bitstream& operator>>(int& value);
|
||||
|
||||
Bitstream& operator<<(const QByteArray& string);
|
||||
Bitstream& operator>>(QByteArray& string);
|
||||
|
@ -120,9 +130,15 @@ public:
|
|||
Bitstream& operator<<(const QString& string);
|
||||
Bitstream& operator>>(QString& string);
|
||||
|
||||
Bitstream& operator<<(const QVariant& value);
|
||||
Bitstream& operator>>(QVariant& value);
|
||||
|
||||
Bitstream& operator<<(QObject* object);
|
||||
Bitstream& operator>>(QObject*& object);
|
||||
|
||||
Bitstream& operator<<(const AttributePointer& attribute);
|
||||
Bitstream& operator>>(AttributePointer& attribute);
|
||||
|
||||
private:
|
||||
|
||||
QDataStream& _underlying;
|
||||
|
@ -130,11 +146,15 @@ private:
|
|||
int _position;
|
||||
|
||||
RepeatedValueStreamer<QByteArray> _classNameStreamer;
|
||||
RepeatedValueStreamer<AttributePointer> _attributeStreamer;
|
||||
|
||||
static QHash<QByteArray, const QMetaObject*> _metaObjects;
|
||||
static QHash<int, TypeStreamer*> _typeStreamers;
|
||||
static QHash<QByteArray, const QMetaObject*>& getMetaObjects();
|
||||
static QHash<int, TypeStreamer*>& getTypeStreamers();
|
||||
};
|
||||
|
||||
/// Macro for registering streamable meta-objects.
|
||||
#define REGISTER_META_OBJECT(x) static int x##Registration = Bitstream::registerMetaObject(#x, &x::staticMetaObject);
|
||||
|
||||
/// Interface for objects that can write values to and read values from bitstreams.
|
||||
class TypeStreamer {
|
||||
public:
|
||||
|
@ -144,11 +164,15 @@ public:
|
|||
};
|
||||
|
||||
/// A streamer that works with Bitstream's operators.
|
||||
template<class T> class SimpleTypeStreamer {
|
||||
template<class T> class SimpleTypeStreamer : public TypeStreamer {
|
||||
public:
|
||||
|
||||
virtual void write(Bitstream& out, const QVariant& value) const { out << value.value<T>(); }
|
||||
virtual QVariant read(Bitstream& in) const { T value; in >> value; return QVariant::fromValue(value); }
|
||||
};
|
||||
|
||||
/// Macro for registering simple type streamers.
|
||||
#define REGISTER_SIMPLE_TYPE_STREAMER(x) static int x##Streamer = \
|
||||
Bitstream::registerTypeStreamer(QMetaType::type(#x), new SimpleTypeStreamer<x>());
|
||||
|
||||
#endif /* defined(__interface__Bitstream__) */
|
||||
|
|
|
@ -65,17 +65,35 @@ AttributeValue MetavoxelData::getAttributeValue(const MetavoxelPath& path, const
|
|||
}
|
||||
|
||||
void MetavoxelData::read(Bitstream& in) {
|
||||
// save the old roots and clear
|
||||
QHash<AttributePointer, MetavoxelNode*> oldRoots = _roots;
|
||||
_roots.clear();
|
||||
|
||||
// read in the new roots, reusing old ones where appropriate
|
||||
qint32 rootCount;
|
||||
in >> rootCount;
|
||||
for (int i = 0; i < rootCount; i++) {
|
||||
|
||||
}
|
||||
AttributePointer attribute;
|
||||
in.getAttributeStreamer() >> attribute;
|
||||
MetavoxelNode* root = oldRoots.take(attribute);
|
||||
if (!root) {
|
||||
root = new MetavoxelNode(attribute);
|
||||
}
|
||||
_roots.insert(attribute, root);
|
||||
root->read(attribute, in);
|
||||
}
|
||||
|
||||
// clear out the remaining old roots
|
||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = oldRoots.constBegin(); it != oldRoots.constEnd(); it++) {
|
||||
it.value()->destroy(it.key());
|
||||
delete it.value();
|
||||
}
|
||||
}
|
||||
|
||||
void MetavoxelData::write(Bitstream& out) const {
|
||||
out << (qint32)_roots.size();
|
||||
for (QHash<AttributePointer, MetavoxelNode*>::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) {
|
||||
|
||||
out.getAttributeStreamer() << it.key();
|
||||
it.value()->write(it.key(), out);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue