Implement peer-specific signal sending
authorJanne Koschinski <janne@kuschku.de>
Mon, 28 Aug 2017 01:56:41 +0000 (03:56 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Tue, 19 Dec 2017 22:25:23 +0000 (23:25 +0100)
src/common/signalproxy.cpp
src/common/signalproxy.h
src/core/coresession.cpp
src/core/coresession.h

index 68ac6fb..e37986b 100644 (file)
@@ -159,6 +159,11 @@ int SignalProxy::SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **
             if (argTypes.size() >= 1 && argTypes[0] == qMetaTypeId<PeerPtr>() && proxy()->proxyMode() == SignalProxy::Server) {
                 Peer *peer = params[0].value<PeerPtr>();
                 proxy()->dispatch(peer, RpcCall(signal.signature, params));
+            } else if (proxy()->_restrictMessageTarget) {
+                for (auto peer : proxy()->_restrictedTargets) {
+                    if (peer != nullptr)
+                        proxy()->dispatch(peer, RpcCall(signal.signature, params));
+                }
             } else
                 proxy()->dispatch(RpcCall(signal.signature, params));
         }
@@ -836,6 +841,23 @@ Peer *SignalProxy::peerById(int peerId) {
     return _peerMap[peerId];
 }
 
+/**
+ * This method allows to send a signal only to a limited set of peers
+ * @param peerIds A list of peers that should receive it
+ * @param closure Code you want to execute within of that restricted environment
+ */
+void SignalProxy::restrictTargetPeers(std::initializer_list<Peer *> peers, std::function<void()> closure)
+{
+    auto previousRestrictMessageTarget = _restrictMessageTarget;
+    auto previousRestrictedTargets = _restrictedTargets;
+    _restrictMessageTarget = true;
+    _restrictedTargets = QSet<Peer*>(peers);
+
+    closure();
+
+    _restrictMessageTarget = previousRestrictMessageTarget;
+    _restrictedTargets = previousRestrictedTargets;
+}
 
 // ==================================================
 //  ExtendedMetaObject
index dce008a..b093396 100644 (file)
@@ -77,6 +77,9 @@ public:
     bool isSecure() const { return _secure; }
     void dumpProxyStats();
     void dumpSyncMap(SyncableObject *object);
+
+    void restrictTargetPeers(std::initializer_list<Peer *> peerIds, std::function<void()> closure);
+
     inline int peerCount() const { return _peers.size(); }
     QVariantList peerData();
 
@@ -172,6 +175,9 @@ private:
 
     int _lastPeerId = 0;
 
+    QSet<Peer *> _restrictedTargets;
+    bool _restrictMessageTarget = false;
+
     friend class SignalRelay;
     friend class SyncableObject;
     friend class Peer;
index 635067a..ea584f9 100644 (file)
@@ -106,6 +106,7 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent)
     p->attachSignal(this, SIGNAL(passwordChanged(PeerPtr,bool)));
 
     p->attachSlot(SIGNAL(kickClient(int)), this, SLOT(kickClient(int)));
+    p->attachSignal(this, SIGNAL(disconnectFromCore()));
 
     loadSettings();
     initScriptEngine();
@@ -721,9 +722,15 @@ void CoreSession::changePassword(PeerPtr peer, const QString &userName, const QS
 }
 
 void CoreSession::kickClient(int peerId) {
+    qWarning() << "kickClient(" << peerId << ")";
+
     auto peer = signalProxy()->peerById(peerId);
-    if (!peer) {
+    if (peer == nullptr) {
         qWarning() << "Invalid peer Id: " << peerId;
+        return;
     }
-    peer->close("Terminated by user action");
+    signalProxy()->restrictTargetPeers({peer}, [&]{
+        qWarning() << "executing closure";
+        emit disconnectFromCore();
+    });
 }
index c4de8cc..61b7d22 100644 (file)
@@ -171,6 +171,8 @@ signals:
 
     void passwordChanged(PeerPtr peer, bool success);
 
+    void disconnectFromCore();
+
 protected:
     virtual void customEvent(QEvent *event);