From: Manuel Nickschas Date: Mon, 7 Jan 2008 19:03:20 +0000 (+0000) Subject: SignalProxy now only allows syncing for classes derived from the new X-Git-Tag: 0.2.0-alpha1~244 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=b797e5f581b10a517c30f78cb53f813af741e261;hp=21d8d7f0a79eeeb541664aa80ce481fdbfc41f09 SignalProxy now only allows syncing for classes derived from the new SyncableObject. This allows us to add certain features to such classes, such as toVariantMap() and fromVariantMap() which handle storing object properties in a QVariantMap. This is quite a disruptive change - distclean advised. --- diff --git a/src/common/common.pri b/src/common/common.pri index 13f971c8..79ea638b 100644 --- a/src/common/common.pri +++ b/src/common/common.pri @@ -1,4 +1,6 @@ DEPMOD = QT_MOD = network -SRCS += bufferinfo.cpp global.cpp identity.cpp logger.cpp message.cpp settings.cpp signalproxy.cpp util.cpp networkinfo.cpp ircuser.cpp ircchannel.cpp -HDRS += bufferinfo.h global.h identity.h logger.h message.h settings.h signalproxy.h util.h networkinfo.h ircuser.h ircchannel.h types.h +SRCS += bufferinfo.cpp global.cpp identity.cpp logger.cpp message.cpp settings.cpp signalproxy.cpp syncableobject.cpp \ + util.cpp networkinfo.cpp ircuser.cpp ircchannel.cpp +HDRS += bufferinfo.h global.h identity.h logger.h message.h settings.h signalproxy.h syncableobject.h \ + util.h networkinfo.h ircuser.h ircchannel.h types.h diff --git a/src/common/global.cpp b/src/common/global.cpp index 5298d17a..09aa5902 100644 --- a/src/common/global.cpp +++ b/src/common/global.cpp @@ -26,6 +26,7 @@ #include "identity.h" #include "bufferinfo.h" #include "types.h" +#include "syncableobject.h" extern void messageHandler(QtMsgType type, const char *msg); diff --git a/src/common/identity.cpp b/src/common/identity.cpp index c2fdeaf5..a45eb757 100644 --- a/src/common/identity.cpp +++ b/src/common/identity.cpp @@ -23,12 +23,12 @@ #include "identity.h" -Identity::Identity(IdentityId id, QObject *parent) : QObject(parent), _identityId(id) { +Identity::Identity(IdentityId id, QObject *parent) : SyncableObject(parent), _identityId(id) { init(); setToDefaults(); } -Identity::Identity(const Identity &other, QObject *parent) : QObject(parent), +Identity::Identity(const Identity &other, QObject *parent) : SyncableObject(parent), _identityId(other.id()), _identityName(other.identityName()), _realName(other.realName()), @@ -313,56 +313,17 @@ bool Identity::operator!=(const Identity &other) { /////////////////////////////// -// we use a hash, so we can easily extend identities without breaking saved ones -QDataStream &operator<<(QDataStream &out, const Identity &id) { - QVariantMap i; - i["IdentityId"] = id.id(); - i["IdentityName"] = id.identityName(); - i["RealName"] = id.realName(); - i["Nicks"] = id.nicks(); - i["AwayNick"] = id.awayNick(); - i["AwayNickEnabled"] = id.awayNickEnabled(); - i["AwayReason"] = id.awayReason(); - i["AwayReasonEnabled"] = id.awayReasonEnabled(); - i["ReturnMessage"] = id.returnMessage(); - i["ReturnMessageEnabled"] = id.returnMessageEnabled(); - i["AutoAwayEnabled"] = id.autoAwayEnabled(); - i["AutoAwayTime"] = id.autoAwayTime(); - i["AutoAwayReason"] = id.autoAwayReason(); - i["AutoAwayReasonEnabled"] = id.autoAwayReasonEnabled(); - i["AutoReturnMessage"] = id.autoReturnMessage(); - i["AutoReturnMessageEnabled"] = id.autoReturnMessageEnabled(); - i["Ident"] = id.ident(); - i["KickReason"] = id.kickReason(); - i["PartReason"] = id.partReason(); - i["QuitReason"] = id.quitReason(); - out << i; +QDataStream &operator<<(QDataStream &out, Identity id) { + out << id.toVariantMap(); return out; } + QDataStream &operator>>(QDataStream &in, Identity &id) { QVariantMap i; in >> i; - id._identityId = i["IdentityId"].toUInt(); - id.setIdentityName(i["IdentityName"].toString()); - id.setRealName(i["RealName"].toString()); - id.setNicks(i["Nicks"].toStringList()); - id.setAwayNick(i["AwayNick"].toString()); - id.setAwayNickEnabled(i["AwayNickEnabled"].toBool()); - id.setAwayReason(i["AwayReason"].toString()); - id.setAwayReasonEnabled(i["AwayReasonEnabled"].toBool()); - id.setReturnMessage(i["ReturnMessage"].toString()); - id.setReturnMessageEnabled(i["ReturnMessageEnabled"].toBool()); - id.setAutoAwayEnabled(i["AutoAwayEnabled"].toBool()); - id.setAutoAwayTime(i["AutoAwayTime"].toInt()); - id.setAutoAwayReason(i["AutoAwayReason"].toString()); - id.setAutoAwayReasonEnabled(i["AutoAwayReasonEnabled"].toBool()); - id.setAutoReturnMessage(i["AutoReturnMessage"].toString()); - id.setAutoReturnMessageEnabled(i["AutoReturnMessageEnabled"].toBool()); - id.setIdent(i["Ident"].toString()); - id.setKickReason(i["KickReason"].toString()); - id.setPartReason(i["PartReason"].toString()); - id.setQuitReason(i["QuitReason"].toString()); + id.fromVariantMap(i); return in; } + diff --git a/src/common/identity.h b/src/common/identity.h index 3db8a282..bffd2a36 100644 --- a/src/common/identity.h +++ b/src/common/identity.h @@ -27,8 +27,9 @@ #include #include "types.h" +#include "syncableobject.h" -class Identity : public QObject { +class Identity : public SyncableObject { Q_OBJECT Q_PROPERTY(IdentityId identityId READ id WRITE setId STORED false); @@ -158,7 +159,7 @@ class Identity : public QObject { friend QDataStream &operator>>(QDataStream &in, Identity &identity); }; -QDataStream &operator<<(QDataStream &out, const Identity &identity); +QDataStream &operator<<(QDataStream &out, Identity identity); QDataStream &operator>>(QDataStream &in, Identity &identity); Q_DECLARE_METATYPE(Identity); diff --git a/src/common/ircchannel.cpp b/src/common/ircchannel.cpp index ba2fd3c2..ffba36d5 100644 --- a/src/common/ircchannel.cpp +++ b/src/common/ircchannel.cpp @@ -34,7 +34,7 @@ IrcChannel::IrcChannel(const QString &channelname, NetworkInfo *networkinfo) - : QObject(networkinfo), + : SyncableObject(networkinfo), _initialized(false), _name(channelname), _topic(QString()), diff --git a/src/common/ircchannel.h b/src/common/ircchannel.h index 1a62c1d5..2cbfa1aa 100644 --- a/src/common/ircchannel.h +++ b/src/common/ircchannel.h @@ -26,11 +26,13 @@ #include #include +#include "syncableobject.h" + class IrcUser; class NetworkInfo; class SignalProxy; -class IrcChannel : public QObject { +class IrcChannel : public SyncableObject { Q_OBJECT Q_PROPERTY(QString name READ name STORED false) diff --git a/src/common/ircuser.cpp b/src/common/ircuser.cpp index 8ef8f1cd..a313fc68 100644 --- a/src/common/ircuser.cpp +++ b/src/common/ircuser.cpp @@ -29,7 +29,7 @@ #include IrcUser::IrcUser(const QString &hostmask, NetworkInfo *networkinfo) - : QObject(networkinfo), + : SyncableObject(networkinfo), _initialized(false), _nick(nickFromMask(hostmask)), _user(userFromMask(hostmask)), diff --git a/src/common/ircuser.h b/src/common/ircuser.h index d1ac21e1..41c1792f 100644 --- a/src/common/ircuser.h +++ b/src/common/ircuser.h @@ -26,11 +26,13 @@ #include #include +#include "syncableobject.h" + class SignalProxy; class NetworkInfo; class IrcChannel; -class IrcUser : public QObject { +class IrcUser : public SyncableObject { Q_OBJECT Q_PROPERTY(QString user READ user WRITE setUser STORED false) diff --git a/src/common/networkinfo.cpp b/src/common/networkinfo.cpp index 98035781..19f4233e 100644 --- a/src/common/networkinfo.cpp +++ b/src/common/networkinfo.cpp @@ -32,7 +32,7 @@ // Public: // ==================== NetworkInfo::NetworkInfo(const uint &networkid, QObject *parent) - : QObject(parent), + : SyncableObject(parent), _networkId(networkid), _initialized(false), _myNick(QString()), diff --git a/src/common/networkinfo.h b/src/common/networkinfo.h index eb2b287a..2caa4dc9 100644 --- a/src/common/networkinfo.h +++ b/src/common/networkinfo.h @@ -29,13 +29,14 @@ #include #include "types.h" +#include "syncableobject.h" class SignalProxy; class IrcUser; class IrcChannel; -class NetworkInfo : public QObject { +class NetworkInfo : public SyncableObject { Q_OBJECT Q_PROPERTY(QString networkName READ networkName WRITE setNetworkName STORED false) diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index 03861d36..e4964798 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include "signalproxy.h" + #include #include #include @@ -31,6 +32,8 @@ #include #include #include + +#include "syncableobject.h" #include "util.h" class SignalRelay: public QObject { @@ -87,7 +90,7 @@ int SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { // dispatch Sync Signal if necessary QByteArray signature(caller->metaObject()->method(_id).signature()); - if(synchronize() && proxy->syncMap(caller).contains(signature)) { + if(synchronize() && proxy->syncMap(qobject_cast(caller)).contains(signature)) { // qDebug() << "__SYNC__ >>>" // << caller->metaObject()->className() // << caller->objectName() @@ -125,7 +128,7 @@ void SignalRelay::setSynchronize(bool sync) { bool SignalRelay::isSyncMethod(int i) { QByteArray signature = caller->metaObject()->method(i).signature(); - if(!proxy->syncMap(caller).contains(signature)) + if(!proxy->syncMap(qobject_cast(caller)).contains(signature)) return false; if(proxy->proxyMode() == SignalProxy::Server && !signature.startsWith("request")) @@ -356,7 +359,7 @@ const QByteArray &SignalProxy::methodName(QObject *obj, int methodId) { } -void SignalProxy::setSyncMap(QObject *obj) { +void SignalProxy::setSyncMap(SyncableObject *obj) { const QMetaObject *meta = obj->metaObject(); QHash syncMap; @@ -391,7 +394,7 @@ void SignalProxy::setSyncMap(QObject *obj) { _classInfo[meta]->syncMap = syncMap; } -const QHash &SignalProxy::syncMap(QObject *obj) { +const QHash &SignalProxy::syncMap(SyncableObject *obj) { Q_ASSERT(_classInfo.contains(obj->metaObject())); if(_classInfo[obj->metaObject()]->syncMap.isEmpty()) setSyncMap(obj); @@ -448,7 +451,7 @@ bool SignalProxy::attachSlot(const QByteArray& sigName, QObject* recv, const cha return true; } -void SignalProxy::synchronize(QObject *obj) { +void SignalProxy::synchronize(SyncableObject *obj) { createClassInfo(obj); // attaching all the Signals @@ -474,18 +477,18 @@ void SignalProxy::synchronize(QObject *obj) { } } -void SignalProxy::setInitialized(QObject *obj) { +void SignalProxy::setInitialized(SyncableObject *obj) { QMetaObject::invokeMethod(obj, "setInitialized"); } -bool SignalProxy::initialized(QObject *obj) { +bool SignalProxy::initialized(SyncableObject *obj) { bool init; if(!QMetaObject::invokeMethod(obj, "initialized", Q_RETURN_ARG(bool, init))) init = false; return init; } -void SignalProxy::requestInit(QObject *obj) { +void SignalProxy::requestInit(SyncableObject *obj) { if(proxyMode() == Server || initialized(obj)) return; @@ -511,7 +514,8 @@ void SignalProxy::detachObject(QObject* obj) { QMutexLocker locker(&slaveMutex); _detachSignals(obj); _detachSlots(obj); - _stopSync(obj); + SyncableObject *syncobj = qobject_cast(obj); + if(syncobj) _stopSync(syncobj); } void SignalProxy::detachSignals(QObject* sender) { @@ -524,7 +528,7 @@ void SignalProxy::detachSlots(QObject* receiver) { _detachSlots(receiver); } -void SignalProxy::stopSync(QObject* obj) { +void SignalProxy::stopSync(SyncableObject* obj) { QMutexLocker locker(&slaveMutex); _stopSync(obj); } @@ -545,7 +549,7 @@ void SignalProxy::_detachSlots(QObject* receiver) { } } -void SignalProxy::_stopSync(QObject* obj) { +void SignalProxy::_stopSync(SyncableObject* obj) { if(_relayHash.contains(obj)) _relayHash[obj]->setSynchronize(false); @@ -618,7 +622,7 @@ void SignalProxy::handleSync(QVariantList params) { return; } - QObject *receiver = _syncSlave[className][objectName]; + SyncableObject *receiver = _syncSlave[className][objectName]; if(!syncMap(receiver).contains(signal)) { qWarning() << QString("no matching slot for sync call: %s::%s (objectName=\"%s\"). Params are:").arg(QString(className)).arg(QString(signal)).arg(objectName) << params; @@ -656,7 +660,7 @@ void SignalProxy::handleInitRequest(QIODevice *sender, const QVariantList ¶m return; } - QObject *obj = _syncSlave[className][objectName]; + SyncableObject *obj = _syncSlave[className][objectName]; QVariantList params_; params_ << obj->metaObject()->className() @@ -690,7 +694,7 @@ void SignalProxy::handleInitData(QIODevice *sender, const QVariantList ¶ms) return; } - QObject *obj = _syncSlave[className][objectName]; + SyncableObject *obj = _syncSlave[className][objectName]; setInitData(obj, propertyMap); } @@ -789,64 +793,17 @@ QString SignalProxy::methodBaseName(const QMetaMethod &method) { return methodname; } -QVariantMap SignalProxy::initData(QObject *obj) const { - QVariantMap properties; - - const QMetaObject* meta = obj->metaObject(); - - // we collect data from properties - for(int i = 0; i < meta->propertyCount(); i++) { - QMetaProperty prop = meta->property(i); - properties[QString(prop.name())] = prop.read(obj); - } - - // ...as well as methods, which have names starting with "init" - for(int i = 0; i < meta->methodCount(); i++) { - QMetaMethod method = meta->method(i); - QString methodname(::methodName(method)); - if(!methodname.startsWith("init") || methodname.startsWith("initSet")) - continue; - - QVariant value = QVariant(QVariant::nameToType(method.typeName())); - QGenericReturnArgument genericvalue = QGenericReturnArgument(method.typeName(), &value); - QMetaObject::invokeMethod(obj, methodname.toAscii(), genericvalue); - - properties[methodBaseName(method)] = value; - // qDebug() << ">>> SYNC:" << methodBaseName(method) << value; - } - - // properties["Payload"] = QByteArray(10000000, 'a'); // for testing purposes - return properties; +QVariantMap SignalProxy::initData(SyncableObject *obj) const { + return obj->toVariantMap(); } -void SignalProxy::setInitData(QObject *obj, const QVariantMap &properties) { +void SignalProxy::setInitData(SyncableObject *obj, const QVariantMap &properties) { if(initialized(obj)) return; - - const QMetaObject *meta = obj->metaObject(); - - QVariantMap::const_iterator iterator = properties.constBegin(); - while(iterator != properties.constEnd()) { - QString name = iterator.key(); - int propertyIndex = meta->indexOfProperty(name.toAscii()); - - if(propertyIndex == -1 || !meta->property(propertyIndex).isWritable()) - setInitValue(obj, name, iterator.value()); - else - obj->setProperty(name.toAscii(), iterator.value()); - // qDebug() << "<<< SYNC:" << name << iterator.value(); - iterator++; - } + obj->fromVariantMap(properties); setInitialized(obj); } -bool SignalProxy::setInitValue(QObject *obj, const QString &property, const QVariant &value) { - QString handlername = QString("initSet") + property; - handlername[7] = handlername[7].toUpper(); - QGenericArgument param(value.typeName(), value.constData()); - return QMetaObject::invokeMethod(obj, handlername.toAscii(), param); -} - void SignalProxy::dumpProxyStats() { QString mode; if(proxyMode() == Server) @@ -871,7 +828,7 @@ void SignalProxy::dumpProxyStats() { qDebug() << "number of Classes cached:" << _classInfo.count(); } -void SignalProxy::dumpSyncMap(QObject *object) { +void SignalProxy::dumpSyncMap(SyncableObject *object) { const QMetaObject *meta = object->metaObject(); qDebug() << "SignalProxy: SyncMap for Class" << meta->className(); diff --git a/src/common/signalproxy.h b/src/common/signalproxy.h index 8c51724b..1a8dfac9 100644 --- a/src/common/signalproxy.h +++ b/src/common/signalproxy.h @@ -32,6 +32,7 @@ #include class SignalRelay; +class SyncableObject; class QMetaObject; class SignalProxy : public QObject { @@ -63,16 +64,16 @@ public: bool attachSignal(QObject *sender, const char *signal, const QByteArray& sigName = QByteArray()); bool attachSlot(const QByteArray& sigName, QObject *recv, const char *slot); - void synchronize(QObject *obj); + void synchronize(SyncableObject *obj); - void setInitialized(QObject *obj); - bool initialized(QObject *obj); - void requestInit(QObject *obj); + void setInitialized(SyncableObject *obj); + bool initialized(SyncableObject *obj); + void requestInit(SyncableObject *obj); void detachObject(QObject *obj); void detachSignals(QObject *sender); void detachSlots(QObject *receiver); - void stopSync(QObject *obj); + void stopSync(SyncableObject *obj); //! Writes a QVariant to a device. /** The data item is prefixed with the resulting blocksize, @@ -92,7 +93,7 @@ public: const QList &argTypes(QObject *obj, int methodId); bool hasUpdateSignal(QObject *obj); const QByteArray &methodName(QObject *obj, int methodId); - const QHash &syncMap(QObject *obj); + const QHash &syncMap(SyncableObject *obj); typedef QHash > ArgHash; typedef QHash MethodNameHash; @@ -124,7 +125,7 @@ private: void createClassInfo(QObject *obj); void setArgTypes(QObject *obj, int methodId); void setMethodName(QObject *obj, int methodId); - void setSyncMap(QObject *obj); + void setSyncMap(SyncableObject *obj); bool methodsMatch(const QMetaMethod &signal, const QMetaMethod &slot) const; @@ -139,16 +140,15 @@ private: bool invokeSlot(QObject *receiver, int methodId, const QVariantList ¶ms); - QVariantMap initData(QObject *obj) const; - void setInitData(QObject *obj, const QVariantMap &properties); - bool setInitValue(QObject *obj, const QString &property, const QVariant &value); + QVariantMap initData(SyncableObject *obj) const; + void setInitData(SyncableObject *obj, const QVariantMap &properties); void _detachSignals(QObject *sender); void _detachSlots(QObject *receiver); - void _stopSync(QObject *obj); + void _stopSync(SyncableObject *obj); + + void dumpSyncMap(SyncableObject *object); - void dumpSyncMap(QObject *object); - // Hash of used QIODevices QHash _peerByteCount; @@ -164,7 +164,7 @@ private: SlotHash _attachedSlots; // slaves for sync - typedef QHash ObjectId; + typedef QHash ObjectId; QHash _syncSlave; diff --git a/src/common/syncableobject.cpp b/src/common/syncableobject.cpp new file mode 100644 index 00000000..5bf68044 --- /dev/null +++ b/src/common/syncableobject.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright (C) 2005-08 by the Quassel IRC Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include "syncableobject.h" + +#include "signalproxy.h" +#include "util.h" + +SyncableObject::SyncableObject(QObject *parent) : QObject(parent) { + +} + +SyncableObject::SyncableObject(const SyncableObject &other, QObject *parent) : QObject(parent) { + Q_UNUSED(other); + +} + +QVariantMap SyncableObject::toVariantMap() { + QVariantMap properties; + + const QMetaObject* meta = metaObject(); + + // we collect data from properties + for(int i = 0; i < meta->propertyCount(); i++) { + QMetaProperty prop = meta->property(i); + properties[QString(prop.name())] = prop.read(this); + } + + // ...as well as methods, which have names starting with "init" + for(int i = 0; i < meta->methodCount(); i++) { + QMetaMethod method = meta->method(i); + QString methodname(::methodName(method)); + if(!methodname.startsWith("init") || methodname.startsWith("initSet")) + continue; + + QVariant value = QVariant(QVariant::nameToType(method.typeName())); + QGenericReturnArgument genericvalue = QGenericReturnArgument(method.typeName(), &value); + QMetaObject::invokeMethod(this, methodname.toAscii(), genericvalue); + + properties[SignalProxy::methodBaseName(method)] = value; + // qDebug() << ">>> SYNC:" << methodBaseName(method) << value; + } + // properties["Payload"] = QByteArray(10000000, 'a'); // for testing purposes + return properties; + +} + +void SyncableObject::fromVariantMap(const QVariantMap &properties) { + const QMetaObject *meta = metaObject(); + + QVariantMap::const_iterator iterator = properties.constBegin(); + while(iterator != properties.constEnd()) { + QString name = iterator.key(); + int propertyIndex = meta->indexOfProperty(name.toAscii()); + + if(propertyIndex == -1 || !meta->property(propertyIndex).isWritable()) + setInitValue(name, iterator.value()); + else + setProperty(name.toAscii(), iterator.value()); + // qDebug() << "<<< SYNC:" << name << iterator.value(); + iterator++; + } +} + +bool SyncableObject::setInitValue(const QString &property, const QVariant &value) { + QString handlername = QString("initSet") + property; + handlername[7] = handlername[7].toUpper(); + QGenericArgument param(value.typeName(), value.constData()); + return QMetaObject::invokeMethod(this, handlername.toAscii(), param); +} + +#include +QDataStream &operator<<(QDataStream &out, SyncableObject object) { + out << object.toVariantMap(); + return out; +} + +QDataStream &operator>>(QDataStream &in, SyncableObject &object) { + QVariantMap map; + in >> map; + object.fromVariantMap(map); + return in; +} diff --git a/src/common/syncableobject.h b/src/common/syncableobject.h new file mode 100644 index 00000000..f89c1680 --- /dev/null +++ b/src/common/syncableobject.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2005-08 by the Quassel IRC Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _SYNCABLEOBJECT_H_ +#define _SYNCABLEOBJECT_H_ + +#include +#include +#include +#include + +class SyncableObject : public QObject { + Q_OBJECT + + public: + SyncableObject(QObject *parent = 0); + SyncableObject(const SyncableObject &other, QObject *parent = 0); + + //! Stores the object's state into a QVariantMap. + /** The default implementation takes dynamic properties as well as getters that have + * names starting with "init" and stores them in a QVariantMap. Override this method in + * derived classes in order to store the object state in a custom form. + * \Note: This is used by SignalProxy to transmit the state of the object to clients + * that request the initial object state. Later updates use a different mechanism + * and assume that the state is completely covered by properties and init* getters. + * DO NOT OVERRIDE THIS unless you know exactly what you do! + * \return The object's state in a QVariantMap + */ + virtual QVariantMap toVariantMap(); + + //! Initialize the object's state from a given QVariantMap. + /** \see toVarianMap() for important information concerning this method. + */ + virtual void fromVariantMap(const QVariantMap &map); + + private: + bool setInitValue(const QString &property, const QVariant &value); + +}; + +QDataStream &operator<<(QDataStream &out, SyncableObject object); +QDataStream &operator>>(QDataStream &in, SyncableObject &object); + +Q_DECLARE_METATYPE(SyncableObject); + +#endif diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index cd75f660..92eeafe3 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -50,7 +50,8 @@ CoreSession::CoreSession(UserId uid, Storage *_storage, QObject *parent) foreach(IdentityId id, s.identityIds()) { Identity *i = new Identity(s.identity(id), this); if(!i->isValid()) { - qDebug() << QString("Invalid identity!"); + qDebug() << QString("Invalid identity! Removing..."); + s.removeIdentity(id); delete i; continue; }