mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
More object streaming refactory.
This commit is contained in:
parent
b4bd774789
commit
9e151001e0
2 changed files with 216 additions and 305 deletions
|
@ -124,7 +124,7 @@ Bitstream::Bitstream(QDataStream& underlying, MetadataType metadataType, Generic
|
|||
_position(0),
|
||||
_metadataType(metadataType),
|
||||
_genericsMode(genericsMode),
|
||||
_metaObjectStreamer(*this),
|
||||
_objectStreamerStreamer(*this),
|
||||
_typeStreamerStreamer(*this),
|
||||
_attributeStreamer(*this),
|
||||
_scriptStringStreamer(*this),
|
||||
|
@ -198,7 +198,7 @@ void Bitstream::reset() {
|
|||
}
|
||||
|
||||
Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() {
|
||||
WriteMappings mappings = { _metaObjectStreamer.getAndResetTransientOffsets(),
|
||||
WriteMappings mappings = { _objectStreamerStreamer.getAndResetTransientOffsets(),
|
||||
_typeStreamerStreamer.getAndResetTransientOffsets(),
|
||||
_attributeStreamer.getAndResetTransientOffsets(),
|
||||
_scriptStringStreamer.getAndResetTransientOffsets(),
|
||||
|
@ -207,7 +207,7 @@ Bitstream::WriteMappings Bitstream::getAndResetWriteMappings() {
|
|||
}
|
||||
|
||||
void Bitstream::persistWriteMappings(const WriteMappings& mappings) {
|
||||
_metaObjectStreamer.persistTransientOffsets(mappings.metaObjectOffsets);
|
||||
_objectStreamerStreamer.persistTransientOffsets(mappings.objectStreamerOffsets);
|
||||
_typeStreamerStreamer.persistTransientOffsets(mappings.typeStreamerOffsets);
|
||||
_attributeStreamer.persistTransientOffsets(mappings.attributeOffsets);
|
||||
_scriptStringStreamer.persistTransientOffsets(mappings.scriptStringOffsets);
|
||||
|
@ -235,7 +235,7 @@ void Bitstream::persistAndResetWriteMappings() {
|
|||
}
|
||||
|
||||
Bitstream::ReadMappings Bitstream::getAndResetReadMappings() {
|
||||
ReadMappings mappings = { _metaObjectStreamer.getAndResetTransientValues(),
|
||||
ReadMappings mappings = { _objectStreamerStreamer.getAndResetTransientValues(),
|
||||
_typeStreamerStreamer.getAndResetTransientValues(),
|
||||
_attributeStreamer.getAndResetTransientValues(),
|
||||
_scriptStringStreamer.getAndResetTransientValues(),
|
||||
|
@ -244,7 +244,7 @@ Bitstream::ReadMappings Bitstream::getAndResetReadMappings() {
|
|||
}
|
||||
|
||||
void Bitstream::persistReadMappings(const ReadMappings& mappings) {
|
||||
_metaObjectStreamer.persistTransientValues(mappings.metaObjectValues);
|
||||
_objectStreamerStreamer.persistTransientValues(mappings.objectStreamerValues);
|
||||
_typeStreamerStreamer.persistTransientValues(mappings.typeStreamerValues);
|
||||
_attributeStreamer.persistTransientValues(mappings.attributeValues);
|
||||
_scriptStringStreamer.persistTransientValues(mappings.scriptStringValues);
|
||||
|
@ -310,20 +310,20 @@ void Bitstream::readRawDelta(QVariant& value, const QVariant& reference) {
|
|||
|
||||
void Bitstream::writeRawDelta(const QObject* value, const QObject* reference) {
|
||||
if (!value) {
|
||||
_metaObjectStreamer << NULL;
|
||||
_objectStreamerStreamer << NULL;
|
||||
return;
|
||||
}
|
||||
const QMetaObject* metaObject = value->metaObject();
|
||||
_metaObjectStreamer << metaObject;
|
||||
foreach (const PropertyWriter& propertyWriter, getPropertyWriters().value(metaObject)) {
|
||||
propertyWriter.writeDelta(*this, value, reference);
|
||||
}
|
||||
const ObjectStreamer* streamer = (metaObject == &GenericSharedObject::staticMetaObject) ?
|
||||
static_cast<const GenericSharedObject*>(value)->getStreamer().data() : getObjectStreamers().value(metaObject);
|
||||
_objectStreamerStreamer << streamer;
|
||||
streamer->writeRawDelta(*this, value, reference);
|
||||
}
|
||||
|
||||
void Bitstream::readRawDelta(QObject*& value, const QObject* reference) {
|
||||
ObjectReader objectReader;
|
||||
_metaObjectStreamer >> objectReader;
|
||||
value = objectReader.readDelta(*this, reference);
|
||||
ObjectStreamerPointer streamer;
|
||||
_objectStreamerStreamer >> streamer;
|
||||
value = streamer ? streamer->readRawDelta(*this, reference) : NULL;
|
||||
}
|
||||
|
||||
void Bitstream::writeRawDelta(const QScriptValue& value, const QScriptValue& reference) {
|
||||
|
@ -814,38 +814,50 @@ Bitstream& Bitstream::operator>>(GenericValue& value) {
|
|||
|
||||
Bitstream& Bitstream::operator<<(const QObject* object) {
|
||||
if (!object) {
|
||||
_metaObjectStreamer << NULL;
|
||||
_objectStreamerStreamer << NULL;
|
||||
return *this;
|
||||
}
|
||||
const QMetaObject* metaObject = object->metaObject();
|
||||
_metaObjectStreamer << metaObject;
|
||||
foreach (const PropertyWriter& propertyWriter, getPropertyWriters().value(metaObject)) {
|
||||
propertyWriter.write(*this, object);
|
||||
}
|
||||
const ObjectStreamer* streamer = (metaObject == &GenericSharedObject::staticMetaObject) ?
|
||||
static_cast<const GenericSharedObject*>(object)->getStreamer().data() : getObjectStreamers().value(metaObject);
|
||||
_objectStreamerStreamer << streamer;
|
||||
streamer->write(*this, object);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(QObject*& object) {
|
||||
ObjectReader objectReader;
|
||||
_metaObjectStreamer >> objectReader;
|
||||
object = objectReader.read(*this);
|
||||
ObjectStreamerPointer streamer;
|
||||
_objectStreamerStreamer >> streamer;
|
||||
object = streamer ? streamer->read(*this) : NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<<(const QMetaObject* metaObject) {
|
||||
_metaObjectStreamer << metaObject;
|
||||
_objectStreamerStreamer << getObjectStreamers().value(metaObject);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(const QMetaObject*& metaObject) {
|
||||
ObjectReader objectReader;
|
||||
_metaObjectStreamer >> objectReader;
|
||||
metaObject = objectReader.getMetaObject();
|
||||
ObjectStreamerPointer streamer;
|
||||
_objectStreamerStreamer >> streamer;
|
||||
metaObject = streamer->getMetaObject();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(ObjectReader& objectReader) {
|
||||
_metaObjectStreamer >> objectReader;
|
||||
Bitstream& Bitstream::operator<<(const ObjectStreamer* streamer) {
|
||||
_objectStreamerStreamer << streamer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(const ObjectStreamer*& streamer) {
|
||||
ObjectStreamerPointer objectStreamer;
|
||||
_objectStreamerStreamer >> objectStreamer;
|
||||
streamer = objectStreamer.data();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>>(ObjectStreamerPointer& streamer) {
|
||||
_objectStreamerStreamer >> streamer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1075,55 +1087,53 @@ Bitstream& Bitstream::operator>>(SharedObjectPointer& object) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator<(const QMetaObject* metaObject) {
|
||||
if (!metaObject) {
|
||||
Bitstream& Bitstream::operator<(const ObjectStreamer* streamer) {
|
||||
if (!streamer) {
|
||||
return *this << QByteArray();
|
||||
}
|
||||
*this << QByteArray::fromRawData(metaObject->className(), strlen(metaObject->className()));
|
||||
if (_metadataType == NO_METADATA) {
|
||||
return *this;
|
||||
}
|
||||
const PropertyWriterVector& propertyWriters = getPropertyWriters().value(metaObject);
|
||||
*this << propertyWriters.size();
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
foreach (const PropertyWriter& propertyWriter, propertyWriters) {
|
||||
_typeStreamerStreamer << propertyWriter.getStreamer();
|
||||
const QMetaProperty& property = propertyWriter.getProperty();
|
||||
if (_metadataType == FULL_METADATA) {
|
||||
*this << QByteArray::fromRawData(property.name(), strlen(property.name()));
|
||||
} else {
|
||||
hash.addData(property.name(), strlen(property.name()) + 1);
|
||||
}
|
||||
}
|
||||
if (_metadataType == HASH_METADATA) {
|
||||
QByteArray hashResult = hash.result();
|
||||
write(hashResult.constData(), hashResult.size() * BITS_IN_BYTE);
|
||||
const char* name = streamer->getName();
|
||||
*this << QByteArray::fromRawData(name, strlen(name));
|
||||
if (_metadataType != NO_METADATA) {
|
||||
streamer->writeMetadata(*this, _metadataType == FULL_METADATA);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>(ObjectReader& objectReader) {
|
||||
Bitstream& Bitstream::operator>(ObjectStreamerPointer& streamer) {
|
||||
QByteArray className;
|
||||
*this >> className;
|
||||
if (className.isEmpty()) {
|
||||
objectReader = ObjectReader();
|
||||
streamer = ObjectStreamerPointer();
|
||||
return *this;
|
||||
}
|
||||
const QMetaObject* metaObject = _metaObjectSubstitutions.value(className);
|
||||
if (!metaObject) {
|
||||
metaObject = getMetaObjects().value(className);
|
||||
}
|
||||
if (!metaObject) {
|
||||
qWarning() << "Unknown class name: " << className << "\n";
|
||||
// start out with the streamer for the named class, if any
|
||||
if (metaObject) {
|
||||
streamer = getObjectStreamers().value(metaObject)->getSelf();
|
||||
} else {
|
||||
streamer = ObjectStreamerPointer();
|
||||
}
|
||||
if (_metadataType == NO_METADATA) {
|
||||
objectReader = ObjectReader(className, metaObject, getPropertyReaders().value(metaObject));
|
||||
if (!metaObject) {
|
||||
qWarning() << "Unknown class name:" << className;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
int storedPropertyCount;
|
||||
*this >> storedPropertyCount;
|
||||
PropertyReaderVector properties(storedPropertyCount);
|
||||
for (int i = 0; i < storedPropertyCount; i++) {
|
||||
if (_genericsMode == ALL_GENERICS) {
|
||||
streamer = readGenericObjectStreamer(className);
|
||||
return *this;
|
||||
}
|
||||
if (!metaObject && _genericsMode == FALLBACK_GENERICS) {
|
||||
streamer = readGenericObjectStreamer(className);
|
||||
return *this;
|
||||
}
|
||||
int propertyCount;
|
||||
*this >> propertyCount;
|
||||
QVector<StreamerPropertyPair> properties(propertyCount);
|
||||
for (int i = 0; i < propertyCount; i++) {
|
||||
TypeStreamerPointer typeStreamer;
|
||||
*this >> typeStreamer;
|
||||
QMetaProperty property = QMetaProperty();
|
||||
|
@ -1134,23 +1144,22 @@ Bitstream& Bitstream::operator>(ObjectReader& objectReader) {
|
|||
property = metaObject->property(metaObject->indexOfProperty(propertyName));
|
||||
}
|
||||
}
|
||||
properties[i] = PropertyReader(typeStreamer, property);
|
||||
properties[i] = StreamerPropertyPair(typeStreamer, property);
|
||||
}
|
||||
// for hash metadata, check the names/types of the properties as well as the name hash against our own class
|
||||
if (_metadataType == HASH_METADATA) {
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
bool matches = true;
|
||||
if (metaObject) {
|
||||
const PropertyWriterVector& propertyWriters = getPropertyWriters().value(metaObject);
|
||||
if (propertyWriters.size() == properties.size()) {
|
||||
for (int i = 0; i < propertyWriters.size(); i++) {
|
||||
const PropertyWriter& propertyWriter = propertyWriters.at(i);
|
||||
if (properties.at(i).getStreamer() != propertyWriter.getStreamer()) {
|
||||
const QVector<StreamerPropertyPair>& localProperties = streamer->getProperties();
|
||||
if (localProperties.size() == properties.size()) {
|
||||
for (int i = 0; i < localProperties.size(); i++) {
|
||||
const StreamerPropertyPair& localProperty = localProperties.at(i);
|
||||
if (localProperty.first != properties.at(i).first) {
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
const QMetaProperty& property = propertyWriter.getProperty();
|
||||
hash.addData(property.name(), strlen(property.name()) + 1);
|
||||
hash.addData(localProperty.second.name(), strlen(localProperty.second.name()) + 1);
|
||||
}
|
||||
} else {
|
||||
matches = false;
|
||||
|
@ -1160,11 +1169,24 @@ Bitstream& Bitstream::operator>(ObjectReader& objectReader) {
|
|||
QByteArray remoteHashResult(localHashResult.size(), 0);
|
||||
read(remoteHashResult.data(), remoteHashResult.size() * BITS_IN_BYTE);
|
||||
if (metaObject && matches && localHashResult == remoteHashResult) {
|
||||
objectReader = ObjectReader(className, metaObject, getPropertyReaders().value(metaObject));
|
||||
return *this;
|
||||
}
|
||||
} else if (metaObject) {
|
||||
const QVector<StreamerPropertyPair>& localProperties = streamer->getProperties();
|
||||
if (localProperties.size() != properties.size()) {
|
||||
streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
|
||||
return *this;
|
||||
}
|
||||
for (int i = 0; i < localProperties.size(); i++) {
|
||||
const StreamerPropertyPair& property = properties.at(i);
|
||||
if (localProperties.at(i).first != property.first || property.second.propertyIndex() != i) {
|
||||
streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
objectReader = ObjectReader(className, metaObject, properties);
|
||||
streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1405,12 +1427,12 @@ Bitstream& Bitstream::operator>(SharedObjectPointer& object) {
|
|||
QPointer<SharedObject> reference = _sharedObjectReferences.value(originID);
|
||||
QPointer<SharedObject>& pointer = _weakSharedObjectHash[id];
|
||||
if (pointer) {
|
||||
ObjectReader objectReader;
|
||||
_metaObjectStreamer >> objectReader;
|
||||
ObjectStreamerPointer objectStreamer;
|
||||
_objectStreamerStreamer >> objectStreamer;
|
||||
if (reference) {
|
||||
objectReader.readDelta(*this, reference.data(), pointer.data());
|
||||
objectStreamer->readRawDelta(*this, reference.data(), pointer.data());
|
||||
} else {
|
||||
objectReader.read(*this, pointer.data());
|
||||
objectStreamer->read(*this, pointer.data());
|
||||
}
|
||||
} else {
|
||||
QObject* rawObject;
|
||||
|
@ -1445,6 +1467,31 @@ void Bitstream::clearSharedObject(QObject* object) {
|
|||
|
||||
const int MD5_HASH_SIZE = 16;
|
||||
|
||||
ObjectStreamerPointer Bitstream::readGenericObjectStreamer(const QByteArray& name) {
|
||||
int propertyCount;
|
||||
*this >> propertyCount;
|
||||
QVector<StreamerNamePair> properties(propertyCount);
|
||||
QByteArray hash;
|
||||
if (propertyCount > 0) {
|
||||
for (int i = 0; i < propertyCount; i++) {
|
||||
TypeStreamerPointer streamer;
|
||||
*this >> streamer;
|
||||
QByteArray name;
|
||||
if (_metadataType == FULL_METADATA) {
|
||||
*this >> name;
|
||||
}
|
||||
properties[i] = StreamerNamePair(streamer, name);
|
||||
}
|
||||
if (_metadataType == HASH_METADATA) {
|
||||
hash.resize(MD5_HASH_SIZE);
|
||||
read(hash.data(), hash.size() * BITS_IN_BYTE);
|
||||
}
|
||||
}
|
||||
ObjectStreamerPointer streamer = ObjectStreamerPointer(new GenericObjectStreamer(name, properties, hash));
|
||||
static_cast<GenericObjectStreamer*>(streamer.data())->_weakSelf = streamer;
|
||||
return streamer;
|
||||
}
|
||||
|
||||
TypeStreamerPointer Bitstream::readGenericTypeStreamer(const QByteArray& name, int category) {
|
||||
TypeStreamerPointer streamer;
|
||||
switch (category) {
|
||||
|
@ -1528,6 +1575,40 @@ QMultiHash<const QMetaObject*, const QMetaObject*>& Bitstream::getMetaObjectSubC
|
|||
return metaObjectSubClasses;
|
||||
}
|
||||
|
||||
const QHash<const QMetaObject*, const ObjectStreamer*>& Bitstream::getObjectStreamers() {
|
||||
static QHash<const QMetaObject*, const ObjectStreamer*> objectStreamers = createObjectStreamers();
|
||||
return objectStreamers;
|
||||
}
|
||||
|
||||
QHash<const QMetaObject*, const ObjectStreamer*> Bitstream::createObjectStreamers() {
|
||||
QHash<const QMetaObject*, const ObjectStreamer*> objectStreamers;
|
||||
foreach (const QMetaObject* metaObject, getMetaObjects()) {
|
||||
QVector<StreamerPropertyPair> properties;
|
||||
for (int i = 0; i < metaObject->propertyCount(); i++) {
|
||||
QMetaProperty property = metaObject->property(i);
|
||||
if (!property.isStored()) {
|
||||
continue;
|
||||
}
|
||||
const TypeStreamer* streamer;
|
||||
if (property.isEnumType()) {
|
||||
QMetaEnum metaEnum = property.enumerator();
|
||||
streamer = getEnumStreamers().value(ScopeNamePair(
|
||||
QByteArray::fromRawData(metaEnum.scope(), strlen(metaEnum.scope())),
|
||||
QByteArray::fromRawData(metaEnum.name(), strlen(metaEnum.name()))));
|
||||
} else {
|
||||
streamer = getTypeStreamers().value(property.userType());
|
||||
}
|
||||
if (streamer) {
|
||||
properties.append(StreamerPropertyPair(streamer->getSelf(), property));
|
||||
}
|
||||
}
|
||||
ObjectStreamerPointer streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
|
||||
streamer->_self = streamer;
|
||||
objectStreamers.insert(metaObject, streamer.data());
|
||||
}
|
||||
return objectStreamers;
|
||||
}
|
||||
|
||||
QHash<int, const TypeStreamer*>& Bitstream::getTypeStreamers() {
|
||||
static QHash<int, const TypeStreamer*> typeStreamers;
|
||||
return typeStreamers;
|
||||
|
@ -1577,69 +1658,17 @@ const TypeStreamer* Bitstream::createInvalidTypeStreamer() {
|
|||
return streamer;
|
||||
}
|
||||
|
||||
const QHash<const QMetaObject*, PropertyReaderVector>& Bitstream::getPropertyReaders() {
|
||||
static QHash<const QMetaObject*, PropertyReaderVector> propertyReaders = createPropertyReaders();
|
||||
return propertyReaders;
|
||||
ObjectStreamer::ObjectStreamer(const QMetaObject* metaObject) :
|
||||
_metaObject(metaObject) {
|
||||
}
|
||||
|
||||
QHash<const QMetaObject*, PropertyReaderVector> Bitstream::createPropertyReaders() {
|
||||
QHash<const QMetaObject*, PropertyReaderVector> propertyReaders;
|
||||
foreach (const QMetaObject* metaObject, getMetaObjects()) {
|
||||
PropertyReaderVector& readers = propertyReaders[metaObject];
|
||||
for (int i = 0; i < metaObject->propertyCount(); i++) {
|
||||
QMetaProperty property = metaObject->property(i);
|
||||
if (!property.isStored()) {
|
||||
continue;
|
||||
}
|
||||
const TypeStreamer* streamer;
|
||||
if (property.isEnumType()) {
|
||||
QMetaEnum metaEnum = property.enumerator();
|
||||
streamer = getEnumStreamers().value(ScopeNamePair(
|
||||
QByteArray::fromRawData(metaEnum.scope(), strlen(metaEnum.scope())),
|
||||
QByteArray::fromRawData(metaEnum.name(), strlen(metaEnum.name()))));
|
||||
} else {
|
||||
streamer = getTypeStreamers().value(property.userType());
|
||||
}
|
||||
if (streamer) {
|
||||
readers.append(PropertyReader(streamer->getSelf(), property));
|
||||
}
|
||||
}
|
||||
}
|
||||
return propertyReaders;
|
||||
const QVector<StreamerPropertyPair>& ObjectStreamer::getProperties() const {
|
||||
static QVector<StreamerPropertyPair> emptyProperties;
|
||||
return emptyProperties;
|
||||
}
|
||||
|
||||
const QHash<const QMetaObject*, PropertyWriterVector>& Bitstream::getPropertyWriters() {
|
||||
static QHash<const QMetaObject*, PropertyWriterVector> propertyWriters = createPropertyWriters();
|
||||
return propertyWriters;
|
||||
}
|
||||
|
||||
QHash<const QMetaObject*, PropertyWriterVector> Bitstream::createPropertyWriters() {
|
||||
QHash<const QMetaObject*, PropertyWriterVector> propertyWriters;
|
||||
foreach (const QMetaObject* metaObject, getMetaObjects()) {
|
||||
PropertyWriterVector& writers = propertyWriters[metaObject];
|
||||
for (int i = 0; i < metaObject->propertyCount(); i++) {
|
||||
QMetaProperty property = metaObject->property(i);
|
||||
if (!property.isStored()) {
|
||||
continue;
|
||||
}
|
||||
const TypeStreamer* streamer;
|
||||
if (property.isEnumType()) {
|
||||
QMetaEnum metaEnum = property.enumerator();
|
||||
streamer = getEnumStreamers().value(ScopeNamePair(
|
||||
QByteArray::fromRawData(metaEnum.scope(), strlen(metaEnum.scope())),
|
||||
QByteArray::fromRawData(metaEnum.name(), strlen(metaEnum.name()))));
|
||||
} else {
|
||||
streamer = getTypeStreamers().value(property.userType());
|
||||
}
|
||||
if (streamer) {
|
||||
writers.append(PropertyWriter(property, streamer));
|
||||
}
|
||||
}
|
||||
}
|
||||
return propertyWriters;
|
||||
}
|
||||
|
||||
MappedObjectStreamer::MappedObjectStreamer(const QVector<StreamerPropertyPair>& properties) :
|
||||
MappedObjectStreamer::MappedObjectStreamer(const QMetaObject* metaObject, const QVector<StreamerPropertyPair>& properties) :
|
||||
ObjectStreamer(metaObject),
|
||||
_properties(properties) {
|
||||
}
|
||||
|
||||
|
@ -1647,6 +1676,10 @@ const char* MappedObjectStreamer::getName() const {
|
|||
return _metaObject->className();
|
||||
}
|
||||
|
||||
const QVector<StreamerPropertyPair>& MappedObjectStreamer::getProperties() const {
|
||||
return _properties;
|
||||
}
|
||||
|
||||
void MappedObjectStreamer::writeMetadata(Bitstream& out, bool full) const {
|
||||
out << _properties.size();
|
||||
if (_properties.isEmpty()) {
|
||||
|
@ -1667,13 +1700,13 @@ void MappedObjectStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
}
|
||||
}
|
||||
|
||||
void MappedObjectStreamer::write(Bitstream& out, QObject* object) const {
|
||||
void MappedObjectStreamer::write(Bitstream& out, const QObject* object) const {
|
||||
foreach (const StreamerPropertyPair& property, _properties) {
|
||||
property.first->write(out, property.second.read(object));
|
||||
}
|
||||
}
|
||||
|
||||
void MappedObjectStreamer::writeDelta(Bitstream& out, QObject* object, QObject* reference) const {
|
||||
void MappedObjectStreamer::writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const {
|
||||
foreach (const StreamerPropertyPair& property, _properties) {
|
||||
property.first->writeDelta(out, property.second.read(object), (reference && reference->metaObject() == _metaObject) ?
|
||||
property.second.read(reference) : QVariant());
|
||||
|
@ -1693,14 +1726,14 @@ QObject* MappedObjectStreamer::read(Bitstream& in, QObject* object) const {
|
|||
return object;
|
||||
}
|
||||
|
||||
QObject* MappedObjectStreamer::readDelta(Bitstream& in, const QObject* reference, QObject* object) const {
|
||||
QObject* MappedObjectStreamer::readRawDelta(Bitstream& in, const QObject* reference, QObject* object) const {
|
||||
if (!object && _metaObject) {
|
||||
object = _metaObject->newInstance();
|
||||
}
|
||||
foreach (const StreamerPropertyPair& property, _properties) {
|
||||
QVariant value;
|
||||
property.first->readDelta(in, value, (property.second.isValid() && reference) ?
|
||||
property.second.read(reference) : QVariant());
|
||||
property.first->readDelta(in, value, (property.second.isValid() && reference &&
|
||||
reference->metaObject() == _metaObject) ? property.second.read(reference) : QVariant());
|
||||
if (property.second.isValid() && object) {
|
||||
property.second.write(object, value);
|
||||
}
|
||||
|
@ -1710,11 +1743,10 @@ QObject* MappedObjectStreamer::readDelta(Bitstream& in, const QObject* reference
|
|||
|
||||
GenericObjectStreamer::GenericObjectStreamer(const QByteArray& name, const QVector<StreamerNamePair>& properties,
|
||||
const QByteArray& hash) :
|
||||
ObjectStreamer(&GenericSharedObject::staticMetaObject),
|
||||
_name(name),
|
||||
_properties(properties),
|
||||
_hash(hash) {
|
||||
|
||||
_metaObject = &GenericSharedObject::staticMetaObject;
|
||||
}
|
||||
|
||||
const char* GenericObjectStreamer::getName() const {
|
||||
|
@ -1744,17 +1776,22 @@ void GenericObjectStreamer::writeMetadata(Bitstream& out, bool full) const {
|
|||
}
|
||||
}
|
||||
|
||||
void GenericObjectStreamer::write(Bitstream& out, QObject* object) const {
|
||||
const QVariantList& values = static_cast<GenericSharedObject*>(object)->getValues();
|
||||
void GenericObjectStreamer::write(Bitstream& out, const QObject* object) const {
|
||||
const QVariantList& values = static_cast<const GenericSharedObject*>(object)->getValues();
|
||||
for (int i = 0; i < _properties.size(); i++) {
|
||||
_properties.at(i).first->write(out, values.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
void GenericObjectStreamer::writeDelta(Bitstream& out, QObject* object, QObject* reference) const {
|
||||
void GenericObjectStreamer::writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const {
|
||||
const GenericSharedObject* genericObject = static_cast<const GenericSharedObject*>(object);
|
||||
const GenericSharedObject* genericReference = (reference &&
|
||||
reference->metaObject() == &GenericSharedObject::staticMetaObject) ?
|
||||
static_cast<const GenericSharedObject*>(reference) : NULL;
|
||||
for (int i = 0; i < _properties.size(); i++) {
|
||||
_properties.at(i).first->writeDelta(out, static_cast<GenericSharedObject*>(object)->getValues().at(i), reference ?
|
||||
static_cast<GenericSharedObject*>(reference)->getValues().at(i) : QVariant());
|
||||
_properties.at(i).first->writeDelta(out, genericObject->getValues().at(i),
|
||||
(genericReference && genericReference->getStreamer() == genericObject->getStreamer()) ?
|
||||
genericReference->getValues().at(i) : QVariant());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1770,7 +1807,7 @@ QObject* GenericObjectStreamer::read(Bitstream& in, QObject* object) const {
|
|||
return object;
|
||||
}
|
||||
|
||||
QObject* GenericObjectStreamer::readDelta(Bitstream& in, const QObject* reference, QObject* object) const {
|
||||
QObject* GenericObjectStreamer::readRawDelta(Bitstream& in, const QObject* reference, QObject* object) const {
|
||||
if (!object) {
|
||||
object = new GenericSharedObject(_weakSelf);
|
||||
}
|
||||
|
@ -1786,75 +1823,6 @@ QObject* GenericObjectStreamer::readDelta(Bitstream& in, const QObject* referenc
|
|||
return object;
|
||||
}
|
||||
|
||||
ObjectReader::ObjectReader(const QByteArray& className, const QMetaObject* metaObject,
|
||||
const PropertyReaderVector& properties) :
|
||||
_className(className),
|
||||
_metaObject(metaObject),
|
||||
_properties(properties) {
|
||||
}
|
||||
|
||||
QObject* ObjectReader::read(Bitstream& in, QObject* object) const {
|
||||
if (!object && _metaObject) {
|
||||
object = _metaObject->newInstance();
|
||||
}
|
||||
foreach (const PropertyReader& property, _properties) {
|
||||
property.read(in, object);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
QObject* ObjectReader::readDelta(Bitstream& in, const QObject* reference, QObject* object) const {
|
||||
if (!object && _metaObject) {
|
||||
object = _metaObject->newInstance();
|
||||
}
|
||||
foreach (const PropertyReader& property, _properties) {
|
||||
property.readDelta(in, object, reference);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
uint qHash(const ObjectReader& objectReader, uint seed) {
|
||||
return qHash(objectReader.getClassName(), seed);
|
||||
}
|
||||
|
||||
QDebug& operator<<(QDebug& debug, const ObjectReader& objectReader) {
|
||||
return debug << objectReader.getClassName();
|
||||
}
|
||||
|
||||
PropertyReader::PropertyReader(const TypeStreamerPointer& streamer, const QMetaProperty& property) :
|
||||
_streamer(streamer),
|
||||
_property(property) {
|
||||
}
|
||||
|
||||
void PropertyReader::read(Bitstream& in, QObject* object) const {
|
||||
QVariant value = _streamer->read(in);
|
||||
if (_property.isValid() && object) {
|
||||
_property.write(object, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyReader::readDelta(Bitstream& in, QObject* object, const QObject* reference) const {
|
||||
QVariant value;
|
||||
_streamer->readDelta(in, value, (_property.isValid() && reference) ? _property.read(reference) : QVariant());
|
||||
if (_property.isValid() && object) {
|
||||
_property.write(object, value);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyWriter::PropertyWriter(const QMetaProperty& property, const TypeStreamer* streamer) :
|
||||
_property(property),
|
||||
_streamer(streamer) {
|
||||
}
|
||||
|
||||
void PropertyWriter::write(Bitstream& out, const QObject* object) const {
|
||||
_streamer->write(out, _property.read(object));
|
||||
}
|
||||
|
||||
void PropertyWriter::writeDelta(Bitstream& out, const QObject* object, const QObject* reference) const {
|
||||
_streamer->writeDelta(out, _property.read(object), reference && object->metaObject() == reference->metaObject() ?
|
||||
_property.read(reference) : QVariant());
|
||||
}
|
||||
|
||||
MetaField::MetaField(const QByteArray& name, const TypeStreamer* streamer) :
|
||||
_name(name),
|
||||
_streamer(streamer) {
|
||||
|
|
|
@ -39,8 +39,6 @@ class GenericValue;
|
|||
class ObjectReader;
|
||||
class ObjectStreamer;
|
||||
class OwnedAttributeValue;
|
||||
class PropertyReader;
|
||||
class PropertyWriter;
|
||||
class TypeStreamer;
|
||||
|
||||
typedef SharedObjectPointerTemplate<Attribute> AttributePointer;
|
||||
|
@ -51,8 +49,6 @@ typedef QSharedPointer<ObjectStreamer> ObjectStreamerPointer;
|
|||
typedef QWeakPointer<ObjectStreamer> WeakObjectStreamerPointer;
|
||||
typedef QSharedPointer<TypeStreamer> TypeStreamerPointer;
|
||||
typedef QWeakPointer<TypeStreamer> WeakTypeStreamerPointer;
|
||||
typedef QVector<PropertyReader> PropertyReaderVector;
|
||||
typedef QVector<PropertyWriter> PropertyWriterVector;
|
||||
|
||||
typedef QPair<QVariant, QVariant> QVariantPair;
|
||||
typedef QList<QVariantPair> QVariantPairList;
|
||||
|
@ -207,7 +203,7 @@ public:
|
|||
|
||||
class WriteMappings {
|
||||
public:
|
||||
QHash<const QMetaObject*, int> metaObjectOffsets;
|
||||
QHash<const ObjectStreamer*, int> objectStreamerOffsets;
|
||||
QHash<const TypeStreamer*, int> typeStreamerOffsets;
|
||||
QHash<AttributePointer, int> attributeOffsets;
|
||||
QHash<QScriptString, int> scriptStringOffsets;
|
||||
|
@ -216,7 +212,7 @@ public:
|
|||
|
||||
class ReadMappings {
|
||||
public:
|
||||
QHash<int, ObjectReader> metaObjectValues;
|
||||
QHash<int, ObjectStreamerPointer> objectStreamerValues;
|
||||
QHash<int, TypeStreamerPointer> typeStreamerValues;
|
||||
QHash<int, AttributePointer> attributeValues;
|
||||
QHash<int, QScriptString> scriptStringValues;
|
||||
|
@ -403,7 +399,10 @@ public:
|
|||
|
||||
Bitstream& operator<<(const QMetaObject* metaObject);
|
||||
Bitstream& operator>>(const QMetaObject*& metaObject);
|
||||
Bitstream& operator>>(ObjectReader& objectReader);
|
||||
|
||||
Bitstream& operator<<(const ObjectStreamer* streamer);
|
||||
Bitstream& operator>>(const ObjectStreamer*& streamer);
|
||||
Bitstream& operator>>(ObjectStreamerPointer& streamer);
|
||||
|
||||
Bitstream& operator<<(const TypeStreamer* streamer);
|
||||
Bitstream& operator>>(const TypeStreamer*& streamer);
|
||||
|
@ -421,11 +420,11 @@ public:
|
|||
Bitstream& operator<<(const SharedObjectPointer& object);
|
||||
Bitstream& operator>>(SharedObjectPointer& object);
|
||||
|
||||
Bitstream& operator<(const QMetaObject* metaObject);
|
||||
Bitstream& operator>(ObjectReader& objectReader);
|
||||
Bitstream& operator<(const ObjectStreamer* streamer);
|
||||
Bitstream& operator>(ObjectStreamerPointer& streamer);
|
||||
|
||||
Bitstream& operator<(const TypeStreamer* streamer);
|
||||
Bitstream& operator>(TypeStreamerPointer& reader);
|
||||
Bitstream& operator>(TypeStreamerPointer& streamer);
|
||||
|
||||
Bitstream& operator<(const AttributePointer& attribute);
|
||||
Bitstream& operator>(AttributePointer& attribute);
|
||||
|
@ -446,6 +445,7 @@ private slots:
|
|||
|
||||
private:
|
||||
|
||||
ObjectStreamerPointer readGenericObjectStreamer(const QByteArray& name);
|
||||
TypeStreamerPointer readGenericTypeStreamer(const QByteArray& name, int category);
|
||||
|
||||
QDataStream& _underlying;
|
||||
|
@ -455,7 +455,7 @@ private:
|
|||
MetadataType _metadataType;
|
||||
GenericsMode _genericsMode;
|
||||
|
||||
RepeatedValueStreamer<const QMetaObject*, const QMetaObject*, ObjectReader> _metaObjectStreamer;
|
||||
RepeatedValueStreamer<const ObjectStreamer*, const ObjectStreamer*, ObjectStreamerPointer> _objectStreamerStreamer;
|
||||
RepeatedValueStreamer<const TypeStreamer*, const TypeStreamer*, TypeStreamerPointer> _typeStreamerStreamer;
|
||||
RepeatedValueStreamer<AttributePointer> _attributeStreamer;
|
||||
RepeatedValueStreamer<QScriptString> _scriptStringStreamer;
|
||||
|
@ -472,6 +472,9 @@ private:
|
|||
static QMultiHash<const QMetaObject*, const QMetaObject*>& getMetaObjectSubClasses();
|
||||
static QHash<int, const TypeStreamer*>& getTypeStreamers();
|
||||
|
||||
static const QHash<const QMetaObject*, const ObjectStreamer*>& getObjectStreamers();
|
||||
static QHash<const QMetaObject*, const ObjectStreamer*> createObjectStreamers();
|
||||
|
||||
static const QHash<ScopeNamePair, const TypeStreamer*>& getEnumStreamers();
|
||||
static QHash<ScopeNamePair, const TypeStreamer*> createEnumStreamers();
|
||||
|
||||
|
@ -480,12 +483,6 @@ private:
|
|||
|
||||
static const TypeStreamer* getInvalidTypeStreamer();
|
||||
static const TypeStreamer* createInvalidTypeStreamer();
|
||||
|
||||
static const QHash<const QMetaObject*, PropertyReaderVector>& getPropertyReaders();
|
||||
static QHash<const QMetaObject*, PropertyReaderVector> createPropertyReaders();
|
||||
|
||||
static const QHash<const QMetaObject*, PropertyWriterVector>& getPropertyWriters();
|
||||
static QHash<const QMetaObject*, PropertyWriterVector> createPropertyWriters();
|
||||
};
|
||||
|
||||
template<class T> inline void Bitstream::writeDelta(const T& value, const T& reference) {
|
||||
|
@ -769,37 +766,46 @@ template<class K, class V> inline Bitstream& Bitstream::operator>>(QHash<K, V>&
|
|||
return *this;
|
||||
}
|
||||
|
||||
typedef QPair<TypeStreamerPointer, QMetaProperty> StreamerPropertyPair;
|
||||
|
||||
/// Contains the information required to stream an object.
|
||||
class ObjectStreamer {
|
||||
public:
|
||||
|
||||
virtual const char* getName() const = 0;
|
||||
ObjectStreamer(const QMetaObject* metaObject);
|
||||
|
||||
const QMetaObject* getMetaObject() const { return _metaObject; }
|
||||
const ObjectStreamerPointer& getSelf() const { return _self; }
|
||||
|
||||
virtual const char* getName() const = 0;
|
||||
virtual const QVector<StreamerPropertyPair>& getProperties() const;
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const = 0;
|
||||
virtual void write(Bitstream& out, QObject* object) const = 0;
|
||||
virtual void writeDelta(Bitstream& out, QObject* object, QObject* reference) const = 0;
|
||||
virtual void write(Bitstream& out, const QObject* object) const = 0;
|
||||
virtual void writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const = 0;
|
||||
virtual QObject* read(Bitstream& in, QObject* object = NULL) const = 0;
|
||||
virtual QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const = 0;
|
||||
virtual QObject* readRawDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
friend class Bitstream;
|
||||
|
||||
const QMetaObject* _metaObject;
|
||||
ObjectStreamerPointer _self;
|
||||
};
|
||||
|
||||
typedef QPair<TypeStreamerPointer, QMetaProperty> StreamerPropertyPair;
|
||||
|
||||
/// A streamer that maps to a local class.
|
||||
class MappedObjectStreamer : public ObjectStreamer {
|
||||
public:
|
||||
|
||||
MappedObjectStreamer(const QVector<StreamerPropertyPair>& properties);
|
||||
MappedObjectStreamer(const QMetaObject* metaObject, const QVector<StreamerPropertyPair>& properties);
|
||||
|
||||
virtual const char* getName() const;
|
||||
virtual const QVector<StreamerPropertyPair>& getProperties() const;
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual void write(Bitstream& out, QObject* object) const;
|
||||
virtual void writeDelta(Bitstream& out, QObject* object, QObject* reference) const;
|
||||
virtual void write(Bitstream& out, const QObject* object) const;
|
||||
virtual void writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const;
|
||||
virtual QObject* read(Bitstream& in, QObject* object = NULL) const;
|
||||
virtual QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const;
|
||||
virtual QObject* readRawDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -816,10 +822,10 @@ public:
|
|||
|
||||
virtual const char* getName() const;
|
||||
virtual void writeMetadata(Bitstream& out, bool full) const;
|
||||
virtual void write(Bitstream& out, QObject* object) const;
|
||||
virtual void writeDelta(Bitstream& out, QObject* object, QObject* reference) const;
|
||||
virtual void write(Bitstream& out, const QObject* object) const;
|
||||
virtual void writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const;
|
||||
virtual QObject* read(Bitstream& in, QObject* object = NULL) const;
|
||||
virtual QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const;
|
||||
virtual QObject* readRawDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -831,69 +837,6 @@ private:
|
|||
QByteArray _hash;
|
||||
};
|
||||
|
||||
/// Contains the information required to read an object from the stream.
|
||||
class ObjectReader {
|
||||
public:
|
||||
|
||||
ObjectReader(const QByteArray& className = QByteArray(), const QMetaObject* metaObject = NULL,
|
||||
const QVector<PropertyReader>& properties = QVector<PropertyReader>());
|
||||
|
||||
const QByteArray& getClassName() const { return _className; }
|
||||
const QMetaObject* getMetaObject() const { return _metaObject; }
|
||||
|
||||
QObject* read(Bitstream& in, QObject* object = NULL) const;
|
||||
QObject* readDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const;
|
||||
|
||||
bool operator==(const ObjectReader& other) const { return _className == other._className; }
|
||||
bool operator!=(const ObjectReader& other) const { return _className != other._className; }
|
||||
|
||||
private:
|
||||
|
||||
QByteArray _className;
|
||||
const QMetaObject* _metaObject;
|
||||
QVector<PropertyReader> _properties;
|
||||
};
|
||||
|
||||
uint qHash(const ObjectReader& objectReader, uint seed = 0);
|
||||
|
||||
QDebug& operator<<(QDebug& debug, const ObjectReader& objectReader);
|
||||
|
||||
/// Contains the information required to read an object property from the stream and apply it.
|
||||
class PropertyReader {
|
||||
public:
|
||||
|
||||
PropertyReader(const TypeStreamerPointer& streamer = TypeStreamerPointer(),
|
||||
const QMetaProperty& property = QMetaProperty());
|
||||
|
||||
const TypeStreamerPointer& getStreamer() const { return _streamer; }
|
||||
|
||||
void read(Bitstream& in, QObject* object) const;
|
||||
void readDelta(Bitstream& in, QObject* object, const QObject* reference) const;
|
||||
|
||||
private:
|
||||
|
||||
TypeStreamerPointer _streamer;
|
||||
QMetaProperty _property;
|
||||
};
|
||||
|
||||
/// Contains the information required to obtain an object property and write it to the stream.
|
||||
class PropertyWriter {
|
||||
public:
|
||||
|
||||
PropertyWriter(const QMetaProperty& property = QMetaProperty(), const TypeStreamer* streamer = NULL);
|
||||
|
||||
const QMetaProperty& getProperty() const { return _property; }
|
||||
const TypeStreamer* getStreamer() const { return _streamer; }
|
||||
|
||||
void write(Bitstream& out, const QObject* object) const;
|
||||
void writeDelta(Bitstream& out, const QObject* object, const QObject* reference) const;
|
||||
|
||||
private:
|
||||
|
||||
QMetaProperty _property;
|
||||
const TypeStreamer* _streamer;
|
||||
};
|
||||
|
||||
/// Describes a metatype field.
|
||||
class MetaField {
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue