X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fsignalproxy.cpp;h=b3ea4ffbc9e0b30b7180c23708ac283a32e0fd35;hp=85f053b25fae92ed30af9e81bd1a53b41d9a0c21;hb=efe20e20080a0c22e1a7b8b84ef622130dbf116e;hpb=5c35ac3ee6f951d39cc052925aa224debfa148a8 diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index 85f053b2..b3ea4ffb 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -34,10 +34,22 @@ #include #include #include +#include +#include #include "syncableobject.h" #include "util.h" +// ================================================== +// PeerSignalEvent +// ================================================== +class PeerSignalEvent : public QEvent { +public: + PeerSignalEvent(SignalProxy *sender, SignalProxy::RequestType requestType, const QVariantList ¶ms) : QEvent(QEvent::User), sender(sender), requestType(requestType), params(params) {} + SignalProxy *sender; + SignalProxy::RequestType requestType; + QVariantList params; +}; // ================================================== // SIGNALRELAY @@ -194,6 +206,18 @@ void SignalProxy::IODevicePeer::dispatchSignal(const RequestType &requestType, c dispatchPackedFunc(QVariant(packedFunc)); } +void SignalProxy::SignalProxyPeer::dispatchSignal(const RequestType &requestType, const QVariantList ¶ms) { + Qt::ConnectionType type = QThread::currentThread() == receiver->thread() + ? Qt::DirectConnection + : Qt::QueuedConnection; + + if(type == Qt::DirectConnection) { + receiver->receivePeerSignal(sender, requestType, params); + } else { + QCoreApplication::postEvent(receiver, new PeerSignalEvent(sender, requestType, params)); + } +} + // ================================================== // SignalProxy // ================================================== @@ -293,6 +317,34 @@ bool SignalProxy::addPeer(QIODevice* iodev) { return true; } +bool SignalProxy::addPeer(SignalProxy* proxy) { + if(!proxy) + return false; + + if(proxyMode() == proxy->proxyMode()) { + qWarning() << "SignalProxy::addPeer(): adding a SignalProxy as peer requires one proxy to be server and one client!"; + return false; + } + + if(_peers.contains(proxy)) { + return true; + } + + if(proxyMode() == Client && !_peers.isEmpty()) { + qWarning("SignalProxy: only one peer allowed in client mode!"); + return false; + } + + _peers[proxy] = new SignalProxyPeer(this, proxy); + + proxy->addPeer(this); + + if(_peers.count() == 1) + emit connected(); + + return true; +} + void SignalProxy::removeAllPeers() { Q_ASSERT(proxyMode() == Server || _peers.count() <= 1); // wee need to copy that list since we modify it in the loop @@ -748,6 +800,15 @@ void SignalProxy::receivePeerSignal(AbstractPeer *sender, const RequestType &req } } +void SignalProxy::receivePeerSignal(SignalProxy *sender, const RequestType &requestType, const QVariantList ¶ms) { + if(!_peers.contains(sender)) { + // we output only the pointer value. otherwise Qt would try to pretty print. As the object might already been destroyed, this is not a good idea. + qWarning() << "SignalProxy::receivePeerSignal(): received Signal from unknown Proxy" << reinterpret_cast(sender); + return; + } + receivePeerSignal(_peers[sender], requestType, params); +} + void SignalProxy::handleSync(AbstractPeer *sender, QVariantList params) { if(params.count() < 3) { qWarning() << "received invalid Sync call" << params; @@ -1112,6 +1173,20 @@ void SignalProxy::receiveHeartBeatReply(AbstractPeer *peer, const QVariantList & updateLag(ioPeer, sendTime.msecsTo(QTime::currentTime()) / 2); } +void SignalProxy::customEvent(QEvent *event) { + switch(event->type()) { + case QEvent::User: + { + PeerSignalEvent *sig = static_cast(event); + receivePeerSignal(sig->sender, sig->requestType, sig->params); + } + event->accept(); + break; + default: + return; + } +} + void SignalProxy::updateLag(IODevicePeer *peer, int lag) { peer->lag = lag; if(proxyMode() == Client) {