From 130ec7488ae6de69b631a5c4db061dfc6111382b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 18 Dec 2013 17:10:53 -0800 Subject: [PATCH] More work on streaming. --- libraries/metavoxels/src/AttributeRegistry.h | 37 +++++++++++++--- libraries/metavoxels/src/Bitstream.cpp | 15 ++++++- libraries/metavoxels/src/Bitstream.h | 13 ++++++ libraries/metavoxels/src/MetavoxelData.cpp | 46 ++++++++++++++++++++ libraries/metavoxels/src/MetavoxelData.h | 6 +++ 5 files changed, 110 insertions(+), 7 deletions(-) diff --git a/libraries/metavoxels/src/AttributeRegistry.h b/libraries/metavoxels/src/AttributeRegistry.h index a5f9c08f8b..559828eecb 100644 --- a/libraries/metavoxels/src/AttributeRegistry.h +++ b/libraries/metavoxels/src/AttributeRegistry.h @@ -140,8 +140,8 @@ public: virtual void* create(void* copy) const = 0; virtual void destroy(void* value) const = 0; - virtual bool read(Bitstream& in, void*& value) const = 0; - virtual bool write(Bitstream& out, void* value) const = 0; + virtual void read(Bitstream& in, void*& value, bool isLeaf) const = 0; + virtual void write(Bitstream& out, void* value, bool isLeaf) const = 0; virtual bool equal(void* first, void* second) const = 0; @@ -163,8 +163,8 @@ public: virtual void* create(void* copy) const { void* value; new (&value) T(*(T*)©); return value; } virtual void destroy(void* value) const { ((T*)&value)->~T(); } - virtual bool read(Bitstream& in, void*& value) const { value = getDefaultValue(); in.read(&value, bits); return false; } - virtual bool write(Bitstream& out, void* value) const { out.write(&value, bits); return false; } + virtual void read(Bitstream& in, void*& value, bool isLeaf) const; + virtual void write(Bitstream& out, void* value, bool isLeaf) const; virtual bool equal(void* first, void* second) const { return decodeInline(first) == decodeInline(second); } @@ -175,6 +175,19 @@ private: T _defaultValue; }; +template inline void InlineAttribute::read(Bitstream& in, void*& value, bool isLeaf) const { + if (isLeaf) { + value = getDefaultValue(); + in.read(&value, bits); + } +} + +template inline void InlineAttribute::write(Bitstream& out, void* value, bool isLeaf) const { + if (isLeaf) { + out.write(&value, bits); + } +} + /// Provides merging using the =, ==, += and /= operators. template class SimpleInlineAttribute : public InlineAttribute { public: @@ -216,8 +229,8 @@ public: virtual void* create(void* copy) const { new T(*static_cast(copy)); } virtual void destroy(void* value) const { delete static_cast(value); } - virtual bool read(Bitstream& in, void*& value) const { in >> *static_cast(value); return true; } - virtual bool write(Bitstream& out, void* value) const { out << *static_cast(value); return true; } + virtual void read(Bitstream& in, void*& value, bool isLeaf) const; + virtual void write(Bitstream& out, void* value, bool isLeaf) const; virtual bool equal(void* first, void* second) const { return *static_cast(first) == *static_cast(second); } @@ -228,6 +241,18 @@ private: T _defaultValue; }; +template inline void PointerAttribute::read(Bitstream& in, void*& value, bool isLeaf) const { + if (isLeaf) { + in.read(value, sizeof(T) * 8); + } +} + +template inline void PointerAttribute::write(Bitstream& out, void* value, bool isLeaf) const { + if (isLeaf) { + out.write(value, sizeof(T) * 8); + } +} + /// Provides merging using the =, ==, += and /= operators. template class SimplePointerAttribute : public PointerAttribute { public: diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index ac91bdf767..032ff27068 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -10,6 +10,12 @@ #include "Bitstream.h" +QHash Bitstream::_metaObjects; + +void Bitstream::registerMetaObject(const QByteArray& name, const QMetaObject* metaObject) { + _metaObjects.insert(name, metaObject); +} + Bitstream::Bitstream(QDataStream& underlying) : _underlying(underlying), _byte(0), _position(0) { } @@ -60,7 +66,6 @@ void Bitstream::flush() { } } - Bitstream& Bitstream::operator<<(bool value) { if (value) { _byte |= (1 << _position); @@ -79,3 +84,11 @@ Bitstream& Bitstream::operator>>(bool& value) { _position = (_position + 1) & LAST_BIT_POSITION; return *this; } + +Bitstream& Bitstream::operator<<(qint32 value) { + return write(&value, 32, 0); +} + +Bitstream& Bitstream::operator>>(qint32& value) { + return read(&value, 32, 0); +} diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index 12a1b88886..74a5d76775 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -9,14 +9,20 @@ #ifndef __interface__Bitstream__ #define __interface__Bitstream__ +#include #include +class QByteArray; class QDataStream; +class QMetaObject; /// A stream for bit-aligned data. 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); + Bitstream(QDataStream& underlying); /// Writes a set of bits to the underlying stream. @@ -35,11 +41,18 @@ public: Bitstream& operator<<(bool value); Bitstream& operator>>(bool& value); + Bitstream& operator<<(qint32 value); + Bitstream& operator>>(qint32& value); + + + private: QDataStream& _underlying; quint8 _byte; int _position; + + static QHash _metaObjects; }; #endif /* defined(__interface__Bitstream__) */ diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 636982b63a..e464399508 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -64,6 +64,21 @@ AttributeValue MetavoxelData::getAttributeValue(const MetavoxelPath& path, const return node->getAttributeValue(attribute); } +void MetavoxelData::read(Bitstream& in) { + qint32 rootCount; + in >> rootCount; + for (int i = 0; i < rootCount; i++) { + + } +} + +void MetavoxelData::write(Bitstream& out) const { + out << (qint32)_roots.size(); + for (QHash::const_iterator it = _roots.constBegin(); it != _roots.constEnd(); it++) { + it.value()->write(it.key(), out); + } +} + MetavoxelNode::MetavoxelNode(const AttributeValue& attributeValue) { _attributeValue = attributeValue.copy(); for (int i = 0; i < CHILD_COUNT; i++) { @@ -118,6 +133,37 @@ bool MetavoxelNode::isLeaf() const { return true; } +void MetavoxelNode::read(const AttributePointer& attribute, Bitstream& in) { + bool leaf; + in >> leaf; + attribute->read(in, _attributeValue, leaf); + if (leaf) { + clearChildren(attribute); + + } else { + void* childValues[CHILD_COUNT]; + for (int i = 0; i < CHILD_COUNT; i++) { + if (!_children[i]) { + _children[i] = new MetavoxelNode(attribute); + } + _children[i]->read(attribute, in); + childValues[i] = _children[i]->_attributeValue; + } + attribute->merge(_attributeValue, childValues); + } +} + +void MetavoxelNode::write(const AttributePointer& attribute, Bitstream& out) const { + bool leaf = isLeaf(); + out << leaf; + attribute->write(out, _attributeValue, leaf); + if (!leaf) { + for (int i = 0; i < CHILD_COUNT; i++) { + _children[i]->write(attribute, out); + } + } +} + void MetavoxelNode::destroy(const AttributePointer& attribute) { attribute->destroy(_attributeValue); for (int i = 0; i < CHILD_COUNT; i++) { diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index fc7045cff4..32c66c789c 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -41,6 +41,9 @@ public: /// Retrieves the attribute value corresponding to the specified path. AttributeValue getAttributeValue(const MetavoxelPath& path, const AttributePointer& attribute) const; + void read(Bitstream& in); + void write(Bitstream& out) const; + private: QHash _roots; @@ -69,6 +72,9 @@ public: bool isLeaf() const; + void read(const AttributePointer& attribute, Bitstream& in); + void write(const AttributePointer& attribute, Bitstream& out) const; + void destroy(const AttributePointer& attribute); private: