+void SignalProxy::detachSlots(QObject *receiver)
+{
+ SlotHash::iterator slotIter = _attachedSlots.begin();
+ while (slotIter != _attachedSlots.end()) {
+ if (slotIter.value().first == receiver) {
+ slotIter = _attachedSlots.erase(slotIter);
+ }
+ else
+ slotIter++;
+ }
+}
+
+
+void SignalProxy::stopSynchronize(SyncableObject *obj)
+{
+ // we can't use a className here, since it might be effed up, if we receive the call as a result of a decon
+ // gladly the objectName() is still valid. So we have only to iterate over the classes not each instance! *sigh*
+ QHash<QByteArray, ObjectId>::iterator classIter = _syncSlave.begin();
+ while (classIter != _syncSlave.end()) {
+ if (classIter->contains(obj->objectName()) && classIter.value()[obj->objectName()] == obj) {
+ classIter->remove(obj->objectName());
+ break;
+ }
+ classIter++;
+ }
+ obj->stopSynchronize(this);
+}
+
+
+template<class T>
+void SignalProxy::dispatch(const T &protoMessage)
+{
+ foreach (AbstractPeer *peer, _peers) {
+ if (peer->isOpen())
+ peer->dispatch(protoMessage);
+ else
+ QCoreApplication::postEvent(this, new ::RemovePeerEvent(peer));
+ }
+}
+
+
+void SignalProxy::handle(SignalProxy::AbstractPeer *peer, const SyncMessage &syncMessage)
+{
+ if (!_syncSlave.contains(syncMessage.className()) || !_syncSlave[syncMessage.className()].contains(syncMessage.objectName())) {
+ qWarning() << QString("no registered receiver for sync call: %1::%2 (objectName=\"%3\"). Params are:").arg(syncMessage.className(), syncMessage.slotName(), syncMessage.objectName())
+ << syncMessage.params();
+ return;
+ }
+
+ SyncableObject *receiver = _syncSlave[syncMessage.className()][syncMessage.objectName()];
+ ExtendedMetaObject *eMeta = extendedMetaObject(receiver);
+ if (!eMeta->slotMap().contains(syncMessage.slotName())) {
+ qWarning() << QString("no matching slot for sync call: %1::%2 (objectName=\"%3\"). Params are:").arg(syncMessage.className(), syncMessage.slotName(), syncMessage.objectName())
+ << syncMessage.params();
+ return;
+ }
+
+ int slotId = eMeta->slotMap()[syncMessage.slotName()];
+ if (proxyMode() != eMeta->receiverMode(slotId)) {
+ qWarning("SignalProxy::handleSync(): invokeMethod for \"%s\" failed. Wrong ProxyMode!", eMeta->methodName(slotId).constData());
+ return;
+ }
+
+ QVariant returnValue((QVariant::Type)eMeta->returnType(slotId));
+ if (!invokeSlot(receiver, slotId, syncMessage.params(), returnValue)) {
+ qWarning("SignalProxy::handleSync(): invokeMethod for \"%s\" failed ", eMeta->methodName(slotId).constData());
+ return;
+ }
+
+ if (returnValue.type() != QVariant::Invalid && eMeta->receiveMap().contains(slotId)) {
+ int receiverId = eMeta->receiveMap()[slotId];
+ QVariantList returnParams;
+ if (eMeta->argTypes(receiverId).count() > 1)
+ returnParams << syncMessage.params();
+ returnParams << returnValue;
+ peer->dispatch(SyncMessage(syncMessage.className(), syncMessage.objectName(), eMeta->methodName(receiverId), returnParams));
+ }
+
+ // send emit update signal
+ invokeSlot(receiver, eMeta->updatedRemotelyId());
+}
+
+
+void SignalProxy::handle(SignalProxy::AbstractPeer *peer, const InitRequest &initRequest)
+{
+ if (!_syncSlave.contains(initRequest.className())) {
+ qWarning() << "SignalProxy::handleInitRequest() received initRequest for unregistered Class:"
+ << initRequest.className();
+ return;
+ }
+
+ if (!_syncSlave[initRequest.className()].contains(initRequest.objectName())) {
+ qWarning() << "SignalProxy::handleInitRequest() received initRequest for unregistered Object:"
+ << initRequest.className() << initRequest.objectName();
+ return;
+ }
+
+ SyncableObject *obj = _syncSlave[initRequest.className()][initRequest.objectName()];
+ peer->dispatch(InitData(initRequest.className(), initRequest.objectName(), initData(obj)));
+}
+
+
+void SignalProxy::handle(SignalProxy::AbstractPeer *peer, const InitData &initData)
+{
+ Q_UNUSED(peer)
+
+ if (!_syncSlave.contains(initData.className())) {
+ qWarning() << "SignalProxy::handleInitData() received initData for unregistered Class:"
+ << initData.className();
+ return;
+ }
+
+ if (!_syncSlave[initData.className()].contains(initData.objectName())) {
+ qWarning() << "SignalProxy::handleInitData() received initData for unregistered Object:"
+ << initData.className() << initData.objectName();
+ return;
+ }
+
+ SyncableObject *obj = _syncSlave[initData.className()][initData.objectName()];
+ setInitData(obj, initData.initData());
+}
+
+
+void SignalProxy::handle(SignalProxy::AbstractPeer *peer, const RpcCall &rpcCall)
+{
+ Q_UNUSED(peer)
+
+ QObject *receiver;
+ int methodId;
+ SlotHash::const_iterator slot = _attachedSlots.constFind(rpcCall.slotName());
+ while (slot != _attachedSlots.constEnd() && slot.key() == rpcCall.slotName()) {
+ receiver = (*slot).first;
+ methodId = (*slot).second;
+ if (!invokeSlot(receiver, methodId, rpcCall.params())) {
+ ExtendedMetaObject *eMeta = extendedMetaObject(receiver);
+ qWarning("SignalProxy::handleSignal(): invokeMethod for \"%s\" failed ", eMeta->methodName(methodId).constData());
+ }
+ ++slot;
+ }