From 1e10161bf20914ec7474e2d3a3fb044996816a37 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 4 Jan 2023 13:05:36 +0100 Subject: [PATCH] CppProjectUpdater: Reuse TaskTree Change-Id: I7474e5a31d169bf435d94536cffd77d218320977 Reviewed-by: Christian Kandeler Reviewed-by: Qt CI Bot --- .../cmakeprojectmanager/cmakebuildsystem.cpp | 1 + src/plugins/cppeditor/cppeditorplugin.cpp | 1 + src/plugins/cppeditor/cppprojectupdater.cpp | 149 +++++++----------- src/plugins/cppeditor/cppprojectupdater.h | 21 +-- .../qmakeprojectmanager/qmakeproject.cpp | 1 + 5 files changed, 64 insertions(+), 109 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index fafc45b1050..30437969622 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index dd5eea2ecb5..20a90c22025 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -68,6 +68,7 @@ #include #include +#include #include #include #include diff --git a/src/plugins/cppeditor/cppprojectupdater.cpp b/src/plugins/cppeditor/cppprojectupdater.cpp index 1b19567cc28..4868077940a 100644 --- a/src/plugins/cppeditor/cppprojectupdater.cpp +++ b/src/plugins/cppeditor/cppprojectupdater.cpp @@ -7,15 +7,13 @@ #include "cppprojectinfogenerator.h" #include "generatedcodemodelsupport.h" -#include +#include -#include +#include #include -#include +#include #include -#include -#include #include @@ -26,17 +24,10 @@ namespace CppEditor { CppProjectUpdater::CppProjectUpdater() { - connect(&m_generateFutureWatcher, - &QFutureWatcher::finished, - this, - &CppProjectUpdater::onProjectInfoGenerated); m_futureSynchronizer.setCancelOnWait(true); } -CppProjectUpdater::~CppProjectUpdater() -{ - cancel(); -} +CppProjectUpdater::~CppProjectUpdater() = default; void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo) { @@ -49,104 +40,78 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, // Stop previous update. cancel(); - m_extraCompilers = Utils::transform(extraCompilers, [](ExtraCompiler *compiler) { - return QPointer(compiler); - }); - m_projectUpdateInfo = projectUpdateInfo; + const QList> compilers = + Utils::transform(extraCompilers, [](ExtraCompiler *compiler) { + return QPointer(compiler); + }); using namespace ProjectExplorer; // Run the project info generator in a worker thread and continue if that one is finished. - auto generateFuture = Utils::runAsync([=](QFutureInterface &futureInterface) { + const auto infoGenerator = [=](QFutureInterface &futureInterface) { ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo; if (fullProjectUpdateInfo.rppGenerator) fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator(); Internal::ProjectInfoGenerator generator(futureInterface, fullProjectUpdateInfo); futureInterface.reportResult(generator.generate()); - }); - m_generateFutureWatcher.setFuture(generateFuture); - m_futureSynchronizer.addFuture(generateFuture); + }; - // extra compilers - for (QPointer compiler : std::as_const(m_extraCompilers)) { - if (!compiler->isDirty()) - continue; - - const auto destroyTaskTree = [this](TaskTree *taskTree) { - m_extraCompilerTasks.remove(taskTree); - taskTree->deleteLater(); - }; - TaskTree *taskTree = new TaskTree({compiler->compileFileItem()}); - connect(taskTree, &TaskTree::done, this, [this, taskTree, destroyTaskTree] { - destroyTaskTree(taskTree); - m_projectUpdateFutureInterface->setProgressValue( - m_projectUpdateFutureInterface->progressValue() + 1); - checkForExtraCompilersFinished(); - }); - connect(taskTree, &TaskTree::errorOccurred, this, [taskTree, destroyTaskTree] { - destroyTaskTree(taskTree); - }); - m_extraCompilerTasks.insert(taskTree); - taskTree->start(); + using namespace Tasking; + struct UpdateStorage { + ProjectInfo::ConstPtr projectInfo = nullptr; + }; + const TreeStorage storage; + const auto setupInfoGenerator = [=](AsyncTask &async) { + async.setAsyncCallData(infoGenerator); + async.setFutureSynchronizer(&m_futureSynchronizer); + }; + const auto onInfoGeneratorDone = [=](const AsyncTask &async) { + storage->projectInfo = async.result(); + }; + QList tasks{parallel}; + tasks.append(Async(setupInfoGenerator, onInfoGeneratorDone)); + for (QPointer compiler : compilers) { + if (compiler && compiler->isDirty()) + tasks.append(compiler->compileFileItem()); } - m_projectUpdateFutureInterface.reset(new QFutureInterface); - m_projectUpdateFutureInterface->setProgressRange(0, m_extraCompilerTasks.size() - + 1 /*generateFuture*/); - m_projectUpdateFutureInterface->setProgressValue(0); - m_projectUpdateFutureInterface->reportStarted(); - Core::ProgressManager::addTask(m_projectUpdateFutureInterface->future(), - tr("Preparing C++ Code Model"), - "CppProjectUpdater"); + const auto onDone = [this, storage, compilers] { + QList extraCompilers; + QSet compilerFiles; + for (const QPointer &compiler : compilers) { + if (compiler) { + extraCompilers += compiler.data(); + compilerFiles += Utils::toSet(compiler->targets()); + } + } + GeneratedCodeModelSupport::update(extraCompilers); + auto updateFuture = CppModelManager::instance()->updateProjectInfo(storage->projectInfo, + compilerFiles); + m_futureSynchronizer.addFuture(updateFuture); + m_taskTree.release()->deleteLater(); + }; + const auto onError = [this] { + m_taskTree.release()->deleteLater(); + }; + + const Group root { + Storage(storage), + Group(tasks), + OnGroupDone(onDone), + OnGroupError(onError) + }; + m_taskTree.reset(new TaskTree(root)); + auto progress = new Core::TaskProgress(m_taskTree.get()); + progress->setDisplayName(tr("Preparing C++ Code Model")); + m_taskTree->start(); } void CppProjectUpdater::cancel() { - if (m_projectUpdateFutureInterface && m_projectUpdateFutureInterface->isRunning()) - m_projectUpdateFutureInterface->reportFinished(); - m_generateFutureWatcher.setFuture({}); - m_isProjectInfoGenerated = false; - qDeleteAll(m_extraCompilerTasks); - m_extraCompilerTasks.clear(); - m_extraCompilers.clear(); + m_taskTree.reset(); m_futureSynchronizer.cancelAllFutures(); } -void CppProjectUpdater::onProjectInfoGenerated() -{ - if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1) - return; - - m_projectUpdateFutureInterface->setProgressValue(m_projectUpdateFutureInterface->progressValue() - + 1); - m_isProjectInfoGenerated = true; - checkForExtraCompilersFinished(); -} - -void CppProjectUpdater::checkForExtraCompilersFinished() -{ - if (!m_extraCompilerTasks.isEmpty() || !m_isProjectInfoGenerated) - return; // still need to wait - - m_projectUpdateFutureInterface->reportFinished(); - m_projectUpdateFutureInterface.reset(); - - QList extraCompilers; - QSet compilerFiles; - for (const QPointer &compiler : std::as_const(m_extraCompilers)) { - if (compiler) { - extraCompilers += compiler.data(); - compilerFiles += Utils::toSet(compiler->targets()); - } - } - GeneratedCodeModelSupport::update(extraCompilers); - m_extraCompilers.clear(); - - auto updateFuture = CppModelManager::instance() - ->updateProjectInfo(m_generateFutureWatcher.result(), compilerFiles); - m_futureSynchronizer.addFuture(updateFuture); -} - namespace Internal { CppProjectUpdaterFactory::CppProjectUpdaterFactory() { diff --git a/src/plugins/cppeditor/cppprojectupdater.h b/src/plugins/cppeditor/cppprojectupdater.h index 9760c25da55..50910e83207 100644 --- a/src/plugins/cppeditor/cppprojectupdater.h +++ b/src/plugins/cppeditor/cppprojectupdater.h @@ -4,18 +4,15 @@ #pragma once #include "cppeditor_global.h" -#include "cppprojectupdaterinterface.h" -#include "projectinfo.h" -#include +#include "cppprojectupdaterinterface.h" + #include -#include - +namespace ProjectExplorer { class ExtraCompiler; } namespace Utils { class TaskTree; } namespace CppEditor { -class ProjectInfo; namespace Internal { @@ -46,18 +43,8 @@ public: void cancel() override; private: - void onProjectInfoGenerated(); - void checkForExtraCompilersFinished(); - -private: - ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo; - QList> m_extraCompilers; - - QFutureWatcher m_generateFutureWatcher; - bool m_isProjectInfoGenerated = false; - QSet m_extraCompilerTasks; - std::unique_ptr> m_projectUpdateFutureInterface; Utils::FutureSynchronizer m_futureSynchronizer; + std::unique_ptr m_taskTree; }; } // namespace CppEditor diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 288e9bdd64e..5d021f9c56d 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include