From 92f256c9ef102ef5af61164bb17b63e501510541 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Tue, 17 Mar 2009 19:22:11 +0100 Subject: [PATCH] no longer requesting backlog for all buffers but only for active bufferviews --- src/client/backlogrequester.cpp | 34 +++++++++++-------- src/client/backlogrequester.h | 16 +++++---- src/client/bufferviewoverlay.cpp | 47 +++++++++++++------------- src/client/client.cpp | 17 +++++++--- src/client/client.h | 3 +- src/client/clientbacklogmanager.cpp | 33 ++++++++++++++++-- src/client/clientbacklogmanager.h | 5 +++ src/client/clientbufferviewmanager.cpp | 26 ++++++++++++++ src/client/clientbufferviewmanager.h | 7 ++++ 9 files changed, 136 insertions(+), 52 deletions(-) diff --git a/src/client/backlogrequester.cpp b/src/client/backlogrequester.cpp index a08227d8..1100784b 100644 --- a/src/client/backlogrequester.cpp +++ b/src/client/backlogrequester.cpp @@ -23,11 +23,13 @@ #include #include "backlogsettings.h" +#include "bufferviewoverlay.h" #include "clientbacklogmanager.h" -BacklogRequester::BacklogRequester(bool buffering, ClientBacklogManager *backlogManager) +BacklogRequester::BacklogRequester(bool buffering, RequesterType requesterType, ClientBacklogManager *backlogManager) : backlogManager(backlogManager), _isBuffering(buffering), + _requesterType(requesterType), _totalBuffers(0) { Q_ASSERT(backlogManager); @@ -49,21 +51,26 @@ bool BacklogRequester::buffer(BufferId bufferId, const MessageList &messages) { return !_buffersWaiting.isEmpty(); } +QList BacklogRequester::allBufferIds() const { + QSet bufferIds = Client::bufferViewOverlay()->bufferIds(); + bufferIds += Client::bufferViewOverlay()->tempRemovedBufferIds(); + return bufferIds.toList(); +} + // ======================================== // FIXED BACKLOG REQUESTER // ======================================== FixedBacklogRequester::FixedBacklogRequester(ClientBacklogManager *backlogManager) - : BacklogRequester(true, backlogManager) + : BacklogRequester(true, BacklogRequester::PerBufferFixed, backlogManager) { BacklogSettings backlogSettings; _backlogCount = backlogSettings.fixedBacklogAmount(); } -void FixedBacklogRequester::requestBacklog() { - QList allBuffers = allBufferIds(); - setWaitingBuffers(allBuffers); - backlogManager->emitMessagesRequested(QObject::tr("Requesting a total of up to %1 backlog messages for %2 buffers").arg(_backlogCount * allBuffers.count()).arg(allBuffers.count())); - foreach(BufferId bufferId, allBuffers) { +void FixedBacklogRequester::requestBacklog(const QList &bufferIds) { + setWaitingBuffers(bufferIds); + backlogManager->emitMessagesRequested(QObject::tr("Requesting a total of up to %1 backlog messages for %2 buffers").arg(_backlogCount * bufferIds.count()).arg(bufferIds.count())); + foreach(BufferId bufferId, bufferIds) { backlogManager->requestBacklog(bufferId, -1, -1, _backlogCount); } } @@ -72,7 +79,7 @@ void FixedBacklogRequester::requestBacklog() { // GLOBAL UNREAD BACKLOG REQUESTER // ======================================== GlobalUnreadBacklogRequester::GlobalUnreadBacklogRequester(ClientBacklogManager *backlogManager) - : BacklogRequester(false, backlogManager) + : BacklogRequester(false, BacklogRequester::GlobalUnread, backlogManager) { BacklogSettings backlogSettings; _limit = backlogSettings.globalUnreadBacklogLimit(); @@ -94,18 +101,17 @@ void GlobalUnreadBacklogRequester::requestBacklog() { // PER BUFFER UNREAD BACKLOG REQUESTER // ======================================== PerBufferUnreadBacklogRequester::PerBufferUnreadBacklogRequester(ClientBacklogManager *backlogManager) - : BacklogRequester(true, backlogManager) + : BacklogRequester(true, BacklogRequester::PerBufferUnread, backlogManager) { BacklogSettings backlogSettings; _limit = backlogSettings.perBufferUnreadBacklogLimit(); _additional = backlogSettings.perBufferUnreadBacklogAdditional(); } -void PerBufferUnreadBacklogRequester::requestBacklog() { - QList allBuffers = allBufferIds(); - setWaitingBuffers(allBuffers); - backlogManager->emitMessagesRequested(QObject::tr("Requesting a total of up to %1 unread backlog messages for %2 buffers").arg((_limit + _additional) * allBuffers.count()).arg(allBuffers.count())); - foreach(BufferId bufferId, allBuffers) { +void PerBufferUnreadBacklogRequester::requestBacklog(const QList &bufferIds) { + setWaitingBuffers(bufferIds); + backlogManager->emitMessagesRequested(QObject::tr("Requesting a total of up to %1 unread backlog messages for %2 buffers").arg((_limit + _additional) * bufferIds.count()).arg(bufferIds.count())); + foreach(BufferId bufferId, bufferIds) { backlogManager->requestBacklog(bufferId, Client::networkModel()->lastSeenMsgId(bufferId), -1, _limit, _additional); } } diff --git a/src/client/backlogrequester.h b/src/client/backlogrequester.h index c3c6832b..85558f8b 100644 --- a/src/client/backlogrequester.h +++ b/src/client/backlogrequester.h @@ -32,17 +32,18 @@ class ClientBacklogManager; class BacklogRequester { public: - enum RequesterTypes { + enum RequesterType { InvalidRequester = 0, PerBufferFixed, PerBufferUnread, GlobalUnread }; - BacklogRequester(bool buffering, ClientBacklogManager *backlogManger); + BacklogRequester(bool buffering, RequesterType requesterType, ClientBacklogManager *backlogManger); virtual inline ~BacklogRequester() {} inline bool isBuffering() { return _isBuffering; } + inline RequesterType type() { return _requesterType; } inline const QList &bufferedMessages() { return _bufferedMessages; } inline int buffersWaiting() const { return _buffersWaiting.count(); } @@ -50,10 +51,11 @@ public: //! returns false if it was the last missing backlogpart bool buffer(BufferId bufferId, const MessageList &messages); - virtual void requestBacklog() = 0; + virtual inline void requestBacklog() { requestBacklog(allBufferIds()); } + virtual void requestBacklog(const QList &bufferIds) = 0; protected: - inline QList allBufferIds() const { return Client::networkModel()->allBufferIds(); } + QList allBufferIds() const; inline void setWaitingBuffers(const QList &buffers) { setWaitingBuffers(buffers.toSet()); } void setWaitingBuffers(const QSet &buffers); void addWaitingBuffer(BufferId buffer); @@ -62,6 +64,7 @@ protected: private: bool _isBuffering; + RequesterType _requesterType; MessageList _bufferedMessages; int _totalBuffers; QSet _buffersWaiting; @@ -73,7 +76,7 @@ private: class FixedBacklogRequester : public BacklogRequester { public: FixedBacklogRequester(ClientBacklogManager *backlogManager); - virtual void requestBacklog(); + virtual void requestBacklog(const QList &bufferIds); private: int _backlogCount; @@ -86,6 +89,7 @@ class GlobalUnreadBacklogRequester : public BacklogRequester { public: GlobalUnreadBacklogRequester(ClientBacklogManager *backlogManager); virtual void requestBacklog(); + virtual void requestBacklog(const QList &) {} private: int _limit; @@ -98,7 +102,7 @@ private: class PerBufferUnreadBacklogRequester : public BacklogRequester { public: PerBufferUnreadBacklogRequester(ClientBacklogManager *backlogManager); - virtual void requestBacklog(); + virtual void requestBacklog(const QList &bufferIds); private: int _limit; diff --git a/src/client/bufferviewoverlay.cpp b/src/client/bufferviewoverlay.cpp index 93af395e..4ec41239 100644 --- a/src/client/bufferviewoverlay.cpp +++ b/src/client/bufferviewoverlay.cpp @@ -118,29 +118,30 @@ void BufferViewOverlay::updateHelper() { QSet removedBuffers; QSet tempRemovedBuffers; - BufferViewConfig *config = 0; - QSet::const_iterator viewIter; - for(viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); viewIter++) { - config = Client::bufferViewManager()->bufferViewConfig(*viewIter); - if(!config) - continue; - - networkIds << config->networkId(); - buffers += config->bufferList().toSet(); - tempRemovedBuffers += config->temporarilyRemovedBuffers(); - - // in the overlay a buffer is removed it is removed from all views - if(removedBuffers.isEmpty()) - removedBuffers = config->removedBuffers(); - else - removedBuffers.intersect(config->removedBuffers()); - - - addBuffersAutomatically |= config->addNewBuffersAutomatically(); - hideInactiveBuffers &= config->hideInactiveBuffers(); - allowedBufferTypes |= config->allowedBufferTypes(); - if(minimumActivity == -1 || config->minimumActivity() < minimumActivity) - minimumActivity = config->minimumActivity(); + if(Client::bufferViewManager()) { + BufferViewConfig *config = 0; + QSet::const_iterator viewIter; + for(viewIter = _bufferViewIds.constBegin(); viewIter != _bufferViewIds.constEnd(); viewIter++) { + config = Client::bufferViewManager()->bufferViewConfig(*viewIter); + if(!config) + continue; + networkIds << config->networkId(); + buffers += config->bufferList().toSet(); + tempRemovedBuffers += config->temporarilyRemovedBuffers(); + + // in the overlay a buffer is removed it is removed from all views + if(removedBuffers.isEmpty()) + removedBuffers = config->removedBuffers(); + else + removedBuffers.intersect(config->removedBuffers()); + + + addBuffersAutomatically |= config->addNewBuffersAutomatically(); + hideInactiveBuffers &= config->hideInactiveBuffers(); + allowedBufferTypes |= config->allowedBufferTypes(); + if(minimumActivity == -1 || config->minimumActivity() < minimumActivity) + minimumActivity = config->minimumActivity(); + } } changed |= (addBuffersAutomatically != _addBuffersAutomatically); diff --git a/src/client/client.cpp b/src/client/client.cpp index e6387f15..3d430371 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -90,6 +90,7 @@ Client::Client(QObject *parent) _debugLog(&_debugLogBuffer) { _signalProxy->synchronize(_ircListHelper); + connect(this, SIGNAL(requestInitialBacklog()), _backlogManager, SLOT(requestInitialBacklog()), Qt::QueuedConnection); } Client::~Client() { @@ -295,24 +296,30 @@ void Client::setSyncedToCore() { connect(bufferSyncer(), SIGNAL(bufferRenamed(BufferId, QString)), this, SLOT(bufferRenamed(BufferId, QString))); connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), this, SLOT(buffersPermanentlyMerged(BufferId, BufferId))); connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), _messageModel, SLOT(buffersPermanentlyMerged(BufferId, BufferId))); - connect(bufferSyncer(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog())); connect(networkModel(), SIGNAL(setLastSeenMsg(BufferId, MsgId)), bufferSyncer(), SLOT(requestSetLastSeenMsg(BufferId, const MsgId &))); signalProxy()->synchronize(bufferSyncer()); // create a new BufferViewManager Q_ASSERT(!_bufferViewManager); _bufferViewManager = new ClientBufferViewManager(signalProxy(), this); - connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(requestInitialBacklog())); connect(bufferViewManager(), SIGNAL(initDone()), this, SLOT(createDefaultBufferView())); + connect(bufferViewManager(), SIGNAL(viewsInitialized()), this, SLOT(requestInitialBacklogBarrier())); _syncedToCore = true; emit connected(); emit coreConnectionStateChanged(true); } -void Client::requestInitialBacklog() { - if(bufferViewManager()->isInitialized() && bufferSyncer()->isInitialized()) - Client::backlogManager()->requestInitialBacklog(); +void Client::requestInitialBacklogBarrier() { + // usually it _should_ take longer until the bufferViews are initialized, so that's what + // triggers this slot. But we have to make sure that we know all buffers yet. + // so we check the BufferSyncer and in case it wasn't initialized we wait for that instead + if(!bufferSyncer()->isInitialized()) { + disconnect(bufferViewManager(), SIGNAL(viewsInitialized()), this, SLOT(requestInitialBacklogBarrier())); + connect(bufferSyncer(), SIGNAL(initDone()), this, SLOT(requestInitialBacklogBarrier())); + return; + } + emit requestInitialBacklog(); } void Client::createDefaultBufferView() { diff --git a/src/client/client.h b/src/client/client.h index dec806c5..ec4ab3a2 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -128,6 +128,7 @@ public: static inline void registerClientSyncer(ClientSyncer *syncer) { emit instance()->newClientSyncer(syncer); } signals: + void requestInitialBacklog(); void requestNetworkStates(); void showConfigWizard(const QVariantMap &coredata); @@ -185,7 +186,7 @@ private slots: void setConnectedToCore(AccountId id, QIODevice *socket = 0); void setSyncedToCore(); - void requestInitialBacklog(); + void requestInitialBacklogBarrier(); void createDefaultBufferView(); private: diff --git a/src/client/clientbacklogmanager.cpp b/src/client/clientbacklogmanager.cpp index 6f45da35..afd7e1f7 100644 --- a/src/client/clientbacklogmanager.cpp +++ b/src/client/clientbacklogmanager.cpp @@ -47,12 +47,13 @@ void ClientBacklogManager::receiveBacklog(BufferId bufferId, MsgId first, MsgId msglist << msg; } + _backlogReceived << bufferId; + if(isBuffering()) { bool lastPart = !_requester->buffer(bufferId, msglist); updateProgress(_requester->totalBuffers() - _requester->buffersWaiting(), _requester->totalBuffers()); if(lastPart) { stopBuffering(); - reset(); } } else { dispatchMessages(msglist); @@ -70,7 +71,6 @@ void ClientBacklogManager::receiveBacklogAll(MsgId first, MsgId last, int limit, } dispatchMessages(msglist); - reset(); } void ClientBacklogManager::requestInitialBacklog() { @@ -98,9 +98,35 @@ void ClientBacklogManager::requestInitialBacklog() { } } -void ClientBacklogManager::stopBuffering() { +void ClientBacklogManager::checkForBacklog(const BufferId bufferId) { + if(_backlogReceived.contains(bufferId)) + return; + + QList bufferIds; + bufferIds << bufferId; + checkForBacklog(bufferIds); +} + +void ClientBacklogManager::checkForBacklog(const QList &bufferIds) { Q_ASSERT(_requester); + switch(_requester->type()) { + case BacklogRequester::GlobalUnread: + break; + case BacklogRequester::PerBufferUnread: + case BacklogRequester::PerBufferFixed: + default: + { + QList buffers; + foreach(BufferId bufferId, bufferIds) + if(!_backlogReceived.contains(bufferId)) + buffers << bufferId; + _requester->requestBacklog(buffers); + } + }; +} +void ClientBacklogManager::stopBuffering() { + Q_ASSERT(_requester); dispatchMessages(_requester->bufferedMessages(), true); } @@ -126,4 +152,5 @@ void ClientBacklogManager::dispatchMessages(const MessageList &messages, bool so void ClientBacklogManager::reset() { delete _requester; _requester = 0; + _backlogReceived.clear(); } diff --git a/src/client/clientbacklogmanager.h b/src/client/clientbacklogmanager.h index 5a8585bd..0762edfd 100644 --- a/src/client/clientbacklogmanager.h +++ b/src/client/clientbacklogmanager.h @@ -40,8 +40,12 @@ public: public slots: virtual void receiveBacklog(BufferId bufferId, MsgId first, MsgId last, int limit, int additional, QVariantList msgs); virtual void receiveBacklogAll(MsgId first, MsgId last, int limit, int additional, QVariantList msgs); + void requestInitialBacklog(); + void checkForBacklog(BufferId bufferId); + void checkForBacklog(const QList &bufferIds); + signals: void messagesReceived(BufferId bufferId, int count) const; void messagesRequested(const QString &) const; @@ -56,6 +60,7 @@ private: void dispatchMessages(const MessageList &messages, bool sort = false); BacklogRequester *_requester; + QSet _backlogReceived; }; #endif // CLIENTBACKLOGMANAGER_H diff --git a/src/client/clientbufferviewmanager.cpp b/src/client/clientbufferviewmanager.cpp index 6682caa7..d7cd837f 100644 --- a/src/client/clientbufferviewmanager.cpp +++ b/src/client/clientbufferviewmanager.cpp @@ -26,6 +26,7 @@ ClientBufferViewManager::ClientBufferViewManager(SignalProxy *proxy, QObject *parent) : BufferViewManager(proxy, parent) { + connect(this, SIGNAL(initDone()), this, SLOT(waitForConfigInit())); } BufferViewConfig *ClientBufferViewManager::bufferViewConfigFactory(int bufferViewConfigId) { @@ -43,3 +44,28 @@ QList ClientBufferViewManager::clientBufferViewConfigs ClientBufferViewConfig *ClientBufferViewManager::clientBufferViewConfig(int bufferViewId) const { return static_cast(bufferViewConfig(bufferViewId)); } + +void ClientBufferViewManager::waitForConfigInit() { + bool initialized = true; + foreach(BufferViewConfig *config, bufferViewConfigs()) { + initialized &= config->isInitialized(); + if(config->isInitialized()) + continue; + connect(config, SIGNAL(initDone()), this, SLOT(configInitBarrier())); + } + if(initialized) + emit viewsInitialized(); +} + +void ClientBufferViewManager::configInitBarrier() { + BufferViewConfig *config = qobject_cast(sender()); + Q_ASSERT(config); + disconnect(config, SIGNAL(initDone()), this, SLOT(configInitBarrier())); + + bool initialized = true; + foreach(BufferViewConfig *config, bufferViewConfigs()) { + initialized &= config->isInitialized(); + } + if(initialized) + emit viewsInitialized(); +} diff --git a/src/client/clientbufferviewmanager.h b/src/client/clientbufferviewmanager.h index f190362b..09639089 100644 --- a/src/client/clientbufferviewmanager.h +++ b/src/client/clientbufferviewmanager.h @@ -37,6 +37,13 @@ public: protected: virtual BufferViewConfig *bufferViewConfigFactory(int bufferViewConfigId); + +signals: + void viewsInitialized(); + +private slots: + void waitForConfigInit(); + void configInitBarrier(); }; #endif //CLIENTBUFFERVIEWMANAGER_H -- 2.20.1