[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdepimlibs/akonadi
From:       Volker Krause <vkrause () kde ! org>
Date:       2010-12-20 10:48:36
Message-ID: 20101220104836.BF69AAC8AA () svn ! kde ! org
[Download RAW message or body]

SVN commit 1208024 by vkrause:

Make sure the change recorder cannot get stuck if one of its signal is
disconnected. Incoming notifications were filtered for that already, now
it also works for signals that are disconnected while the corresponding
notification is already in the queue. This is necessary for further
optimizations in AgentBase for not implemented Observer methods.


 M  +6 -0      changerecorder.h  
 M  +8 -0      changerecorder_p.h  
 M  +50 -20    monitor_p.cpp  
 M  +15 -3     monitor_p.h  


--- trunk/KDE/kdepimlibs/akonadi/changerecorder.h #1208023:1208024
@@ -36,6 +36,12 @@
  * is online again. Therefore the agent doesn't have to care about
  * online/offline mode in its synchronization algorithm.
  *
+ * Unlike Akonadi::Monitor this class only emits one change signal at a
+ * time. To receive the next one you need to explicitly call replayNext().
+ * If a signal is emitted that has no receivers, it's automatically skipped,
+ * which means you only need to connect to signals you are actually interested
+ * in.
+ *
  * @author Volker Krause <vkrause@kde.org>
  */
 class AKONADI_EXPORT ChangeRecorder : public Monitor
--- trunk/KDE/kdepimlibs/akonadi/changerecorder_p.h #1208023:1208024
@@ -55,6 +55,14 @@
       }
     }
 
+    virtual bool emitNotification(const Akonadi::NotificationMessage& msg)
+    {
+      const bool someoneWasListening = MonitorPrivate::emitNotification( msg );
+      if ( !someoneWasListening && enableChangeRecording )
+        QMetaObject::invokeMethod( q_ptr, "replayNext", Qt::QueuedConnection ); // \
skip notifications noone was listening to +      return someoneWasListening;
+    }
+
     void loadNotifications()
     {
       pendingNotifications.clear();
--- trunk/KDE/kdepimlibs/akonadi/monitor_p.cpp #1208023:1208024
@@ -252,7 +252,7 @@
   return allCached;
 }
 
-void MonitorPrivate::emitNotification( const NotificationMessage &msg )
+bool MonitorPrivate::emitNotification( const NotificationMessage &msg )
 {
   const Collection parent = collectionCache.retrieve( msg.parentCollection() );
   Collection destParent;
@@ -261,11 +261,13 @@
 
   if ( msg.type() == NotificationMessage::Collection ) {
     const Collection col = collectionCache.retrieve( msg.uid() );
-    emitCollectionNotification( msg, col, parent, destParent );
+    return emitCollectionNotification( msg, col, parent, destParent );
   } else if ( msg.type() == NotificationMessage::Item ) {
     const Item item = itemCache.retrieve( msg.uid() );
-    emitItemNotification( msg, item, parent, destParent );
+    return emitItemNotification( msg, item, parent, destParent );
   }
+
+  return false; // nothing emitted
 }
 
 void MonitorPrivate::dataAvailable()
@@ -370,7 +372,7 @@
   dispatchNotifications();
 }
 
-void MonitorPrivate::emitItemNotification( const NotificationMessage &msg, const \
Item &item, +bool MonitorPrivate::emitItemNotification( const NotificationMessage \
                &msg, const Item &item,
                                              const Collection &collection, const \
Collection &collectionDest  )  {
   Q_ASSERT( msg.type() == NotificationMessage::Item );
@@ -420,30 +422,43 @@
 
   switch ( msg.operation() ) {
     case NotificationMessage::Add:
+      if ( q_ptr->receivers( SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)) ) \
== 0 ) +        return false;
       emit q_ptr->itemAdded( it, col );
-      break;
+      return true;
     case NotificationMessage::Modify:
+      if ( q_ptr->receivers( SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)) ) \
== 0 ) +        return false;
       emit q_ptr->itemChanged( it, msg.itemParts() );
-      break;
+      return true;
     case NotificationMessage::Move:
+      if ( q_ptr->receivers( \
SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)) ) == 0 ) +   \
return false;  emit q_ptr->itemMoved( it, col, colDest );
-      break;
+      return true;
     case NotificationMessage::Remove:
+      if ( q_ptr->receivers( SIGNAL(itemRemoved(Akonadi::Item)) ) == 0 )
+        return false;
       emit q_ptr->itemRemoved( it );
-      break;
+      return true;
     case NotificationMessage::Link:
+      if ( q_ptr->receivers( SIGNAL(itemLinked(Akonadi::Item,Akonadi::Collection)) ) \
== 0 ) +        return false;
       emit q_ptr->itemLinked( it, col );
