+ void dispatchSignal(QIODevice *receiver, const RequestType &requestType, const QVariantList ¶ms);
+ void dispatchSignal(const RequestType &requestType, const QVariantList ¶ms);
+
+ void receivePackedFunc(AbstractPeer *sender, const QVariant &packedFunc);
+ void receivePeerSignal(AbstractPeer *sender, const RequestType &requestType, const QVariantList ¶ms);
+ void receivePeerSignal(SignalProxy *sender, const RequestType &requestType, const QVariantList ¶ms);
+ void handleSync(AbstractPeer *sender, QVariantList params);
+ void handleInitRequest(AbstractPeer *sender, const QVariantList ¶ms);
+ void handleInitData(AbstractPeer *sender, const QVariantList ¶ms);
+ void handleSignal(const QVariantList &data);
+
+ bool invokeSlot(QObject *receiver, int methodId, const QVariantList ¶ms, QVariant &returnValue);
+ bool invokeSlot(QObject *receiver, int methodId, const QVariantList ¶ms = QVariantList());
+
+ QVariantMap initData(SyncableObject *obj) const;
+ void setInitData(SyncableObject *obj, const QVariantMap &properties);
+
+ void updateLag(IODevicePeer *peer, int lag);
+
+public:
+ void dumpSyncMap(SyncableObject *object);
+ inline int peerCount() const { return _peers.size(); }
+
+private:
+ class AbstractPeer {
+ public:
+ enum PeerType {
+ NotAPeer = 0,
+ IODevicePeer = 1,
+ SignalProxyPeer = 2
+ };
+ AbstractPeer() : _type(NotAPeer) {}
+ AbstractPeer(PeerType type) : _type(type) {}
+ virtual ~AbstractPeer() {}
+ inline PeerType type() const { return _type; }
+ virtual void dispatchSignal(const RequestType &requestType, const QVariantList ¶ms) = 0;
+ private:
+ PeerType _type;
+ };
+
+ class IODevicePeer : public AbstractPeer {
+ public:
+ IODevicePeer(QIODevice *device, bool compress) : AbstractPeer(AbstractPeer::IODevicePeer), _device(device), byteCount(0), usesCompression(compress), sentHeartBeats(0), lag(0) {}
+ virtual void dispatchSignal(const RequestType &requestType, const QVariantList ¶ms);
+ inline void dispatchPackedFunc(const QVariant &packedFunc) { SignalProxy::writeDataToDevice(_device, packedFunc, usesCompression); }
+ QString address() const;
+ inline bool isOpen() const { return _device->isOpen(); }
+ inline void close() const { _device->close(); }
+ inline bool readData(QVariant &item) { return SignalProxy::readDataFromDevice(_device, byteCount, item, usesCompression); }
+ private:
+ QIODevice *_device;
+ quint32 byteCount;
+ bool usesCompression;
+ public:
+ int sentHeartBeats;
+ int lag;
+ };
+
+ class SignalProxyPeer : public AbstractPeer {
+ public:
+ SignalProxyPeer(SignalProxy *sender, SignalProxy *receiver) : AbstractPeer(AbstractPeer::SignalProxyPeer), sender(sender), receiver(receiver) {}
+ virtual void dispatchSignal(const RequestType &requestType, const QVariantList ¶ms);
+ private:
+ SignalProxy *sender;
+ SignalProxy *receiver;
+ };
+
+ // a Hash of the actual used communication object to it's corresponding peer
+ // currently a communication object can either be an arbitrary QIODevice or another SignalProxy
+ typedef QHash<QObject *, AbstractPeer *> PeerHash;
+ PeerHash _peers;