More TypeReader refactoring progress.

This commit is contained in:
Andrzej Kapolka 2014-06-10 18:29:21 -07:00
parent 69899f4d37
commit 9aa152f43f
2 changed files with 213 additions and 4 deletions

View file

@ -1950,11 +1950,22 @@ QVariant TypeStreamer::read(Bitstream& in) const {
}
void TypeStreamer::writeDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const {
// nothing by default
if (value == reference) {
out << false;
} else {
out << true;
writeRawDelta(out, value, reference);
}
}
void TypeStreamer::readDelta(Bitstream& in, QVariant& value, const QVariant& reference) const {
value = reference;
bool changed;
in >> changed;
if (changed) {
readRawDelta(in, value, reference);
} else {
value = reference;
}
}
void TypeStreamer::writeRawDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const {
@ -2151,6 +2162,30 @@ void EnumTypeStreamer::setEnumValue(QVariant& object, int value, const QHash<int
}
}
MappedEnumTypeStreamer::MappedEnumTypeStreamer(const TypeStreamer* baseStreamer, int bits, const QHash<int, int>& mappings) :
_baseStreamer(baseStreamer),
_bits(bits),
_mappings(mappings) {
}
QVariant MappedEnumTypeStreamer::read(Bitstream& in) const {
QVariant object = _baseStreamer ? QVariant(_baseStreamer->getType(), 0) : QVariant();
int value = 0;
in.read(&value, _bits);
if (_baseStreamer) {
_baseStreamer->setEnumValue(object, value, _mappings);
}
return object;
}
void MappedEnumTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const {
int value = 0;
in.read(&value, _bits);
if (_baseStreamer) {
_baseStreamer->setEnumValue(object, value, _mappings);
}
}
GenericValue::GenericValue(const TypeStreamerPointer& streamer, const QVariant& value) :
_streamer(streamer),
_value(value) {
@ -2163,3 +2198,121 @@ bool GenericValue::operator==(const GenericValue& other) const {
const TypeStreamer* GenericTypeStreamer::getStreamerToWrite(const QVariant& value) const {
return value.value<GenericValue>().getStreamer().data();
}
MappedListTypeStreamer::MappedListTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer) :
_baseStreamer(baseStreamer),
_valueStreamer(valueStreamer) {
}
QVariant MappedListTypeStreamer::read(Bitstream& in) const {
QVariant object = _baseStreamer ? QVariant(_baseStreamer->getType(), 0) : QVariant();
int size;
in >> size;
for (int i = 0; i < size; i++) {
QVariant value = _valueStreamer->read(in);
if (_baseStreamer) {
_baseStreamer->insert(object, value);
}
}
return object;
}
void MappedListTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const {
object = reference;
int size, referenceSize;
in >> size >> referenceSize;
if (_baseStreamer) {
if (size < referenceSize) {
_baseStreamer->prune(object, size);
}
for (int i = 0; i < size; i++) {
if (i < referenceSize) {
QVariant value;
_valueStreamer->readDelta(in, value, _baseStreamer->getValue(reference, i));
_baseStreamer->setValue(object, i, value);
} else {
_baseStreamer->insert(object, _valueStreamer->read(in));
}
}
} else {
for (int i = 0; i < size; i++) {
if (i < referenceSize) {
QVariant value;
_valueStreamer->readDelta(in, value, QVariant());
} else {
_valueStreamer->read(in);
}
}
}
}
MappedSetTypeStreamer::MappedSetTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer) :
MappedListTypeStreamer(baseStreamer, valueStreamer) {
}
void MappedSetTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const {
object = reference;
int addedOrRemoved;
in >> addedOrRemoved;
for (int i = 0; i < addedOrRemoved; i++) {
QVariant value = _valueStreamer->read(in);
if (_baseStreamer && !_baseStreamer->remove(object, value)) {
_baseStreamer->insert(object, value);
}
}
}
MappedMapTypeStreamer::MappedMapTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& keyStreamer,
const TypeStreamerPointer& valueStreamer) :
_baseStreamer(baseStreamer),
_keyStreamer(keyStreamer),
_valueStreamer(valueStreamer) {
}
QVariant MappedMapTypeStreamer::read(Bitstream& in) const {
QVariant object = _baseStreamer ? QVariant(_baseStreamer->getType(), 0) : QVariant();
int size;
in >> size;
for (int i = 0; i < size; i++) {
QVariant key = _keyStreamer->read(in);
QVariant value = _valueStreamer->read(in);
if (_baseStreamer) {
_baseStreamer->insert(object, key, value);
}
}
return object;
}
void MappedMapTypeStreamer::readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const {
object = reference;
int added;
in >> added;
for (int i = 0; i < added; i++) {
QVariant key = _keyStreamer->read(in);
QVariant value = _valueStreamer->read(in);
if (_baseStreamer) {
_baseStreamer->insert(object, key, value);
}
}
int modified;
in >> modified;
for (int i = 0; i < modified; i++) {
QVariant key = _keyStreamer->read(in);
QVariant value;
if (_baseStreamer) {
_valueStreamer->readDelta(in, value, _baseStreamer->getValue(reference, key));
_baseStreamer->insert(object, key, value);
} else {
_valueStreamer->readDelta(in, value, QVariant());
}
}
int removed;
in >> removed;
for (int i = 0; i < removed; i++) {
QVariant key = _keyStreamer->read(in);
if (_baseStreamer) {
_baseStreamer->remove(object, key);
}
}
}

