From c4236da9d1ceb83de1b6c960637def7ace81e1a8 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 11 May 2021 16:53:03 +0200 Subject: [PATCH] Introduce Utils::FutureSynchronizer The API is nearly the same as QFutureSynchronizer. The differences are: 1. We don't make this class a template class, however, we are leaving some template methods, like addFuture(). For the scope of future synchronizing there is no need for QFuture API, the QFuture is sufficient. 2. Renamed cancelOnWait() getter to isCancelOnWait() in order to conform more to Qt API naming rules. 3. Removed futures() getter and provided isEmpty() instead. 4. Removed c'tor that takes a future and setFuture(). These 2 methods were superfluous and may easily be substituted with other methods from the existing API. The additional feature is about flushing finished futures. This can be done on demand by a call to flushFinishedFutures(), or is done automatically on every call to addFuture(). Change-Id: I6a323c9481eeeea9235e6b6e3048cef02873da08 Reviewed-by: Eike Ziller --- src/libs/utils/CMakeLists.txt | 1 + src/libs/utils/futuresynchronizer.cpp | 81 +++++++++++++++++++++++++++ src/libs/utils/futuresynchronizer.h | 65 +++++++++++++++++++++ src/libs/utils/utils-lib.pri | 2 + src/libs/utils/utils.qbs | 2 + 5 files changed, 151 insertions(+) create mode 100644 src/libs/utils/futuresynchronizer.cpp create mode 100644 src/libs/utils/futuresynchronizer.h diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 4bddb17fc4b..c18b7acdf1c 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -59,6 +59,7 @@ add_qtc_library(Utils fixedsizeclicklabel.cpp fixedsizeclicklabel.h flowlayout.cpp flowlayout.h functiontraits.h + futuresynchronizer.cpp futuresynchronizer.h fuzzymatcher.cpp fuzzymatcher.h genericconstants.h globalfilechangeblocker.cpp globalfilechangeblocker.h diff --git a/src/libs/utils/futuresynchronizer.cpp b/src/libs/utils/futuresynchronizer.cpp new file mode 100644 index 00000000000..da76b41ed0a --- /dev/null +++ b/src/libs/utils/futuresynchronizer.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "futuresynchronizer.h" + +/*! \class Utils::FutureSynchronizer + + \brief The FutureSynchronizer is an enhanced version of QFutureSynchronizer. +*/ + +namespace Utils { + +FutureSynchronizer::~FutureSynchronizer() +{ + waitForFinished(); +} + +bool FutureSynchronizer::isEmpty() const +{ + return m_futures.isEmpty(); +} + +void FutureSynchronizer::waitForFinished() +{ + if (m_cancelOnWait) { + for (QFuture &future : m_futures) + future.cancel(); + } + for (QFuture &future : m_futures) + future.waitForFinished(); + clearFutures(); +} + +void FutureSynchronizer::clearFutures() +{ + m_futures.clear(); +} + +void FutureSynchronizer::setCancelOnWait(bool enabled) +{ + m_cancelOnWait = enabled; +} + +bool FutureSynchronizer::isCancelOnWait() const +{ + return m_cancelOnWait; +} + +void FutureSynchronizer::flushFinishedFutures() +{ + QList> newFutures; + for (const QFuture &future : qAsConst(m_futures)) { + if (!future.isFinished()) + newFutures.append(future); + } + m_futures = newFutures; +} + +} // namespace Utils diff --git a/src/libs/utils/futuresynchronizer.h b/src/libs/utils/futuresynchronizer.h new file mode 100644 index 00000000000..db6afc7a97e --- /dev/null +++ b/src/libs/utils/futuresynchronizer.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "utils_global.h" +#include + +#include +#include + +namespace Utils { + +class QTCREATOR_UTILS_EXPORT FutureSynchronizer final +{ +public: + FutureSynchronizer() = default; + ~FutureSynchronizer(); + + template + void addFuture(const QFuture &future) + { + m_futures.append(QFuture(future)); + flushFinishedFutures(); + } + + bool isEmpty() const; + + void waitForFinished(); + void clearFutures(); + + void setCancelOnWait(bool enabled); + bool isCancelOnWait() const; // TODO: The original contained cancelOnWait, what suggests action, not a getter + + void flushFinishedFutures(); + +private: + + QList> m_futures; + bool m_cancelOnWait = false; // TODO: True default makes more sense... +}; + +} // namespace Utils diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index b4e5d3d31ae..6aa5ae62dd3 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -141,6 +141,7 @@ SOURCES += \ $$PWD/aspects.cpp \ $$PWD/layoutbuilder.cpp \ $$PWD/variablechooser.cpp \ + $$PWD/futuresynchronizer.cpp \ $$PWD/qtcsettings.cpp HEADERS += \ @@ -298,6 +299,7 @@ HEADERS += \ $$PWD/layoutbuilder.h \ $$PWD/variablechooser.h \ $$PWD/set_algorithm.h \ + $$PWD/futuresynchronizer.h \ $$PWD/qtcsettings.h FORMS += $$PWD/filewizardpage.ui \ diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index b55476ca483..e079049ac3d 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -129,6 +129,8 @@ Project { "flowlayout.cpp", "flowlayout.h", "functiontraits.h", + "futuresynchronizer.cpp", + "futuresynchronizer.h", "fuzzymatcher.cpp", "fuzzymatcher.h", "globalfilechangeblocker.cpp",