CppTools: Optionally move raw project parts creation into thread

... by letting callers pass in a generator function.
This takes some load off the UI thread for larger projects.
For now only used by the QbsProjectManager, which can provide a thread-
safe generator function due to the project data existing in "value"
form.

Task-number: QTCREATORBUG-18533
Change-Id: I525dea36a4c4079bd1bd5a4fff844617547d56f1
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-02-04 12:27:58 +01:00
parent fd8187cb86
commit cd9571b4f7
4 changed files with 42 additions and 16 deletions

View File

@@ -61,7 +61,10 @@ void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &project
// Run the project info generator in a worker thread and continue if that one is finished.
const QFuture<ProjectInfo> future = Utils::runAsync([=]() {
Internal::ProjectInfoGenerator generator(m_futureInterface, projectUpdateInfo);
ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo;
if (fullProjectUpdateInfo.rppGenerator)
fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator();
Internal::ProjectInfoGenerator generator(m_futureInterface, fullProjectUpdateInfo);
return generator.generate();
});
m_generateFutureWatcher.setFuture(future);

View File

@@ -192,9 +192,11 @@ ToolChainInfo::ToolChainInfo(const ToolChain *toolChain,
ProjectUpdateInfo::ProjectUpdateInfo(Project *project,
const KitInfo &kitInfo,
const Utils::Environment &env,
const RawProjectParts &rawProjectParts)
const RawProjectParts &rawProjectParts,
const RppGenerator &rppGenerator)
: project(project)
, rawProjectParts(rawProjectParts)
, rppGenerator(rppGenerator)
, cToolChain(kitInfo.cToolChain)
, cxxToolChain(kitInfo.cxxToolChain)
, cToolChainInfo(ToolChainInfo(cToolChain, kitInfo.sysRootPath, env))

View File

@@ -163,16 +163,20 @@ public:
class PROJECTEXPLORER_EXPORT ProjectUpdateInfo
{
public:
using RppGenerator = std::function<RawProjectParts()>;
ProjectUpdateInfo() = default;
ProjectUpdateInfo(Project *project,
const KitInfo &kitInfo,
const Utils::Environment &env,
const RawProjectParts &rawProjectParts);
const RawProjectParts &rawProjectParts,
const RppGenerator &rppGenerator = {});
bool isValid() const;
public:
QPointer<Project> project;
RawProjectParts rawProjectParts;
RppGenerator rppGenerator;
const ToolChain *cToolChain = nullptr;
const ToolChain *cxxToolChain = nullptr;

View File

@@ -810,16 +810,13 @@ static void getExpandedCompilerFlags(QStringList &cFlags, QStringList &cxxFlags,
}
}
void QbsBuildSystem::updateCppCodeModel()
static RawProjectParts generateProjectParts(
const QJsonObject &projectData,
const std::shared_ptr<const ToolChain> &cToolChain,
const std::shared_ptr<const ToolChain> &cxxToolChain,
QtVersion qtVersion
)
{
OpTimer optimer("updateCppCodeModel");
const QJsonObject projectData = session()->projectData();
if (projectData.isEmpty())
return;
const QtSupport::CppKitInfo kitInfo(kit());
QTC_ASSERT(kitInfo.isValid(), return);
RawProjectParts rpps;
forAllProducts(projectData, [&](const QJsonObject &prd) {
const QString productName = prd.value("full-display-name").toString();
@@ -843,7 +840,7 @@ void QbsBuildSystem::updateCppCodeModel()
const Utils::QtVersion qtVersionForPart
= prd.value("module-properties").toObject().value("Qt.core.version").isUndefined()
? Utils::QtVersion::None
: kitInfo.projectPartQtVersion;
: qtVersion;
const QJsonArray groups = prd.value("groups").toArray();
for (const QJsonValue &g : groups) {
@@ -860,8 +857,8 @@ void QbsBuildSystem::updateCppCodeModel()
QStringList cFlags;
QStringList cxxFlags;
getExpandedCompilerFlags(cFlags, cxxFlags, props);
rpp.setFlagsForC({kitInfo.cToolChain, cFlags});
rpp.setFlagsForCxx({kitInfo.cxxToolChain, cxxFlags});
rpp.setFlagsForC({cToolChain.get(), cFlags});
rpp.setFlagsForCxx({cxxToolChain.get(), cxxFlags});
rpp.setMacros(transform<QVector>(arrayToStringList(props.value("cpp.defines")),
[](const QString &s) { return Macro::fromKeyValue(s); }));
@@ -946,8 +943,28 @@ void QbsBuildSystem::updateCppCodeModel()
rpps.append(rpp);
}
});
return rpps;
}
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), rpps});
void QbsBuildSystem::updateCppCodeModel()
{
OpTimer optimer("updateCppCodeModel");
const QJsonObject projectData = session()->projectData();
if (projectData.isEmpty())
return;
const QtSupport::CppKitInfo kitInfo(kit());
QTC_ASSERT(kitInfo.isValid(), return);
const auto cToolchain = std::shared_ptr<ToolChain>(kitInfo.cToolChain
? kitInfo.cToolChain->clone() : nullptr);
const auto cxxToolchain = std::shared_ptr<ToolChain>(kitInfo.cxxToolChain
? kitInfo.cxxToolChain->clone() : nullptr);
m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {},
[projectData, kitInfo, cToolchain, cxxToolchain] {
return generateProjectParts(projectData, cToolchain, cxxToolchain,
kitInfo.projectPartQtVersion);
}});
}
void QbsBuildSystem::updateExtraCompilers()