View file

@ -47,6 +47,7 @@ class TypeStreamer;
typedef SharedObjectPointerTemplate<Attribute> AttributePointer;
typedef QPair<QByteArray, QByteArray> ScopeNamePair;
typedef QSharedPointer<TypeStreamer> TypeStreamerPointer;
typedef QVector<PropertyReader> PropertyReaderVector;
typedef QVector<PropertyWriter> PropertyWriterVector;
@ -904,8 +905,6 @@ Q_DECLARE_METATYPE(const QMetaObject*)
/// Macro for registering streamable meta-objects.
#define REGISTER_META_OBJECT(x) static int x##Registration = Bitstream::registerMetaObject(#x, &x::staticMetaObject);
typedef QSharedPointer<TypeStreamer> TypeStreamerPointer;
/// Interface for objects that can write values to and read values from bitstreams.
class TypeStreamer {
public:
@ -1014,6 +1013,22 @@ private:
int _bits;
};
/// A streamer class for enums that maps to a local type.
class MappedEnumTypeStreamer : public TypeStreamer {
public:
MappedEnumTypeStreamer(const TypeStreamer* baseStreamer, int bits, const QHash<int, int>& mappings);
virtual QVariant read(Bitstream& in) const;
virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const;
private:
const TypeStreamer* _baseStreamer;
int _bits;
QHash<int, int> _mappings;
};
/// Contains a value along with a pointer to its streamer.
class GenericValue {
public:
@ -1089,6 +1104,21 @@ public:
static_cast<QVector<T>*>(object.data())->replace(index, value.value<T>()); }
};
/// A streamer for lists that maps to a local type.
class MappedListTypeStreamer : public TypeStreamer {
public:
MappedListTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer);
virtual QVariant read(Bitstream& in) const;
virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const;
protected:
const TypeStreamer* _baseStreamer;
TypeStreamerPointer _valueStreamer;
};
/// A streamer for set types.
template<class T> class CollectionTypeStreamer<QSet<T> > : public SimpleTypeStreamer<QSet<T> > {
public:
@ -1101,6 +1131,15 @@ public:
return static_cast<QSet<T>*>(object.data())->remove(key.value<T>()); }
};
/// A streamer for sets that maps to a local type.
class MappedSetTypeStreamer : public MappedListTypeStreamer {
public:
MappedSetTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& valueStreamer);
virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const;
};
/// A streamer for hash types.
template<class K, class V> class CollectionTypeStreamer<QHash<K, V> > : public SimpleTypeStreamer<QHash<K, V> > {
public:
@ -1116,6 +1155,23 @@ public:
return QVariant::fromValue(static_cast<const QHash<K, V>*>(object.constData())->value(key.value<K>())); }
};
/// A streamer for maps that maps to a local type.
class MappedMapTypeStreamer : public TypeStreamer {
public:
MappedMapTypeStreamer(const TypeStreamer* baseStreamer, const TypeStreamerPointer& keyStreamer,
const TypeStreamerPointer& valueStreamer);
virtual QVariant read(Bitstream& in) const;
virtual void readRawDelta(Bitstream& in, QVariant& object, const QVariant& reference) const;
private:
const TypeStreamer* _baseStreamer;
TypeStreamerPointer _keyStreamer;
TypeStreamerPointer _valueStreamer;
};
/// Macro for registering simple type streamers.
#define REGISTER_SIMPLE_TYPE_STREAMER(X) static int X##Streamer = \
Bitstream::registerTypeStreamer(qMetaTypeId<X>(), new SimpleTypeStreamer<X>());