+ bool isSecure() const { return _secure; }
+ void dumpProxyStats();
+
+public slots:
+ void detachObject(QObject *obj);
+ void detachSignals(QObject *sender);
+ void detachSlots(QObject *receiver);
+ void stopSync(QObject *obj);
+
+protected:
+ void customEvent(QEvent *event);
+
+private slots:
+ void dataAvailable();
+ void removePeerBySender();
+ void objectRenamed(const QString &newname, const QString &oldname);
+ void objectRenamed(const QByteArray &classname, const QString &newname, const QString &oldname);
+ void sendHeartBeat();
+ void receiveHeartBeat(AbstractPeer *peer, const QVariantList ¶ms);
+ void receiveHeartBeatReply(AbstractPeer *peer, const QVariantList ¶ms);
+
+ void updateSecureState();
+
+signals:
+ void peerRemoved(QIODevice *dev);
+ void connected();
+ void disconnected();
+ void objectInitialized(SyncableObject *);
+ void lagUpdated(int lag);
+ void securityChanged(bool);
+ void secureStateChanged(bool);
+
+private:
+ void init();
+ void initServer();
+ void initClient();
+
+ static const QMetaObject *metaObject(const QObject *obj);
+
+ 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());
+
+ void requestInit(SyncableObject *obj);
+ 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:
+ static void disconnectDevice(QIODevice *dev, const QString &reason = QString());
+
+ // 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;
+
+ // containg a list of argtypes for fast access
+ QHash<const QMetaObject *, ExtendedMetaObject *> _extendedMetaObjects;
+
+ // SignalRelay for all manually attached signals
+ SignalRelay *_signalRelay;
+ // one SyncRelay per class
+ QHash<const QMetaObject *, SyncRelay *> _syncRelays;
+
+ // RPC function -> (object, slot ID)
+ typedef QPair<QObject*, int> MethodId;
+ typedef QMultiHash<QByteArray, MethodId> SlotHash;
+ SlotHash _attachedSlots;
+
+ // slaves for sync
+ typedef QHash<QString, SyncableObject *> ObjectId;
+ QHash<QByteArray, ObjectId> _syncSlave;
+
+
+ ProxyMode _proxyMode;
+ QTimer _heartBeatTimer;
+
+ bool _secure; // determines if all connections are in a secured state (using ssl or internal connections)
+
+ friend class SignalRelay;
+};
+
+
+// ==================================================
+// ExtendedMetaObject
+// ==================================================
+class SignalProxy::ExtendedMetaObject {
+public:
+ ExtendedMetaObject(const QMetaObject *meta);
+
+ const QList<int> &argTypes(int methodId);
+ const int &returnType(int methodId);
+ const int &minArgCount(int methodId);
+ const QByteArray &methodName(int methodId);
+ const QHash<QByteArray, int> &syncMap();
+ const QHash<int, int> &receiveMap();
+ int updatedRemotelyId();
+
+ const QMetaObject *metaObject() const { return _meta; }
+
+ static QByteArray methodName(const QMetaMethod &method);
+ static bool methodsMatch(const QMetaMethod &signal, const QMetaMethod &slot);
+ static QString methodBaseName(const QMetaMethod &method);
+
+private:
+ typedef QHash<int, QList<int> > ArgHash;
+ typedef QHash<int, QByteArray> MethodNameHash;
+
+ const QMetaObject *_meta;
+ ArgHash _argTypes;
+ QHash<int, int> _returnType;
+ QHash<int, int> _minArgCount;
+ MethodNameHash _methodNames;
+ int _updatedRemotelyId; // id of the updatedRemotely() signal - makes things faster
+ QHash<QByteArray, int> _syncMap;
+ QHash<int, int> _receiveMap;