better abstraction of BacklogRequester to support different requesting methods
authorMarcus Eggenberger <egs@quassel-irc.org>
Mon, 27 Oct 2008 13:18:59 +0000 (14:18 +0100)
committerMarcus Eggenberger <egs@quassel-irc.org>
Mon, 27 Oct 2008 13:18:59 +0000 (14:18 +0100)
src/client/CMakeLists.txt
src/client/backlogrequester.cpp
src/client/backlogrequester.h
src/client/client.cpp
src/client/clientbacklogmanager.cpp
src/client/clientbacklogmanager.h
src/common/message.h
src/qtui/mainwin.cpp
src/qtui/mainwin.h

index aa77ae1..f10489f 100644 (file)
@@ -43,6 +43,7 @@ set(MOC_HDRS
     treemodel.h)
 
 set(HEADERS
+    backlogsettings.h
     backlogrequester.h
     buffersettings.h
     clientsettings.h)
index c22b6b6..8b53cf3 100644 (file)
 
 #include "backlogmanager.h"
 
-BacklogRequester::BacklogRequester(BacklogManager *backlogManager)
-  : backlogManager(backlogManager)
+BacklogRequester::BacklogRequester(bool buffering, BacklogManager *backlogManager)
+  : backlogManager(backlogManager),
+    _isBuffering(buffering)
 {
   Q_ASSERT(backlogManager);
 }
 
-// FIXED BACKLOG REQUESTER
-const int FixedBacklogRequester::backlogCount(500);
+bool BacklogRequester::buffer(BufferId bufferId, const MessageList &messages) {
+  _bufferedMessages << messages;
+  _buffersWaiting.remove(bufferId);
+  return !_buffersWaiting.isEmpty();
+}
 
+// ========================================
+//  FIXED BACKLOG REQUESTER
+// ========================================
 FixedBacklogRequester::FixedBacklogRequester(BacklogManager *backlogManager)
-  : BacklogRequester(backlogManager)
+  : BacklogRequester(true, backlogManager),
+    _backlogCount(500)
 {
 }
 
 void FixedBacklogRequester::requestBacklog() {
-  foreach(BufferId bufferId, allBufferIds()) {
-    backlogManager->requestBacklog(bufferId, backlogCount, -1);
+  QList<BufferId> allBuffers = allBufferIds();
+  setWaitingBuffers(allBuffers);
+  foreach(BufferId bufferId, allBuffers) {
+    backlogManager->requestBacklog(bufferId, _backlogCount, -1);
   }
 }
index 5ef71b2..b942d7b 100644 (file)
@@ -24,6 +24,7 @@
 #include <QList>
 
 #include "client.h"
+#include "message.h"
 #include "networkmodel.h"
 #include "types.h"
 
@@ -31,25 +32,47 @@ class BacklogManager;
 
 class BacklogRequester {
 public:
-  BacklogRequester(BacklogManager *backlogManger);
+  enum RequesterTypes {
+    InvalidRequester = 0,
+    GlobalUnread,
+    PerBufferUnread,
+    PerBufferFixed
+  };
+
+  BacklogRequester(bool buffering, BacklogManager *backlogManger);
   virtual inline ~BacklogRequester() {}
 
+  inline bool isBuffering() { return _isBuffering; }
+  inline const QList<Message> &bufferedMessages() { return _bufferedMessages; }
+
+  //! returns false if it was the last missing backlogpart
+  bool buffer(BufferId bufferId, const MessageList &messages);
+  
   virtual void requestBacklog() = 0;
 
 protected:
   inline QList<BufferId> allBufferIds() const { return Client::networkModel()->allBufferIds(); }
+  inline void setWaitingBuffers(const QList<BufferId> &buffers) { _buffersWaiting = buffers.toSet(); }
+  inline void setWaitingBuffers(const QSet<BufferId> &buffers) { _buffersWaiting = buffers; }
+  inline void addWaitingBuffer(BufferId buffer) { _buffersWaiting << buffer; }
   BacklogManager *backlogManager;
-};
 
+private:
+  bool _isBuffering;
+  MessageList _bufferedMessages;
+  QSet<BufferId> _buffersWaiting;
+};
 
+// ========================================
+//  FIXED BACKLOG REQUESTER
+// ========================================
 class FixedBacklogRequester : public BacklogRequester {
 public:
   FixedBacklogRequester(BacklogManager *backlogManager);
-
   virtual void requestBacklog();
 
 private:
-  static const int backlogCount;
+  int _backlogCount;
 };
 
 
