Explorar o código

Automatically disconnect service listeners on QObject::destroyed()

Sascha Zelzer %!s(int64=14) %!d(string=hai) anos
pai
achega
b208ab9e53

+ 6 - 1
Libs/PluginFramework/ctkPluginContext.h

@@ -492,7 +492,12 @@ public:
    * the filter syntax.
    *
    * <p>
-   * If the context plugin's list of listeners already contains a the same
+   * If the object to connect to is destroyed, the slot is automatically
+   * disconnected. To explicitly disconnect the slot, use
+   * disconnectServiceListener().
+   *
+   * <p>
+   * If the context plugin's list of listeners already contains the same
    * slot for the given receiver, then this
    * method replaces that slot's filter (which may be <code>null</code>)
    * with the specified one (which may be <code>null</code>).

+ 8 - 1
Libs/PluginFramework/ctkPluginFrameworkListeners.cpp

@@ -56,6 +56,8 @@ void ctkPluginFrameworkListeners::addServiceSlot(
   }
   serviceSet.insert(sse);
   checkSimple(sse);
+
+  connect(receiver, SIGNAL(destroyed(QObject*)), this, SLOT(serviceListenerDestroyed(QObject*)));
 }
 
 void ctkPluginFrameworkListeners::removeServiceSlot(ctkPlugin* plugin,
@@ -75,11 +77,16 @@ void ctkPluginFrameworkListeners::removeServiceSlot(ctkPlugin* plugin,
       //listeners.framework.hooks.handleServiceListenerUnreg(sle);
       removeFromCache(currentEntry);
       it.remove();
-      break;
+      if (slot) break;
     }
   }
 }
 
+void ctkPluginFrameworkListeners::serviceListenerDestroyed(QObject *listener)
+{
+  this->removeServiceSlot(0, listener, 0);
+}
+
 QSet<ctkServiceSlotEntry> ctkPluginFrameworkListeners::getMatchingServiceSlots(
     const ctkServiceReference& sr)
 {

+ 4 - 0
Libs/PluginFramework/ctkPluginFrameworkListeners_p.h

@@ -100,6 +100,10 @@ signals:
 
   void frameworkEvent(const ctkPluginFrameworkEvent& event);
 
+private slots:
+
+  void serviceListenerDestroyed(QObject* listener);
+
 private:
 
   QMutex mutex;

+ 2 - 2
Libs/PluginFramework/ctkServiceSlotEntry.cpp

@@ -105,9 +105,9 @@ ctkServiceSlotEntry::~ctkServiceSlotEntry()
 
 bool ctkServiceSlotEntry::operator==(const ctkServiceSlotEntry& other) const
 {
-  return d->plugin == other.d->plugin &&
+  return ((d->plugin == 0 || other.d->plugin == 0) || d->plugin == other.d->plugin) &&
          d->receiver == other.d->receiver &&
-         std::strcmp(d->slot, other.d->slot) == 0;
+         ((d->slot == 0 || other.d->slot == 0) || std::strcmp(d->slot, other.d->slot) == 0);
 }
 
 void ctkServiceSlotEntry::invokeSlot(const ctkServiceEvent &event)