mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 00:13:29 +02:00
Collection streaming (untested).
This commit is contained in:
parent
b84499c83b
commit
a4cc15a2cd
2 changed files with 109 additions and 17 deletions
|
@ -577,6 +577,22 @@ Bitstream& Bitstream::operator<(const TypeStreamer* streamer) {
|
||||||
if (_metadataType == NO_METADATA) {
|
if (_metadataType == NO_METADATA) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
TypeStreamer::Category category = streamer->getCategory();
|
||||||
|
*this << (int)category;
|
||||||
|
switch (category) {
|
||||||
|
case TypeStreamer::SIMPLE_CATEGORY:
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
case TypeStreamer::LIST_CATEGORY:
|
||||||
|
return *this << streamer->getValueStreamer();
|
||||||
|
|
||||||
|
case TypeStreamer::MAP_CATEGORY:
|
||||||
|
return *this << streamer->getKeyStreamer() << streamer->getValueStreamer();
|
||||||
|
|
||||||
|
default:
|
||||||
|
break; // fall through
|
||||||
|
}
|
||||||
|
// streamable type
|
||||||
const QVector<MetaField>& metaFields = streamer->getMetaFields();
|
const QVector<MetaField>& metaFields = streamer->getMetaFields();
|
||||||
*this << metaFields.size();
|
*this << metaFields.size();
|
||||||
if (metaFields.isEmpty()) {
|
if (metaFields.isEmpty()) {
|
||||||
|
@ -612,6 +628,40 @@ Bitstream& Bitstream::operator>(TypeReader& reader) {
|
||||||
reader = TypeReader(typeName, streamer);
|
reader = TypeReader(typeName, streamer);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
int category;
|
||||||
|
*this >> category;
|
||||||
|
switch (category) {
|
||||||
|
case TypeStreamer::SIMPLE_CATEGORY:
|
||||||
|
reader = TypeReader(typeName, streamer);
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
case TypeStreamer::LIST_CATEGORY: {
|
||||||
|
TypeReader valueReader;
|
||||||
|
*this >> valueReader;
|
||||||
|
if (streamer && streamer->getCategory() == TypeStreamer::LIST_CATEGORY &&
|
||||||
|
valueReader.matchesExactly(streamer->getValueStreamer())) {
|
||||||
|
reader = TypeReader(typeName, streamer);
|
||||||
|
} else {
|
||||||
|
reader = TypeReader(typeName, streamer, false, TypeReaderPointer(),
|
||||||
|
TypeReaderPointer(new TypeReader(valueReader)));
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
case TypeStreamer::MAP_CATEGORY: {
|
||||||
|
TypeReader keyReader, valueReader;
|
||||||
|
*this >> keyReader >> valueReader;
|
||||||
|
if (streamer && streamer->getCategory() == TypeStreamer::MAP_CATEGORY &&
|
||||||
|
keyReader.matchesExactly(streamer->getKeyStreamer()) &&
|
||||||
|
valueReader.matchesExactly(streamer->getValueStreamer())) {
|
||||||
|
reader = TypeReader(typeName, streamer);
|
||||||
|
} else {
|
||||||
|
reader = TypeReader(typeName, streamer, false, TypeReaderPointer(new TypeReader(keyReader)),
|
||||||
|
TypeReaderPointer(new TypeReader(valueReader)));
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// streamable type
|
||||||
int fieldCount;
|
int fieldCount;
|
||||||
*this >> fieldCount;
|
*this >> fieldCount;
|
||||||
QVector<FieldReader> fields(fieldCount);
|
QVector<FieldReader> fields(fieldCount);
|
||||||
|
@ -664,20 +714,20 @@ Bitstream& Bitstream::operator>(TypeReader& reader) {
|
||||||
// if all fields are the same type and in the right order, we can use the (more efficient) default streamer
|
// if all fields are the same type and in the right order, we can use the (more efficient) default streamer
|
||||||
const QVector<MetaField>& localFields = streamer->getMetaFields();
|
const QVector<MetaField>& localFields = streamer->getMetaFields();
|
||||||
if (fieldCount != localFields.size()) {
|
if (fieldCount != localFields.size()) {
|
||||||
reader = TypeReader(typeName, streamer, false, fields);
|
reader = TypeReader(typeName, streamer, false, TypeReaderPointer(), TypeReaderPointer(), fields);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < fieldCount; i++) {
|
for (int i = 0; i < fieldCount; i++) {
|
||||||
const FieldReader& fieldReader = fields.at(i);
|
const FieldReader& fieldReader = fields.at(i);
|
||||||
if (!fieldReader.getReader().matchesExactly(localFields.at(i).getStreamer()) || fieldReader.getIndex() != i) {
|
if (!fieldReader.getReader().matchesExactly(localFields.at(i).getStreamer()) || fieldReader.getIndex() != i) {
|
||||||
reader = TypeReader(typeName, streamer, false, fields);
|
reader = TypeReader(typeName, streamer, false, TypeReaderPointer(), TypeReaderPointer(), fields);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader = TypeReader(typeName, streamer);
|
reader = TypeReader(typeName, streamer);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
reader = TypeReader(typeName, streamer, false, fields);
|
reader = TypeReader(typeName, streamer, false, TypeReaderPointer(), TypeReaderPointer(), fields);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,11 +823,13 @@ QVector<PropertyReader> Bitstream::getPropertyReaders(const QMetaObject* metaObj
|
||||||
return propertyReaders;
|
return propertyReaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer,
|
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer, bool exactMatch,
|
||||||
bool exactMatch, const QVector<FieldReader>& fields) :
|
const TypeReaderPointer& keyReader, const TypeReaderPointer& valueReader, const QVector<FieldReader>& fields) :
|
||||||
_typeName(typeName),
|
_typeName(typeName),
|
||||||
_streamer(streamer),
|
_streamer(streamer),
|
||||||
_exactMatch(exactMatch),
|
_exactMatch(exactMatch),
|
||||||
|
_keyReader(keyReader),
|
||||||
|
_valueReader(valueReader),
|
||||||
_fields(fields) {
|
_fields(fields) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,9 +838,30 @@ QVariant TypeReader::read(Bitstream& in) const {
|
||||||
return _streamer->read(in);
|
return _streamer->read(in);
|
||||||
}
|
}
|
||||||
QVariant object = _streamer ? QVariant(_streamer->getType(), 0) : QVariant();
|
QVariant object = _streamer ? QVariant(_streamer->getType(), 0) : QVariant();
|
||||||
|
if (_valueReader) {
|
||||||
|
int size;
|
||||||
|
in >> size;
|
||||||
|
if (_keyReader) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
QVariant key = _keyReader->read(in);
|
||||||
|
QVariant value = _valueReader->read(in);
|
||||||
|
if (_streamer) {
|
||||||
|
_streamer->insert(object, key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
QVariant value = _valueReader->read(in);
|
||||||
|
if (_streamer) {
|
||||||
|
_streamer->insert(object, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
foreach (const FieldReader& field, _fields) {
|
foreach (const FieldReader& field, _fields) {
|
||||||
field.read(in, _streamer, object);
|
field.read(in, _streamer, object);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,6 +939,10 @@ void TypeStreamer::setField(int index, QVariant& object, const QVariant& value)
|
||||||
// nothing by default
|
// nothing by default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeStreamer::Category TypeStreamer::getCategory() const {
|
||||||
|
return SIMPLE_CATEGORY;
|
||||||
|
}
|
||||||
|
|
||||||
const TypeStreamer* TypeStreamer::getKeyStreamer() const {
|
const TypeStreamer* TypeStreamer::getKeyStreamer() const {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -874,7 +951,7 @@ const TypeStreamer* TypeStreamer::getValueStreamer() const {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeStreamer::append(QVariant& object, const QVariant& element) const {
|
void TypeStreamer::insert(QVariant& object, const QVariant& element) const {
|
||||||
// nothing by default
|
// nothing by default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -444,12 +444,15 @@ template<class K, class V> inline Bitstream& Bitstream::operator>>(QHash<K, V>&
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef QSharedPointer<TypeReader> TypeReaderPointer;
|
||||||
|
|
||||||
/// Contains the information required to read a type from the stream.
|
/// Contains the information required to read a type from the stream.
|
||||||
class TypeReader {
|
class TypeReader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TypeReader(const QByteArray& typeName = QByteArray(), const TypeStreamer* streamer = NULL,
|
TypeReader(const QByteArray& typeName = QByteArray(), const TypeStreamer* streamer = NULL, bool exactMatch = true,
|
||||||
bool exactMatch = true, const QVector<FieldReader>& fields = QVector<FieldReader>());
|
const TypeReaderPointer& keyReader = TypeReaderPointer(), const TypeReaderPointer& valueReader = TypeReaderPointer(),
|
||||||
|
const QVector<FieldReader>& fields = QVector<FieldReader>());
|
||||||
|
|
||||||
const QByteArray& getTypeName() const { return _typeName; }
|
const QByteArray& getTypeName() const { return _typeName; }
|
||||||
const TypeStreamer* getStreamer() const { return _streamer; }
|
const TypeStreamer* getStreamer() const { return _streamer; }
|
||||||
|
@ -466,6 +469,8 @@ private:
|
||||||
QByteArray _typeName;
|
QByteArray _typeName;
|
||||||
const TypeStreamer* _streamer;
|
const TypeStreamer* _streamer;
|
||||||
bool _exactMatch;
|
bool _exactMatch;
|
||||||
|
TypeReaderPointer _keyReader;
|
||||||
|
TypeReaderPointer _valueReader;
|
||||||
QVector<FieldReader> _fields;
|
QVector<FieldReader> _fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -552,8 +557,6 @@ Q_DECLARE_METATYPE(const QMetaObject*)
|
||||||
class TypeStreamer {
|
class TypeStreamer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Category { SIMPLE_CATEGORY, STREAMABLE_CATEGORY };
|
|
||||||
|
|
||||||
virtual ~TypeStreamer();
|
virtual ~TypeStreamer();
|
||||||
|
|
||||||
void setType(int type) { _type = type; }
|
void setType(int type) { _type = type; }
|
||||||
|
@ -566,10 +569,14 @@ public:
|
||||||
virtual int getFieldIndex(const QByteArray& name) const;
|
virtual int getFieldIndex(const QByteArray& name) const;
|
||||||
virtual void setField(int index, QVariant& object, const QVariant& value) const;
|
virtual void setField(int index, QVariant& object, const QVariant& value) const;
|
||||||
|
|
||||||
|
enum Category { SIMPLE_CATEGORY, STREAMABLE_CATEGORY, LIST_CATEGORY, MAP_CATEGORY };
|
||||||
|
|
||||||
|
virtual Category getCategory() const;
|
||||||
|
|
||||||
virtual const TypeStreamer* getKeyStreamer() const;
|
virtual const TypeStreamer* getKeyStreamer() const;
|
||||||
virtual const TypeStreamer* getValueStreamer() const;
|
virtual const TypeStreamer* getValueStreamer() const;
|
||||||
|
|
||||||
virtual void append(QVariant& object, const QVariant& element) const;
|
virtual void insert(QVariant& object, const QVariant& value) const;
|
||||||
virtual void insert(QVariant& object, const QVariant& key, const QVariant& value) const;
|
virtual void insert(QVariant& object, const QVariant& key, const QVariant& value) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -589,6 +596,7 @@ public:
|
||||||
template<class T> class StreamableTypeStreamer : public SimpleTypeStreamer<T> {
|
template<class T> class StreamableTypeStreamer : public SimpleTypeStreamer<T> {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual TypeStreamer::Category getCategory() const { return TypeStreamer::STREAMABLE_CATEGORY; }
|
||||||
virtual const QVector<MetaField>& getMetaFields() const { return T::getMetaFields(); }
|
virtual const QVector<MetaField>& getMetaFields() const { return T::getMetaFields(); }
|
||||||
virtual int getFieldIndex(const QByteArray& name) const { return T::getFieldIndex(name); }
|
virtual int getFieldIndex(const QByteArray& name) const { return T::getFieldIndex(name); }
|
||||||
virtual void setField(int index, QVariant& object, const QVariant& value) const {
|
virtual void setField(int index, QVariant& object, const QVariant& value) const {
|
||||||
|
@ -603,22 +611,29 @@ template<class T> class CollectionTypeStreamer : public SimpleTypeStreamer<T> {
|
||||||
template<class T> class CollectionTypeStreamer<QList<T> > : public SimpleTypeStreamer<QList<T> > {
|
template<class T> class CollectionTypeStreamer<QList<T> > : public SimpleTypeStreamer<QList<T> > {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void append(QVariant& object, const QVariant& element) const {
|
virtual TypeStreamer::Category getCategory() const { return TypeStreamer::LIST_CATEGORY; }
|
||||||
static_cast<QList<T>*>(object.data())->append(element.value<T>()); }
|
virtual const TypeStreamer* getValueStreamer() const { return Bitstream::getTypeStreamer(qMetaTypeId<T>()); }
|
||||||
|
virtual void insert(QVariant& object, const QVariant& value) const {
|
||||||
|
static_cast<QList<T>*>(object.data())->append(value.value<T>()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A streamer for set types.
|
/// A streamer for set types.
|
||||||
template<class T> class CollectionTypeStreamer<QSet<T> > : public SimpleTypeStreamer<QSet<T> > {
|
template<class T> class CollectionTypeStreamer<QSet<T> > : public SimpleTypeStreamer<QSet<T> > {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void append(QVariant& object, const QVariant& element) const {
|
virtual TypeStreamer::Category getCategory() const { return TypeStreamer::LIST_CATEGORY; }
|
||||||
static_cast<QSet<T>*>(object.data())->insert(element.value<T>()); }
|
virtual const TypeStreamer* getValueStreamer() const { return Bitstream::getTypeStreamer(qMetaTypeId<T>()); }
|
||||||
|
virtual void insert(QVariant& object, const QVariant& value) const {
|
||||||
|
static_cast<QSet<T>*>(object.data())->insert(value.value<T>()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A streamer for hash types.
|
/// A streamer for hash types.
|
||||||
template<class K, class V> class CollectionTypeStreamer<QHash<K, V> > : public SimpleTypeStreamer<QHash<K, V> > {
|
template<class K, class V> class CollectionTypeStreamer<QHash<K, V> > : public SimpleTypeStreamer<QHash<K, V> > {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual TypeStreamer::Category getCategory() const { return TypeStreamer::MAP_CATEGORY; }
|
||||||
|
virtual const TypeStreamer* getKeyStreamer() const { return Bitstream::getTypeStreamer(qMetaTypeId<K>()); }
|
||||||
|
virtual const TypeStreamer* getValueStreamer() const { return Bitstream::getTypeStreamer(qMetaTypeId<V>()); }
|
||||||
virtual void insert(QVariant& object, const QVariant& key, const QVariant& value) const {
|
virtual void insert(QVariant& object, const QVariant& key, const QVariant& value) const {
|
||||||
static_cast<QHash<K, V>*>(object.data())->insert(key.value<K>(), value.value<V>()); }
|
static_cast<QHash<K, V>*>(object.data())->insert(key.value<K>(), value.value<V>()); }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue