More work on streaming.

This commit is contained in:
Andrzej Kapolka 2013-12-18 17:10:53 -08:00
parent 0b02ed6683
commit 130ec7488a
5 changed files with 110 additions and 7 deletions

View file

@ -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*)&copy); 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<T>(first) == decodeInline<T>(second); }
@ -175,6 +175,19 @@ private:
T _defaultValue;
};
template<class T, int bits> inline void InlineAttribute<T, bits>::read(Bitstream& in, void*& value, bool isLeaf) const {
if (isLeaf) {
value = getDefaultValue();
in.read(&value, bits);
}
}
template<class T, int bits> inline void InlineAttribute<T, bits>::write(Bitstream& out, void* value, bool isLeaf) const {
if (isLeaf) {
out.write(&value, bits);
}
}
/// Provides merging using the =, ==, += and /= operators.
template<class T, int bits = 32> class SimpleInlineAttribute : public InlineAttribute<T, bits> {
public:
@ -216,8 +229,8 @@ public:
virtual void* create(void* copy) const { new T(*static_cast<T*>(copy)); }
virtual void destroy(void* value) const { delete static_cast<T*>(value); }
virtual bool read(Bitstream& in, void*& value) const { in >> *static_cast<T*>(value); return true; }
virtual bool write(Bitstream& out, void* value) const { out << *static_cast<T*>(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<T*>(first) == *static_cast<T*>(second); }
@ -228,6 +241,18 @@ private:
T _defaultValue;
};
template<class T> inline void PointerAttribute<T>::read(Bitstream& in, void*& value, bool isLeaf) const {
if (isLeaf) {
in.read(value, sizeof(T) * 8);
}
}
template<class T> inline void PointerAttribute<T>::write(Bitstream& out, void* value, bool isLeaf) const {
if (isLeaf) {
out.write(value, sizeof(T) * 8);
}
}
/// Provides merging using the =, ==, += and /= operators.
template<class T> class SimplePointerAttribute : public PointerAttribute<T> {
public:

View file

@ -10,6 +10,12 @@
#include "Bitstream.h"
QHash<QByteArray, const QMetaObject*> 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);
}

View file

@ -9,14 +9,20 @@
#ifndef __interface__Bitstream__
#define __interface__Bitstream__
#include <QHash>
#include <QtGlobal>
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<QByteArray, const QMetaObject*> _metaObjects;
};
#endif /* defined(__interface__Bitstream__) */

View file

@ -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<AttributePointer, MetavoxelNode*>::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++) {

View file

@ -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<AttributePointer, MetavoxelNode*> _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: