mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-21 08:49:13 +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;
|
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 {
|
bool TypeReader::matchesExactly(const TypeStreamer* streamer) const {
|
||||||
return _exactMatch && _streamer == streamer;
|
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,
|
ObjectReader::ObjectReader(const QByteArray& className, const QMetaObject* metaObject,
|
||||||
const QVector<PropertyReader>& properties) :
|
const QVector<PropertyReader>& properties) :
|
||||||
_className(className),
|
_className(className),
|
||||||
|
|
|
@ -268,6 +268,9 @@ public:
|
||||||
/// Removes a shared object from the read mappings.
|
/// Removes a shared object from the read mappings.
|
||||||
void clearSharedObject(int id);
|
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);
|
||||||
Bitstream& operator>>(bool& value);
|
Bitstream& operator>>(bool& value);
|
||||||
|
|
||||||
|
@ -378,6 +381,23 @@ private:
|
||||||
static QVector<PropertyReader> getPropertyReaders(const QMetaObject* metaObject);
|
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) {
|
template<class T> inline Bitstream& Bitstream::operator<<(const QList<T>& list) {
|
||||||
*this << list.size();
|
*this << list.size();
|
||||||
foreach (const T& entry, list) {
|
foreach (const T& entry, list) {
|
||||||
|
@ -458,6 +478,7 @@ public:
|
||||||
const TypeStreamer* getStreamer() const { return _streamer; }
|
const TypeStreamer* getStreamer() const { return _streamer; }
|
||||||
|
|
||||||
QVariant read(Bitstream& in) const;
|
QVariant read(Bitstream& in) const;
|
||||||
|
void readDelta(Bitstream& in, QVariant& object, const QVariant& reference) const;
|
||||||
|
|
||||||
bool matchesExactly(const TypeStreamer* streamer) const;
|
bool matchesExactly(const TypeStreamer* streamer) const;
|
||||||
|
|
||||||
|
@ -486,6 +507,7 @@ public:
|
||||||
int getIndex() const { return _index; }
|
int getIndex() const { return _index; }
|
||||||
|
|
||||||
void read(Bitstream& in, const TypeStreamer* streamer, QVariant& object) const;
|
void read(Bitstream& in, const TypeStreamer* streamer, QVariant& object) const;
|
||||||
|
void readDelta(Bitstream& in, const TypeStreamer* streamer, QVariant& object, const QVariant& reference) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -565,6 +587,9 @@ public:
|
||||||
virtual void write(Bitstream& out, const QVariant& value) const = 0;
|
virtual void write(Bitstream& out, const QVariant& value) const = 0;
|
||||||
virtual QVariant read(Bitstream& in) 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 const QVector<MetaField>& getMetaFields() const;
|
||||||
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;
|
||||||
|
@ -590,6 +615,10 @@ public:
|
||||||
|
|
||||||
virtual void write(Bitstream& out, const QVariant& value) const { out << value.value<T>(); }
|
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 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.
|
/// A streamer for types compiled by mtc.
|
||||||
|
@ -652,6 +681,8 @@ public:
|
||||||
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
||||||
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
||||||
Bitstream& operator>>(Bitstream& in, 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); \
|
||||||
bool operator!=(const X& first, const X& second); \
|
bool operator!=(const X& first, const X& second); \
|
||||||
static const int* _TypePtr##X = &X::Type;
|
static const int* _TypePtr##X = &X::Type;
|
||||||
|
@ -659,6 +690,8 @@ public:
|
||||||
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
||||||
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
||||||
Bitstream& operator>>(Bitstream& in, 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); \
|
||||||
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;
|
__attribute__((unused)) static const int* _TypePtr##X = &X::Type;
|
||||||
|
@ -667,6 +700,8 @@ public:
|
||||||
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
#define DECLARE_STREAMABLE_METATYPE(X) Q_DECLARE_METATYPE(X) \
|
||||||
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
Bitstream& operator<<(Bitstream& out, const X& obj); \
|
||||||
Bitstream& operator>>(Bitstream& in, 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); \
|
||||||
bool operator!=(const X& first, const X& second); \
|
bool operator!=(const X& first, const X& second); \
|
||||||
static const int* _TypePtr##X = &X::Type; \
|
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
|
// default behavior is to make a copy using the no-arg constructor and copy the stored properties
|
||||||
const QMetaObject* metaObject = this->metaObject();
|
const QMetaObject* metaObject = this->metaObject();
|
||||||
SharedObject* newObject = static_cast<SharedObject*>(metaObject->newInstance());
|
SharedObject* newObject = static_cast<SharedObject*>(metaObject->newInstance());
|
||||||
|
@ -50,6 +50,9 @@ SharedObject* SharedObject::clone() const {
|
||||||
foreach (const QByteArray& propertyName, dynamicPropertyNames()) {
|
foreach (const QByteArray& propertyName, dynamicPropertyNames()) {
|
||||||
newObject->setProperty(propertyName, property(propertyName));
|
newObject->setProperty(propertyName, property(propertyName));
|
||||||
}
|
}
|
||||||
|
if (withID) {
|
||||||
|
newObject->setID(_id);
|
||||||
|
}
|
||||||
return newObject;
|
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;
|
int SharedObject::_lastID = 0;
|
||||||
WeakSharedObjectHash SharedObject::_weakHash;
|
WeakSharedObjectHash SharedObject::_weakHash;
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,8 @@ public:
|
||||||
void decrementReferenceCount();
|
void decrementReferenceCount();
|
||||||
|
|
||||||
/// Creates a new clone of this object.
|
/// 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.
|
/// Tests this object for equality with another.
|
||||||
virtual bool equals(const SharedObject* other) const;
|
virtual bool equals(const SharedObject* other) const;
|
||||||
|
@ -57,6 +58,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void setID(int id);
|
||||||
|
|
||||||
int _id;
|
int _id;
|
||||||
int _remoteID;
|
int _remoteID;
|
||||||
int _referenceCount;
|
int _referenceCount;
|
||||||
|
|
|
@ -172,6 +172,26 @@ void generateOutput (QTextStream& out, const QList<Streamable>& streamables) {
|
||||||
out << " return in;\n";
|
out << " return in;\n";
|
||||||
out << "}\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";
|
out << "bool operator==(const " << name << "& first, const " << name << "& second) {\n";
|
||||||
if (str.clazz.bases.isEmpty() && str.fields.isEmpty()) {
|
if (str.clazz.bases.isEmpty() && str.fields.isEmpty()) {
|
||||||
out << " return true";
|
out << " return true";
|
||||||
|
|
Loading…
Reference in a new issue