[Telepathy-commits] [telepathy-qt4/master] TextChannel: Implement acknowledge() and forget() (plural forms only)

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Feb 20 09:27:29 PST 2009


---
 TelepathyQt4/Client/text-channel.cpp |   90 ++++++++++++++++++++++++++++++++++
 TelepathyQt4/Client/text-channel.h   |   26 ++--------
 2 files changed, 94 insertions(+), 22 deletions(-)

diff --git a/TelepathyQt4/Client/text-channel.cpp b/TelepathyQt4/Client/text-channel.cpp
index bfe45ba..379c46d 100644
--- a/TelepathyQt4/Client/text-channel.cpp
+++ b/TelepathyQt4/Client/text-channel.cpp
@@ -559,6 +559,7 @@ struct TextChannel::Private
     QList<ReceivedMessage> messages;
     QList<QueuedEvent *> incompleteMessages;
     QSet<uint> awaitingContacts;
+    QHash<QDBusPendingCallWatcher *, UIntList> acknowledgeBatches;
     void contactLost(uint handle);
     void contactFound(QSharedPointer<Contact> contact);
 };
@@ -793,6 +794,95 @@ QList<ReceivedMessage> TextChannel::messageQueue() const
     return mPriv->messages;
 }
 
+void TextChannel::onAcknowledgePendingMessagesReply(
+        QDBusPendingCallWatcher *watcher)
+{
+    UIntList ids = mPriv->acknowledgeBatches.value(watcher);
+    QDBusPendingReply<> reply = *watcher;
+
+    if (reply.isError()) {
+        // One of the IDs was bad, and we can't know which one. Recover by
+        // doing as much as possible, and hope for the best...
+        debug() << "Recovering from AcknowledgePendingMessages failure for: "
+            << ids;
+        foreach (uint id, ids) {
+            textInterface()->AcknowledgePendingMessages(UIntList() << id);
+        }
+    }
+
+    mPriv->acknowledgeBatches.remove(watcher);
+    watcher->deleteLater();
+}
+
+/**
+ * Acknowledge that received messages have been displayed to the user.
+ *
+ * This method should only be called by the main handler of a Channel, usually
+ * meaning the user interface process that displays the Channel to the user
+ * (when a ChannelDispatcher is used, the Handler must acknowledge messages,
+ * and other Approvers or Observers must not acknowledge messages).
+ *
+ * Processes other than the main handler of a Channel can free memory used
+ * in Telepathy-Qt4 by calling forget() instead.
+ *
+ * The messages must have come from this channel, therefore this method does
+ * not make sense if FeatureMessageQueue has not been enabled.
+ *
+ * \param messages A list of received messages that have now been displayed.
+ */
+void TextChannel::acknowledge(const QList<ReceivedMessage> &messages)
+{
+    UIntList ids;
+
+    foreach (const ReceivedMessage &m, messages) {
+        if (m.mPriv->textChannel != this) {
+            warning() << "message did not come from this channel, ignoring";
+        } else {
+            ids << m.mPriv->getUIntOrZero(0, "pending-message-id");
+        }
+    }
+
+    if (ids.isEmpty()) {
+        return;
+    }
+
+    // we're going to acknowledge these messages (or as many as possible, if
+    // we lose a race with another acknowledging process), so let's remove
+    // them from the list immediately
+    forget(messages);
+
+    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
+            textInterface()->AcknowledgePendingMessages(ids));
+    connect(watcher,
+            SIGNAL(finished(QDBusPendingCallWatcher *)),
+            SLOT(onAcknowledgePendingMessagesReply(QDBusPendingCallWatcher *)));
+    mPriv->acknowledgeBatches[watcher] = ids;
+}
+
+/**
+ * Remove messages from messageQueue without acknowledging them.
+ *
+ * This method frees memory inside the Telepathy-Qt4 TextChannel proxy, but
+ * does not free the corresponding memory in the Connection Manager process.
+ * It should be used by clients that are not the main handler for a Channel;
+ * the main handler for a Channel should use acknowledge instead.
+ *
+ * The messages must have come from this channel, therefore this method does
+ * not make sense if FeatureMessageQueue has not been enabled.
+ *
+ * \param messages A list of received messages that have now been processed.
+ */
+void TextChannel::forget(const QList<ReceivedMessage> &messages)
+{
+    foreach (const ReceivedMessage &m, messages) {
+        if (m.mPriv->textChannel != this) {
+            warning() << "message did not come from this channel, ignoring";
+        } else if (mPriv->messages.removeOne(m)) {
+            emit pendingMessageRemoved(m);
+        }
+    }
+}
+
 /**
  * Return whether the desired features are ready for use.
  *
diff --git a/TelepathyQt4/Client/text-channel.h b/TelepathyQt4/Client/text-channel.h
index 2f2ce53..8dad371 100644
--- a/TelepathyQt4/Client/text-channel.h
+++ b/TelepathyQt4/Client/text-channel.h
@@ -137,32 +137,13 @@ public:
     // requires FeatureMessageQueue
     QList<ReceivedMessage> messageQueue() const;
 
-#if 0
 public Q_SLOTS:
 
-    // Asynchronously acknowledge incoming messages, if not already acked, and
-    // remove them from messageQueue.
-    //
-    // Docs must say that only the primary channel handler can do this.
-    //
-    // I don't think we need to bother with a PendingOperation here.
-    //
-    // Implementation: on InvalidArgument, the QList form should fall back to
-    // acknowledging each message individually
-    //
-    // The messages must have come from this channel, therefore this makes no
-    // sense if FeatureMessageQueue isn't enabled.
-    void acknowledge(ReceivedMessage message);
-    void acknowledge(QList<ReceivedMessage> messages);
+    void acknowledge(const QList<ReceivedMessage> &messages);
 
-    // Remove the objects representing incoming messages from messageQueue,
-    // without acknowledging (appropriate for Observers like loggers)
-    //
-    // The messages must have come from this channel, therefore this makes
-    // no sense if FeatureMessageQueue isn't enabled.
-    void forget(ReceivedMessage message);
-    void forget(QList<ReceivedMessage> messages);
+    void forget(const QList<ReceivedMessage> &messages);
 
+#if 0
     // Returns a sent-message token (as in messageSent), or "".
     QString send(const QString &text,
             ChannelTextMessageType type = ChannelTextMessageTypeNormal);
@@ -195,6 +176,7 @@ Q_SIGNALS:
 private Q_SLOTS:
     void onChannelReady(Telepathy::Client::PendingOperation *);
     void onContactsFinished(Telepathy::Client::PendingOperation *);
+    void onAcknowledgePendingMessagesReply(QDBusPendingCallWatcher *);
 
     void onMessageSent(const Telepathy::MessagePartList &, uint,
             const QString &);
-- 
1.5.6.5




More information about the telepathy-commits mailing list