-      break;
+      return true;
     case NotificationMessage::Unlink:
+      if ( q_ptr->receivers( SIGNAL(itemUnlinked(Akonadi::Item,Akonadi::Collection)) \
) == 0 ) +        return false;
       emit q_ptr->itemUnlinked( it, col );
-      break;
+      return true;;
     default:
       kDebug() << "Unknown operation type" << msg.operation() << "in item change \
                notification";
-      break;
   }
+
+  return false;
 }
 
-void MonitorPrivate::emitCollectionNotification( const NotificationMessage &msg, \
const Collection &col, +bool MonitorPrivate::emitCollectionNotification( const \
                NotificationMessage &msg, const Collection &col,
                                                    const Collection &par, const \
Collection &dest )  {
   Q_ASSERT( msg.type() == NotificationMessage::Collection );
@@ -487,29 +502,44 @@
 
   switch ( msg.operation() ) {
     case NotificationMessage::Add:
+      if ( q_ptr->receivers( \
SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)) ) == 0 ) +        \
return false;  emit q_ptr->collectionAdded( collection, parent );
-      break;
+      return true;
     case NotificationMessage::Modify:
+      if ( q_ptr->receivers( SIGNAL(collectionChanged(Akonadi::Collection)) ) == 0
+        && q_ptr->receivers( \
SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)) ) == 0 ) +        \
return false;  emit q_ptr->collectionChanged( collection );
       emit q_ptr->collectionChanged( collection, msg.itemParts() );
-      break;
+      return true;
     case NotificationMessage::Move:
+      if ( q_ptr->receivers( \
SIGNAL(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)) \
) == 0 ) +        return false;
       emit q_ptr->collectionMoved( collection, parent, destination );
-      break;
+      return true;
     case NotificationMessage::Remove:
+      if ( q_ptr->receivers( SIGNAL(collectionRemoved(Akonadi::Collection)) ) == 0 )
+        return false;
       emit q_ptr->collectionRemoved( collection );
-      break;
+      return true;
     case NotificationMessage::Subscribe:
-      if ( !monitorAll )
+      if ( q_ptr->receivers( \
SIGNAL(collectionSubscribed(Akonadi::Collection,Akonadi::Collection)) ) == 0 ) +      \
return false; +      if ( !monitorAll ) // ### why??
         emit q_ptr->collectionSubscribed( collection, parent );
-      break;
+      return true;
     case NotificationMessage::Unsubscribe:
-      if ( !monitorAll )
+      if ( q_ptr->receivers( SIGNAL(collectionUnsubscribed(Akonadi::Collection)) ) \
== 0 ) +        return false;
+      if ( !monitorAll ) // ### why??
         emit q_ptr->collectionUnsubscribed( collection );
-      break;
+      return true;
     default:
       kDebug() << "Unknown operation type" << msg.operation() << "in collection \
change notification";  }
+
+  return false;
 }
 
 void MonitorPrivate::invalidateCaches( const NotificationMessage &msg )
--- trunk/KDE/kdepimlibs/akonadi/monitor_p.h #1208023:1208024
@@ -81,7 +81,11 @@
     void cleanOldNotifications();
 
     bool ensureDataAvailable( const NotificationMessage &msg );
-    void emitNotification( const NotificationMessage &msg );
+    /**
+     * Sends out the change notification @p msg.
+     * @return @c true if the notification was actually send to someone, @c false if \
noone was listening. +     */
+    virtual bool emitNotification( const NotificationMessage &msg );
     void updatePendingStatistics( const NotificationMessage &msg );
     void invalidateCaches( const NotificationMessage &msg );
 
@@ -102,9 +106,17 @@
 
     virtual void slotNotify( const NotificationMessage::List &msgs );
 
-    void emitItemNotification( const NotificationMessage &msg, const Item &item = \
Item(), +    /**
+     * Sends out a change notification for an item.
+     * @return @c true if the notification was actually send to someone, @c false if \
noone was listening. +     */
+    bool emitItemNotification( const NotificationMessage &msg, const Item &item = \
                Item(),
                                const Collection &collection = Collection(), const \
                Collection &collectionDest = Collection() );
-    void emitCollectionNotification( const NotificationMessage &msg, const \
Collection &col = Collection(), +    /**
+     * Sends out a change notification for a collection.
+     * @return @c true if the notification was actually send to someone, @c false if \
noone was listening. +     */
+    bool emitCollectionNotification( const NotificationMessage &msg, const \
                Collection &col = Collection(),
                                      const Collection &par = Collection(), const \
Collection &dest = Collection() );  
     void serverStateChanged( Akonadi::ServerManager::State state );


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic