mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-07 10:52:37 +02:00
Working on delta streaming.
This commit is contained in:
parent
a4cc15a2cd
commit
24b2da1c0d
5 changed files with 88 additions and 3 deletions
|
@ -865,6 +865,21 @@ QVariant TypeReader::read(Bitstream& in) const {
|
|||
return object;
|
||||
}
|
||||
|
||||
void TypeReader::readDelta(Bitstream& in, QVariant& object, const QVariant& reference) const {
|
||||
if (_exactMatch) {
|
||||
_streamer->readDelta(in, object, reference);
|
||||
return;
|
||||
}
|
||||
if (_valueReader) {
|
||||
// TODO: collection deltas
|
||||
|
||||
} else {
|
||||
foreach (const FieldReader& field, _fields) {
|
||||
field.readDelta(in, _streamer, object, reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TypeReader::matchesExactly(const TypeStreamer* streamer) const {
|
||||
return _exactMatch && _streamer == streamer;
|
||||
}
|
||||
|
@ -885,6 +900,10 @@ void FieldReader::read(Bitstream& in, const TypeStreamer* streamer, QVariant& ob
|
|||
}
|
||||
}
|
||||
|
||||
void FieldReader::readDelta(Bitstream& in, const TypeStreamer* streamer, QVariant& object, const QVariant& reference) const {
|
||||
// TODO: field delta
|
||||
}
|
||||
|
||||
ObjectReader::ObjectReader(const QByteArray& className, const QMetaObject* metaObject,
|
||||
const QVector<PropertyReader>& properties) :
|
||||
_className(className),
|
||||
|
|
|
@ -268,6 +268,9 @@ public:
|
|||
/// Removes a shared object from the read mappings.
|
||||
void clearSharedObject(int id);
|
||||
|
||||
template<class T> void writeDelta(const T& value, const T& reference);
|
||||
template<class T> void readDelta(T& value, const T& reference);
|
||||
|
||||
Bitstream& operator<<(bool value);
|
||||
Bitstream& operator>>(bool& value);
|
||||
|
||||
|
@ -378,6 +381,23 @@ private:
|
|||
static QVector<PropertyReader> getPropertyReaders(const QMetaObject* metaObject);
|
||||
};
|
||||
|
||||
template<class T> inline void Bitstream::writeDelta(const T& value, const T& reference) {
|
||||
if (value == reference) {
|
||||
*this << false;
|
||||
} else {
|
||||
*this << true;
|
||||
*this << value;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> inline void Bitstream::readDelta(T& value, const T& reference) {
|
||||
bool changed;
|
||||
*this >> changed;
|
||||
if (changed) {
|
||||
*this >> value;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> inline Bitstream& Bitstream::operator<<(const QList<T>& list) {
|
||||
*this << list.size();
|
||||
foreach (const T& entry, list) {
|
||||
|
@ -458,6 +478,7 @@ public:
|
|||
const TypeStreamer* getStreamer() const { return _streamer; }
|
||||
|
||||
QVariant read(Bitstream& in) const;
|
||||
void readDelta(Bitstream& in, QVariant& object, const QVariant& reference) const;
|
||||
|
||||
bool matchesExactly(const TypeStreamer* streamer) const;
|
||||
|
||||
|
@ -486,7 +507,8 @@ public:
|
|||
int getIndex() const { return _index; }
|
||||
|
||||
void read(Bitstream& in, const TypeStreamer* streamer, QVariant& object) const;
|
||||
|
||||
void readDelta(Bitstream& in, const TypeStreamer* streamer, QVariant& object, const QVariant& reference) const;
|
||||
|
||||
private:
|
||||
|
||||
TypeReader _reader;
|
||||
|
@ -565,6 +587,9 @@ public:
|
|||
virtual void write(Bitstream& out, const QVariant& value) const = 0;
|
||||
virtual QVariant read(Bitstream& in) const = 0;
|
||||
|
||||
virtual void writeDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const = 0;
|
||||
virtual void readDelta(Bitstream& in, QVariant& value, const QVariant& reference) const = 0;
|
||||
|
||||
virtual const QVector<MetaField>& getMetaFields() const;
|
||||
virtual int getFieldIndex(const QByteArray& name) const;
|
||||
virtual void setField(int index, QVariant& object, const QVariant& value) const;
|
||||
|
@ -590,6 +615,10 @@ public:
|
|||
|
||||
virtual void write(Bitstream& out, const QVariant& value) const { out << value.value<T>(); }
|
||||
virtual QVariant read(Bitstream& in) const { T value; in >> value; return QVariant::fromValue(value); }
|
||||
virtual void writeDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const {
|
||||
out.writeDelta(value.value<T>(), reference.value<T>()); }
|
||||
virtual void readDelta(Bitstream& in, QVariant& value, const QVariant& reference) const {
|
||||
in.readDelta(*static_cast<T*>(value.data()), reference.value<T>()); }
|
||||
};
|
||||
|
||||
/// A streamer for types compiled by mtc.
|
||||
|
@ -652,6 +681,8 @@ public:
|
|||
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
||||
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
||||
Bitstream& operator>>(Bitstream& in, X& obj); \
|
||||
template<> void Bitstream::writeDelta(const X& value, const X& reference); \
|
||||
template<> void Bitstream::readDelta(X& value, const X& reference); \
|
||||
bool operator==(const X& first, const X& second); \
|
||||
bool operator!=(const X& first, const X& second); \
|
||||
static const int* _TypePtr##X = &X::Type;
|
||||
|
@ -659,6 +690,8 @@ public:
|
|||
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
||||
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
||||
Bitstream& operator>>(Bitstream& in, X& obj); \
|
||||
template<> void Bitstream::writeDelta(const X& value, const X& reference); \
|
||||
template<> void Bitstream::readDelta(X& value, const X& reference); \
|
||||
bool operator==(const X& first, const X& second); \
|
||||
bool operator!=(const X& first, const X& second); \
|
||||
__attribute__((unused)) static const int* _TypePtr##X = &X::Type;
|
||||
|
@ -667,6 +700,8 @@ public:
|
|||
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
||||
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
||||
Bitstream& operator>>(Bitstream& in, X& obj); \
|
||||
template<> void Bitstream::writeDelta(const X& value, const X& reference); \
|
||||
template<> void Bitstream::readDelta(X& value, const X& reference); \
|
||||
bool operator==(const X& first, const X& second); \
|
||||
bool operator!=(const X& first, const X& second); \
|
||||
static const int* _TypePtr##X = &X::Type; \
|
||||
|
|
|
@ -37,7 +37,7 @@ void SharedObject::decrementReferenceCount() {
|
|||
}
|
||||
}
|
||||
|
||||
SharedObject* SharedObject::clone() const {
|
||||
SharedObject* SharedObject::clone(bool withID) const {
|
||||
// default behavior is to make a copy using the no-arg constructor and copy the stored properties
|
||||
const QMetaObject* metaObject = this->metaObject();
|
||||
SharedObject* newObject = static_cast<SharedObject*>(metaObject->newInstance());
|
||||
|
@ -50,6 +50,9 @@ SharedObject* SharedObject::clone() const {
|
|||
foreach (const QByteArray& propertyName, dynamicPropertyNames()) {
|
||||
newObject->setProperty(propertyName, property(propertyName));
|
||||
}
|
||||
if (withID) {
|
||||
newObject->setID(_id);
|
||||
}
|
||||
return newObject;
|
||||
}
|
||||
|
||||
|
@ -91,6 +94,11 @@ void SharedObject::dump(QDebug debug) const {
|
|||
}
|
||||
}
|
||||
|
||||
void SharedObject::setID(int id) {
|
||||
_weakHash.remove(_id);
|
||||
_weakHash.insert(_id = id, this);
|
||||
}
|
||||
|
||||
int SharedObject::_lastID = 0;
|
||||
WeakSharedObjectHash SharedObject::_weakHash;
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ public:
|
|||
void decrementReferenceCount();
|
||||
|
||||
/// Creates a new clone of this object.
|
||||
virtual SharedObject* clone() const;
|
||||
/// \param withID if true, give the clone the same ID as this object
|
||||
virtual SharedObject* clone(bool withID = false) const;
|
||||
|
||||
/// Tests this object for equality with another.
|
||||
virtual bool equals(const SharedObject* other) const;
|
||||
|
@ -57,6 +58,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void setID(int id);
|
||||
|
||||
int _id;
|
||||
int _remoteID;
|
||||
int _referenceCount;
|
||||
|
|
|
@ -172,6 +172,26 @@ void generateOutput (QTextStream& out, const QList<Streamable>& streamables) {
|
|||
out << " return in;\n";
|
||||
out << "}\n";
|
||||
|
||||
out << "template<> void Bitstream::writeDelta(const " << name << "& value, const " << name << "& reference) {\n";
|
||||
foreach (const QString& base, str.clazz.bases) {
|
||||
out << " writeDelta(static_cast<const " << base << "&>(value), static_cast<const " <<
|
||||
base << "&>(reference));\n";
|
||||
}
|
||||
foreach (const Field& field, str.fields) {
|
||||
out << " writeDelta(value." << field.name << ", reference." << field.name << ");\n";
|
||||
}
|
||||
out << "}\n";
|
||||
|
||||
out << "template<> void Bitstream::readDelta(" << name << "& value, const " << name << "& reference) {\n";
|
||||
foreach (const QString& base, str.clazz.bases) {
|
||||
out << " readDelta(static_cast<" << base << "&>(value), static_cast<const " <<
|
||||
base << "&>(reference));\n";
|
||||
}
|
||||
foreach (const Field& field, str.fields) {
|
||||
out << " readDelta(value." << field.name << ", reference." << field.name << ");\n";
|
||||
}
|
||||
out << "}\n";
|
||||
|
||||
out << "bool operator==(const " << name << "& first, const " << name << "& second) {\n";
|
||||
if (str.clazz.bases.isEmpty() && str.fields.isEmpty()) {
|
||||
out << " return true";
|
||||
|
|
Loading…
Reference in a new issue