Allow shared objects to write extra, non-property data.

This commit is contained in:
Andrzej Kapolka 2014-11-24 16:45:34 -08:00
parent 71cee18c4b
commit af875eb5af
4 changed files with 83 additions and 6 deletions

View file

@ -1156,6 +1156,16 @@ Bitstream& Bitstream::operator<(const ObjectStreamer* streamer) {
return *this;
}
static MappedObjectStreamer* createMappedObjectStreamer(const QMetaObject* metaObject,
const QVector<StreamerPropertyPair>& properties) {
for (const QMetaObject* super = metaObject; super; super = super->superClass()) {
if (super == &SharedObject::staticMetaObject) {
return new SharedObjectStreamer(metaObject, properties);
}
}
return new MappedObjectStreamer(metaObject, properties);
}
Bitstream& Bitstream::operator>(ObjectStreamerPointer& streamer) {
QByteArray className;
*this >> className;
@ -1231,7 +1241,7 @@ Bitstream& Bitstream::operator>(ObjectStreamerPointer& streamer) {
} else if (metaObject) {
const QVector<StreamerPropertyPair>& localProperties = streamer->getProperties();
if (localProperties.size() != properties.size()) {
streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
streamer = ObjectStreamerPointer(createMappedObjectStreamer(metaObject, properties));
return *this;
}
for (int i = 0; i < localProperties.size(); i++) {
@ -1239,13 +1249,13 @@ Bitstream& Bitstream::operator>(ObjectStreamerPointer& streamer) {
const StreamerPropertyPair& localProperty = localProperties.at(i);
if (property.first != localProperty.first ||
property.second.propertyIndex() != localProperty.second.propertyIndex()) {
streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
streamer = ObjectStreamerPointer(createMappedObjectStreamer(metaObject, properties));
return *this;
}
}
return *this;
}
streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
streamer = ObjectStreamerPointer(createMappedObjectStreamer(metaObject, properties));
return *this;
}
@ -1671,7 +1681,7 @@ QHash<const QMetaObject*, const ObjectStreamer*> Bitstream::createObjectStreamer
properties.append(StreamerPropertyPair(streamer->getSelf(), property));
}
}
ObjectStreamerPointer streamer = ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties));
ObjectStreamerPointer streamer = ObjectStreamerPointer(createMappedObjectStreamer(metaObject, properties));
streamer->_self = streamer;
objectStreamers.insert(metaObject, streamer.data());
}
@ -2122,7 +2132,7 @@ JSONReader::JSONReader(const QJsonDocument& document, Bitstream::GenericsMode ge
if (matches) {
_objectStreamers.insert(name, baseStreamer->getSelf());
} else {
_objectStreamers.insert(name, ObjectStreamerPointer(new MappedObjectStreamer(metaObject, properties)));
_objectStreamers.insert(name, ObjectStreamerPointer(createMappedObjectStreamer(metaObject, properties)));
}
}
@ -2437,6 +2447,32 @@ QObject* MappedObjectStreamer::readRawDelta(Bitstream& in, const QObject* refere
return object;
}
SharedObjectStreamer::SharedObjectStreamer(const QMetaObject* metaObject, const QVector<StreamerPropertyPair>& properties) :
MappedObjectStreamer(metaObject, properties) {
}
void SharedObjectStreamer::write(Bitstream& out, const QObject* object) const {
MappedObjectStreamer::write(out, object);
static_cast<const SharedObject*>(object)->writeExtra(out);
}
void SharedObjectStreamer::writeRawDelta(Bitstream& out, const QObject* object, const QObject* reference) const {
MappedObjectStreamer::writeRawDelta(out, object, reference);
static_cast<const SharedObject*>(object)->writeExtraDelta(out, static_cast<const SharedObject*>(reference));
}
QObject* SharedObjectStreamer::read(Bitstream& in, QObject* object) const {
QObject* result = MappedObjectStreamer::read(in, object);
static_cast<SharedObject*>(result)->readExtra(in);
return result;
}
QObject* SharedObjectStreamer::readRawDelta(Bitstream& in, const QObject* reference, QObject* object) const {
QObject* result = MappedObjectStreamer::readRawDelta(in, reference, object);
static_cast<SharedObject*>(result)->readExtraDelta(in, static_cast<const SharedObject*>(reference));
return result;
}
GenericObjectStreamer::GenericObjectStreamer(const QByteArray& name, const QVector<StreamerNamePair>& properties,
const QByteArray& hash) :
ObjectStreamer(&GenericSharedObject::staticMetaObject),

View file

@ -1133,6 +1133,18 @@ private:
QVector<StreamerPropertyPair> _properties;
};
/// A streamer that maps to a local shared object class. Shared objects can write extra, non-property data.
class SharedObjectStreamer : public MappedObjectStreamer {
public:
SharedObjectStreamer(const QMetaObject* metaObject, const QVector<StreamerPropertyPair>& properties);
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* readRawDelta(Bitstream& in, const QObject* reference, QObject* object = NULL) const;
};
typedef QPair<TypeStreamerPointer, QByteArray> StreamerNamePair;
/// A streamer for generic objects.

View file

@ -131,6 +131,22 @@ void SharedObject::dump(QDebug debug) const {
}
}
void SharedObject::writeExtra(Bitstream& out) const {
// nothing by default
}
void SharedObject::readExtra(Bitstream& in) {
// nothing by default
}
void SharedObject::writeExtraDelta(Bitstream& out, const SharedObject* reference) const {
// nothing by default
}
void SharedObject::readExtraDelta(Bitstream& in, const SharedObject* reference) {
// nothing by default
}
QAtomicInt SharedObject::_nextID(1);
WeakSharedObjectHash SharedObject::_weakHash;
QReadWriteLock SharedObject::_weakHashLock;

View file

@ -24,6 +24,7 @@
class QComboBox;
class Bitstream;
class SharedObject;
typedef QHash<int, QPointer<SharedObject> > WeakSharedObjectHash;
@ -76,9 +77,21 @@ public:
/// this is an instance of a superclass of the other object's class) rather than simply returning false.
virtual bool equals(const SharedObject* other, bool sharedAncestry = false) const;
// Dumps the contents of this object to the debug output.
/// Dumps the contents of this object to the debug output.
virtual void dump(QDebug debug = QDebug(QtDebugMsg)) const;
/// Writes the non-property contents of this object to the specified stream.
virtual void writeExtra(Bitstream& out) const;
/// Reads the non-property contents of this object from the specified stream.
virtual void readExtra(Bitstream& in);
/// Writes the delta-encoded non-property contents of this object to the specified stream.
virtual void writeExtraDelta(Bitstream& out, const SharedObject* reference) const;
/// Reads the delta-encoded non-property contents of this object from the specified stream.
virtual void readExtraDelta(Bitstream& in, const SharedObject* reference);
private:
int _id;