diff --git a/cli/application.cpp b/cli/application.cpp index d685526..fa6753d 100644 --- a/cli/application.cpp +++ b/cli/application.cpp @@ -943,46 +943,45 @@ void Application::waitForIdle(const ArgumentOccurrence &) { m_preventDisconnect = true; - // setup timer - QTimer idleTime; + // setup timer for handling minimum idle duration + auto idleTime = QTimer(); idleTime.setSingleShot(true); idleTime.setInterval(m_idleDuration); - // define variable which is set to true if handleTimeout to indicate the idle state has persisted long enough - bool isLongEnoughIdle = false; - - // define handler for timer timeout - function handleTimeout([this, &isLongEnoughIdle] { + // define event handlers + auto isLongEnoughIdle = false, dirsOrDevsChanged = true, newDirsOrDevs = true; + const auto handleStatusChange = [&dirsOrDevsChanged] { dirsOrDevsChanged = true; }; + const auto handleNewDirsOrDevs = [&newDirsOrDevs] { newDirsOrDevs = true; }; + const auto handleAllEventsProcessed = [this, &newDirsOrDevs, &dirsOrDevsChanged, &idleTime] { + if (newDirsOrDevs) { + findRelevantDirsAndDevs(OperationType::WaitForIdle); + } + if (newDirsOrDevs || dirsOrDevsChanged) { + if (!checkWhetherIdle()) { + idleTime.stop(); + return; + } + if (!idleTime.isActive()) { + idleTime.start(); + } + } + newDirsOrDevs = dirsOrDevsChanged = false; + }; + const auto handleIdleTimer = [this, &isLongEnoughIdle] { if (checkWhetherIdle()) { isLongEnoughIdle = true; } - }); - - // define handler for dirStatusChanged/devStatusChanged - function handleStatusChange([this, &idleTime] { - if (!checkWhetherIdle()) { - idleTime.stop(); - return; - } - if (!idleTime.isActive()) { - idleTime.start(); - } - }); - - // define handler for newDirs/newDevices to call findRelevantDirsAndDevs() in that case - function handleNewDirsOrDevs([this, &handleStatusChange] { - findRelevantDirsAndDevs(OperationType::WaitForIdle); - handleStatusChange(); - }); + }; // invoke handler manually because Syncthing could already be idling - handleNewDirsOrDevs(); + handleAllEventsProcessed(); waitForSignals(&noop, m_idleTimeout, signalInfo(&m_connection, &SyncthingConnection::dirStatusChanged, handleStatusChange, &isLongEnoughIdle), signalInfo(&m_connection, &SyncthingConnection::devStatusChanged, handleStatusChange, &isLongEnoughIdle), signalInfo(&m_connection, &SyncthingConnection::newDirs, handleNewDirsOrDevs, &isLongEnoughIdle), signalInfo(&m_connection, &SyncthingConnection::newDevices, handleNewDirsOrDevs, &isLongEnoughIdle), - signalInfo(&idleTime, &QTimer::timeout, handleTimeout, &isLongEnoughIdle)); + signalInfo(&m_connection, &SyncthingConnection::allEventsProcessed, handleAllEventsProcessed, &isLongEnoughIdle), + signalInfo(&idleTime, &QTimer::timeout, handleIdleTimer, &isLongEnoughIdle)); if (!isLongEnoughIdle) { cerr << Phrases::Warning << "Exiting after timeout" << Phrases::End << flush; diff --git a/syncthingconnector/syncthingconnection.cpp b/syncthingconnector/syncthingconnection.cpp index 74d7054..73f0039 100644 --- a/syncthingconnector/syncthingconnection.cpp +++ b/syncthingconnector/syncthingconnection.cpp @@ -1113,6 +1113,16 @@ void SyncthingConnection::recalculateStatus() * \remarks New events are automatically polled when connected. */ +/*! + * \fn SyncthingConnection::allEventsProcesses() + * \brief Indicates all new events have been processed. + * \remarks + * This event is emitted after newEvents() and dirStatusChanged(), devStatusChanged() and other specific events. + * If you would go through the list of all directories on every dirStatusChanged() event using instead might + * be a more efficient alternative allEventsProcesses(). Just set a flag on dirStatusChanged() and go though the + * list of directories only once on the allEventsProcesses() event when the flag has been set. + */ + /*! * \fn SyncthingConnection::dirStatusChanged() * \brief Indicates the status of the specified \a dir changed. diff --git a/syncthingconnector/syncthingconnection.h b/syncthingconnector/syncthingconnection.h index 82bbaef..f8e0ac3 100644 --- a/syncthingconnector/syncthingconnection.h +++ b/syncthingconnector/syncthingconnection.h @@ -233,6 +233,7 @@ Q_SIGNALS: void newDevices(const std::vector &devs); void newConfigApplied(); void newEvents(const QJsonArray &events); + void allEventsProcessed(); void dirStatusChanged(const Data::SyncthingDir &dir, int index); void devStatusChanged(const Data::SyncthingDev &dev, int index); void fileChanged(const Data::SyncthingDir &dir, int index, const Data::SyncthingFileChange &fileChange); diff --git a/syncthingconnector/syncthingconnection_requests.cpp b/syncthingconnector/syncthingconnection_requests.cpp index 32a4f60..70fc3f2 100644 --- a/syncthingconnector/syncthingconnection_requests.cpp +++ b/syncthingconnector/syncthingconnection_requests.cpp @@ -1737,7 +1737,9 @@ void SyncthingConnection::readEvents() m_hasEvents = true; const auto replyArray = replyDoc.array(); emit newEvents(replyArray); - if (!readEventsFromJsonArray(replyArray, m_lastEventId)) { + const auto res = readEventsFromJsonArray(replyArray, m_lastEventId); + emit allEventsProcessed(); + if (!res) { return; }