index b17fa28..19f0c5e 100644 (file)
@@ -302,7 +302,6 @@ void Client::disconnectedFromCore() {
   emit disconnected();
   emit coreConnectionStateChanged(false);
 
-  backlogManager()->reset();
   messageProcessor()->reset();
 
   // Clear internal data. Hopefully nothing relies on it at this point.
index b485726..f28913f 100644 (file)
 #include "clientbacklogmanager.h"
 
 #include "abstractmessageprocessor.h"
+#include "backlogsettings.h"
 #include "backlogrequester.h"
 #include "client.h"
 
-#include <QDebug>
 #include <ctime>
 
 ClientBacklogManager::ClientBacklogManager(QObject *parent)
   : BacklogManager(parent),
-    _buffer(true)
+    _requester(0)
 {
 }
 
@@ -40,46 +40,62 @@ void ClientBacklogManager::receiveBacklog(BufferId bufferId, int lastMsgs, int o
   if(msgs.isEmpty())
     return;
 
-  //QTime start = QTime::currentTime();
-  QList<Message> msglist;
+  MessageList msglist;
   foreach(QVariant v, msgs) {
     Message msg = v.value<Message>();
     msg.setFlags(msg.flags() | Message::Backlog);
     msglist << msg;
   }
 
-  if(_buffer) {
-    _messageBuffer << msglist;
-    _buffersWaiting.remove(bufferId);
-    if(_buffersWaiting.isEmpty()) {
-      _buffer = false;
-      clock_t start_t = clock();
-      qSort(_messageBuffer);
-      Client::messageProcessor()->process(_messageBuffer);
-      clock_t end_t = clock();
-      qDebug() << "Processed" << _messageBuffer.count() << "Messages in" << (float)(end_t - start_t) / CLOCKS_PER_SEC << "seconds ==" << end_t - start_t << "clocks.";
-      _messageBuffer.clear();
+  if(isBuffering()) {
+    if(!_requester->buffer(bufferId, msglist)) {
+      // this was the last part to buffer
+      stopBuffering();
     }
   } else {
-    Client::messageProcessor()->process(msglist);
+    dispatchMessages(msglist);
   }
-  //qDebug() << "processed" << msgs.count() << "backlog lines in" << start.msecsTo(QTime::currentTime());
 }
 
-QVariantList ClientBacklogManager::requestBacklog(BufferId bufferId, int lastMsgs, int offset) {
-  if(_buffer)
-    _buffersWaiting << bufferId;
+void ClientBacklogManager::requestInitialBacklog() {
+  if(_requester) {
+    qWarning() << "ClientBacklogManager::requestInitialBacklog() called twice in the same session! (Backlog has already been requested)";
+    return;
+  }
 
-  return BacklogManager::requestBacklog(bufferId, lastMsgs, offset);
+  BacklogSettings settings;
+  switch(settings.requesterType()) {
+  case BacklogRequester::GlobalUnread:
+  case BacklogRequester::PerBufferUnread:
+  case BacklogRequester::PerBufferFixed:
+  default:
+    _requester = new FixedBacklogRequester(this);
+  };
+
+  _requester->requestBacklog();
 }
 
-void ClientBacklogManager::requestInitialBacklog() {
-  FixedBacklogRequester backlogRequester(this);
-  backlogRequester.requestBacklog();
+void ClientBacklogManager::stopBuffering() {
+  Q_ASSERT(_requester);
+
+  dispatchMessages(_requester->bufferedMessages(), true);
+
+  delete _requester;
+  _requester = 0;
+}
+
+bool ClientBacklogManager::isBuffering() {
+  return _requester && _requester->isBuffering();
 }
 
-void ClientBacklogManager::reset() {
-  _buffer = true;
-  _messageBuffer.clear();
-  _buffersWaiting.clear();
+void ClientBacklogManager::dispatchMessages(const MessageList &messages, bool sort) {
+  MessageList msgs = messages;
+
+  clock_t start_t = clock();
+  if(sort)
+    qSort(msgs);
+  Client::messageProcessor()->process(msgs);
+  clock_t end_t = clock();
+
+  emit messagesProcessed(tr("Processed %1 messages in %2 seconds.").arg(msgs.count()).arg((float)(end_t - start_t) / CLOCKS_PER_SEC));
 }
index ae6b147..2fb6a2d 100644 (file)
@@ -24,6 +24,8 @@
 #include "backlogmanager.h"
 #include "message.h"
 
+class BacklogRequester;
+
 class ClientBacklogManager : public BacklogManager {
   Q_OBJECT
 
@@ -34,15 +36,18 @@ public:
 
 public slots:
   virtual void receiveBacklog(BufferId bufferId, int lastMsgs, int offset, QVariantList msgs);
-  virtual QVariantList requestBacklog(BufferId bufferId, int lastMsgs = -1, int offset = -1);
   void requestInitialBacklog();
 
-  void reset();
+signals:
+  void messagesProcessed(const QString &);
 
 private:
-  bool _buffer;
-  QList<Message> _messageBuffer;
-  QSet<BufferId> _buffersWaiting;
+  bool isBuffering();
+  void stopBuffering();
+
+  void dispatchMessages(const MessageList &messages, bool sort = false);
+
+  BacklogRequester *_requester;
 };
 
 #endif // CLIENTBACKLOGMANAGER_H
index 6f74028..4d283ad 100644 (file)
@@ -93,6 +93,8 @@ private:
   friend QDataStream &operator>>(QDataStream &in, Message &msg);
 };
 
+typedef QList<Message> MessageList;
+
 QDataStream &operator<<(QDataStream &out, const Message &msg);
 QDataStream &operator>>(QDataStream &in, Message &msg);
 QDebug operator<<(QDebug dbg, const Message &msg);
index 5f302a9..5137447 100644 (file)
@@ -410,6 +410,8 @@ void MainWin::setupStatusBar() {
 
   connect(showStatusbar, SIGNAL(toggled(bool)), statusBar(), SLOT(setVisible(bool)));
   connect(showStatusbar, SIGNAL(toggled(bool)), this, SLOT(saveStatusBarStatus(bool)));
+
+  connect(Client::backlogManager(), SIGNAL(messagesProcessed(const QString &)), this, SLOT(showStatusBarMessage(const QString &)));
 }
 
 void MainWin::saveStatusBarStatus(bool enabled) {
@@ -745,3 +747,7 @@ void MainWin::saveStateToSessionSettings(SessionSettings & s)
   s.setValue("MainWinPos", pos());
   s.setValue("MainWinState", saveState());
 }
+
+void MainWin::showStatusBarMessage(const QString &message) {
+  statusBar()->showMessage(message, 10);
+}
index 1bff138..74953c0 100644 (file)
@@ -56,6 +56,7 @@ class MainWin : public QMainWindow {
   public slots:
     void saveStateToSession(const QString &sessionId);
     void saveStateToSessionSettings(SessionSettings &s);
+    void showStatusBarMessage(const QString &message);
 
   protected:
     void closeEvent(QCloseEvent *event);