mirror of
https://github.com/overte-org/overte.git
synced 2025-08-13 00:10:00 +02:00
More commentation.
This commit is contained in:
parent
5e0cab59ea
commit
b8e6660e19
2 changed files with 47 additions and 6 deletions
|
@ -1879,6 +1879,7 @@ QJsonDocument JSONWriter::getDocument() const {
|
|||
}
|
||||
|
||||
JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode genericsMode) {
|
||||
// create and map the type streamers in order
|
||||
QJsonObject top = document.object();
|
||||
foreach (const QJsonValue& element, top.value("types").toArray()) {
|
||||
QJsonObject type = element.toObject();
|
||||
|
@ -1889,10 +1890,11 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
baseStreamer = Bitstream::getEnumStreamersByName().value(latinName);
|
||||
}
|
||||
if (!baseStreamer && genericsMode == Bitstream::NO_GENERICS) {
|
||||
continue;
|
||||
continue; // no built-in type and no generics allowed; we give up
|
||||
}
|
||||
QString category = type.value("category").toString();
|
||||
if (!baseStreamer || genericsMode == Bitstream::ALL_GENERICS) {
|
||||
// create a generic streamer
|
||||
TypeStreamerPointer streamer;
|
||||
if (category == "ENUM") {
|
||||
QVector<NameIntPair> values;
|
||||
|
@ -1933,6 +1935,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
static_cast<GenericTypeStreamer*>(streamer.data())->_weakSelf = streamer;
|
||||
continue;
|
||||
}
|
||||
// create a mapped streamer, determining along the way whether it matches our base
|
||||
if (category == "ENUM") {
|
||||
QHash<int, int> mappings;
|
||||
int highestValue = 0;
|
||||
|
@ -1949,6 +1952,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
}
|
||||
matches &= (value == mapping);
|
||||
}
|
||||
// if everything matches our built-in enum, we can use that, which will be faster
|
||||
if (matches) {
|
||||
_typeStreamers.insert(name, baseStreamer->getSelf());
|
||||
} else {
|
||||
|
@ -1967,6 +1971,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
fields.append(StreamerIndexPair(streamer, index));
|
||||
matches &= (index == i && streamer == metaFields.at(i).getStreamer());
|
||||
}
|
||||
// if everything matches our built-in streamable, we can use that, which will be faster
|
||||
if (matches) {
|
||||
_typeStreamers.insert(name, baseStreamer->getSelf());
|
||||
} else {
|
||||
|
@ -2001,6 +2006,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
}
|
||||
}
|
||||
|
||||
// create and map the object streamers in order
|
||||
foreach (const QJsonValue& element, top.value("classes").toArray()) {
|
||||
QJsonObject clazz = element.toObject();
|
||||
QString name = clazz.value("name").toString();
|
||||
|
@ -2008,9 +2014,10 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
const ObjectStreamer* baseStreamer = Bitstream::getObjectStreamers().value(
|
||||
Bitstream::getMetaObjects().value(latinName));
|
||||
if (!baseStreamer && genericsMode == Bitstream::NO_GENERICS) {
|
||||
continue;
|
||||
continue; // no built-in class and no generics allowed; we give up
|
||||
}
|
||||
if (!baseStreamer || genericsMode == Bitstream::ALL_GENERICS) {
|
||||
// create a generic streamer
|
||||
QVector<StreamerNamePair> properties;
|
||||
foreach (const QJsonValue& property, clazz.value("properties").toArray()) {
|
||||
QJsonObject object = property.toObject();
|
||||
|
@ -2023,6 +2030,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
static_cast<GenericObjectStreamer*>(streamer.data())->_weakSelf = streamer;
|
||||
continue;
|
||||
}
|
||||
// create a mapped streamer, determining along the way whether it matches our base
|
||||
const QMetaObject* metaObject = baseStreamer->getMetaObject();
|
||||
const QVector<StreamerPropertyPair>& baseProperties = baseStreamer->getProperties();
|
||||
QVector<StreamerPropertyPair> properties;
|
||||
|
@ -2039,6 +2047,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
matches &= (typeStreamer == baseProperty.first &&
|
||||
metaProperty.propertyIndex() == baseProperty.second.propertyIndex());
|
||||
}
|
||||
// if everything matches our built-in type, we can use that directly, which will be faster
|
||||
if (matches) {
|
||||
_objectStreamers.insert(name, baseStreamer->getSelf());
|
||||
} else {
|
||||
|
@ -2046,6 +2055,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
}
|
||||
}
|
||||
|
||||
// create and map the objects in order
|
||||
foreach (const QJsonValue& element, top.value("objects").toArray()) {
|
||||
QJsonObject object = element.toObject();
|
||||
int id = object.value("id").toInt();
|
||||
|
@ -2056,6 +2066,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
|
|||
}
|
||||
}
|
||||
|
||||
// prepare the contents for extraction
|
||||
_contents = top.value("contents").toArray();
|
||||
_contentsIterator = _contents.constBegin();
|
||||
}
|
||||
|
|
|
@ -205,6 +205,36 @@ template<class K, class P, class V> inline RepeatedValueStreamer<K, P, V>&
|
|||
/// version-resilient persistence, the class provides a metadata system that maps stored types to local types (or to
|
||||
/// generic containers), allowing one to add and remove fields to classes without breaking compatibility with previously
|
||||
/// stored data.
|
||||
///
|
||||
/// The basic usage requires one to create a Bitstream that wraps an underlying QDataStream, specifying the metadata type
|
||||
/// desired and (for readers) the generics mode. Then, one uses the << or >> operators to write or read values to/from
|
||||
/// the stream (a stream instance may be used for reading or writing, but not both). For write streams, the flush
|
||||
/// function should be called on completion to write any partial data.
|
||||
///
|
||||
/// Polymorphic types are supported via the QVariant and QObject*/SharedObjectPointer types. When you write a QVariant or
|
||||
/// QObject, the type or class name (at minimum) is written to the stream. When you read a QVariant or QObject, the default
|
||||
/// behavior is to look for a corresponding registered type with the written name. With hash metadata, Bitstream can verify
|
||||
/// that the local type matches the stream type, throwing the streamed version away if not. With full metadata, Bitstream can
|
||||
/// create a mapping from the streamed type to the local type that applies the intersection of the two types' fields.
|
||||
///
|
||||
/// To register types for streaming, select from the provided templates and macros. To register a QObject (or SharedObject)
|
||||
/// subclass, use REGISTER_META_OBJECT in the class's source file. To register a streamable class for use in QVariant, use
|
||||
/// the STREAMABLE/STREAM/DECLARE_STREAMABLE_METATYPE macros and use the mtc tool to generate the associated implementation
|
||||
/// code. To register a QObject enum for use outside the QObject's direct properties, use the
|
||||
/// DECLARE_ENUM_METATYPE/IMPLEMENT_ENUM_METATYPE macro pair. To register a collection type (QList, QVector, QSet, QMap) of
|
||||
/// streamable types, use the registerCollectionMetaType template function.
|
||||
///
|
||||
/// Delta-streaming is supported through the writeDelta/readDelta functions (analogous to <</>>), which accept a reference
|
||||
/// value and stream only the information necessary to turn the reference into the target value. This assumes that the
|
||||
/// reference value provided when reading is identical to the one used when writing.
|
||||
///
|
||||
/// Special delta handling is provided for objects tracked by SharedObjectPointers. SharedObjects have IDs (representing their
|
||||
/// unique identity on one system) as well as origin IDs (representing their identity as preserved over the course of
|
||||
/// mutation). Once a shared object with a given ID is written (and its mapping persisted), that object's state will not be
|
||||
/// written again; only its ID will be sent. However, if an object with a new ID but the same origin ID is written, that
|
||||
/// object's state will be encoded as a delta between the previous object and the new one. So, to transmit delta-encoded
|
||||
/// objects, one should treat each local SharedObject instance as immutable, replacing it when mutated with a cloned instance
|
||||
/// generated by calling SharedObject::clone(true) and applying the desired changes.
|
||||
class Bitstream : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -1001,7 +1031,7 @@ protected:
|
|||
friend class Bitstream;
|
||||
|
||||
const QMetaObject* _metaObject;
|
||||
ObjectStreamerPointer _self;
|
||||
ObjectStreamerPointer _self; ///< set/used for built-in classes (never deleted), to obtain shared pointers
|
||||
};
|
||||
|
||||
/// A streamer that maps to a local class.
|
||||
|
@ -1050,7 +1080,7 @@ private:
|
|||
friend class JSONReader;
|
||||
|
||||
QByteArray _name;
|
||||
WeakObjectStreamerPointer _weakSelf;
|
||||
WeakObjectStreamerPointer _weakSelf; ///< promoted to strong references in GenericSharedObject when reading
|
||||
QVector<StreamerNamePair> _properties;
|
||||
QByteArray _hash;
|
||||
};
|
||||
|
@ -1184,7 +1214,7 @@ protected:
|
|||
friend class Bitstream;
|
||||
|
||||
int _type;
|
||||
TypeStreamerPointer _self;
|
||||
TypeStreamerPointer _self; ///< set/used for built-in types (never deleted), to obtain shared pointers
|
||||
};
|
||||
|
||||
QDebug& operator<<(QDebug& debug, const TypeStreamer* typeStreamer);
|
||||
|
@ -1278,7 +1308,7 @@ protected:
|
|||
friend class JSONReader;
|
||||
|
||||
QByteArray _name;
|
||||
WeakTypeStreamerPointer _weakSelf;
|
||||
WeakTypeStreamerPointer _weakSelf; ///< promoted to strong references in GenericValue when reading
|
||||
};
|
||||
|
||||
/// A streamer for generic enums.
|
||||
|
|
Loading…
Reference in a new issue