diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index a4d632b7e4d..4d15450d488 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -82,6 +82,9 @@ public: int m_spanY = 1; BaseAspect::ConfigWidgetCreator m_configWidgetCreator; QList> m_subWidgets; + + BaseAspect::DataCreator m_dataCreator; + QList m_dataExtractors; }; } // Internal @@ -110,7 +113,9 @@ public: */ BaseAspect::BaseAspect() : d(new Internal::BaseAspectPrivate) -{} +{ + addDataExtractor(this, &BaseAspect::value, &Data::value); +} /*! Destructs a BaseAspect. @@ -772,6 +777,9 @@ StringAspect::StringAspect() { setDefaultValue(QString()); setSpan(2, 1); // Default: Label + something + + addDataExtractor(this, &StringAspect::value, &Data::value); + addDataExtractor(this, &StringAspect::filePath, &Data::filePath); } /*! @@ -1293,6 +1301,8 @@ BoolAspect::BoolAspect(const QString &settingsKey) setDefaultValue(false); setSettingsKey(settingsKey); setSpan(2, 1); + + addDataExtractor(this, &BoolAspect::value, &Data::value); } /*! @@ -1747,6 +1757,8 @@ IntegerAspect::IntegerAspect() { setDefaultValue(qint64(0)); setSpan(2, 1); + + addDataExtractor(this, &IntegerAspect::value, &Data::value); } /*! @@ -2378,4 +2390,43 @@ void AspectContainer::forEachAspect(const std::function &run } } +BaseAspect::Data *BaseAspect::extractData(const MacroExpander *expander) const +{ + QTC_ASSERT(d->m_dataCreator, return nullptr); + Data *data = d->m_dataCreator(); + data->m_classId = metaObject(); + data->m_id = id(); + for (const DataExtractor &extractor : d->m_dataExtractors) + extractor(data, expander); + return data; +} + +void BaseAspect::addDataExtractorHelper(const DataExtractor &extractor) const +{ + d->m_dataExtractors.append(extractor); +} + +void BaseAspect::setDataCreatorHelper(const DataCreator &creator) const +{ + d->m_dataCreator = creator; +} + +const BaseAspect::Data *AspectContainerData::aspect(Id instanceId) const +{ + for (const BaseAspect::Data *data : m_data) { + if (data->id() == instanceId) + return data; + } + return nullptr; +} + +const BaseAspect::Data *AspectContainerData::aspect(BaseAspect::Data::ClassId classId) const +{ + for (const BaseAspect::Data *data : m_data) { + if (data->classId() == classId) + return data; + } + return nullptr; +} + } // namespace Utils diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index d1a0bdfe553..39c2992b93c 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -140,6 +140,30 @@ public: bool isDirty() const; bool hasAction() const; + class QTCREATOR_UTILS_EXPORT Data + { + public: + // The (unique) address of the "owning" aspect's meta object is used as identifier. + using ClassId = const void *; + + virtual ~Data() = default; + + Utils::Id id() const { return m_id; } + ClassId classId() const { return m_classId; } + + QVariant value; + + protected: + friend class BaseAspect; + Utils::Id m_id; + ClassId m_classId = 0; + }; + + using DataCreator = std::function; + using DataExtractor = std::function; + + Data *extractData(const MacroExpander *expander) const; + signals: void changed(); void labelLinkActivated(const QString &link); @@ -149,6 +173,29 @@ protected: void setupLabel(); void addLabeledItem(LayoutBuilder &builder, QWidget *widget); + void setDataCreatorHelper(const DataCreator &creator) const; + void addDataExtractorHelper(const DataExtractor &extractor) const; + + template + void addDataExtractor(AspectClass *aspect, + Type(AspectClass::*p)() const, + Type DataClass::*q) { + setDataCreatorHelper([] { return new DataClass; }); + addDataExtractorHelper([aspect, p, q](Data *data, const MacroExpander *) { + static_cast(data)->*q = (aspect->*p)(); + }); + } + + template + void addDataExtractor(AspectClass *aspect, + Type(AspectClass::*p)(const MacroExpander *) const, + Type DataClass::*q) { + setDataCreatorHelper([] { return new DataClass; }); + addDataExtractorHelper([aspect, p, q](Data *data, const MacroExpander *expander) { + static_cast(data)->*q = (aspect->*p)(expander); + }); + } + template Widget *createSubWidget(Args && ...args) { auto w = new Widget(args...); @@ -172,6 +219,11 @@ public: explicit BoolAspect(const QString &settingsKey = QString()); ~BoolAspect() override; + struct Data : BaseAspect::Data + { + bool value; + }; + void addToLayout(LayoutBuilder &builder) override; QAction *action() override; @@ -280,6 +332,12 @@ public: StringAspect(); ~StringAspect() override; + struct Data : BaseAspect::Data + { + QString value; + Utils::FilePath filePath; + }; + void addToLayout(LayoutBuilder &builder) override; QVariant volatileValue() const override; @@ -373,6 +431,8 @@ public: void setSpecialValueText(const QString &specialText); void setSingleStep(qint64 step); + struct Data : BaseAspect::Data { qint64 value = 0; }; + private: std::unique_ptr d; }; @@ -499,6 +559,29 @@ private: std::unique_ptr d; }; +class QTCREATOR_UTILS_EXPORT AspectContainerData +{ +public: + AspectContainerData() = default; + ~AspectContainerData() { qDeleteAll(m_data); } + + const BaseAspect::Data *aspect(Utils::Id instanceId) const; + const BaseAspect::Data *aspect(Utils::BaseAspect::Data::ClassId classId) const; + + template const typename T::Data *aspect() const + { + return static_cast(aspect(&T::staticMetaObject)); + } + + void append(BaseAspect::Data *data) { m_data.append(data); } + +private: + AspectContainerData(const AspectContainerData &) = delete; + void operator=(const AspectContainerData &) = delete; + + QList m_data; +}; + class QTCREATOR_UTILS_EXPORT AspectContainer : public QObject { Q_OBJECT diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h index 0f150299f32..4f2e6dd087c 100644 --- a/src/libs/utils/environment.h +++ b/src/libs/utils/environment.h @@ -119,3 +119,5 @@ public: }; } // namespace Utils + +Q_DECLARE_METATYPE(Utils::Environment) diff --git a/src/plugins/android/androidqmlpreviewworker.cpp b/src/plugins/android/androidqmlpreviewworker.cpp index f8dd04bd42d..103e7b2e5c3 100644 --- a/src/plugins/android/androidqmlpreviewworker.cpp +++ b/src/plugins/android/androidqmlpreviewworker.cpp @@ -425,7 +425,7 @@ bool AndroidQmlPreviewWorker::startPreviewApp() const QDir destDir(apkInfo()->uploadDir); const QString qmlrcPath = destDir.filePath(m_uploadInfo.uploadPackage.baseName() + packageSuffix); - const QStringList envVars = m_rc->aspect()->environment().toStringList(); + const QStringList envVars = m_rc->aspect()->environment.toStringList(); const QStringList command { "am", "start", diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index 5da5d99ec27..43a03472840 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -242,8 +242,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa auto aspect = runControl->aspect(); Utils::Id runMode = runControl->runMode(); const bool debuggingMode = runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE; - m_useCppDebugger = debuggingMode && aspect->useCppDebugger(); - if (debuggingMode && aspect->useQmlDebugger()) + m_useCppDebugger = debuggingMode && aspect->useCppDebugger; + if (debuggingMode && aspect->useQmlDebugger) m_qmlDebugServices = QmlDebug::QmlDebuggerServices; else if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) m_qmlDebugServices = QmlDebug::QmlProfilerServices; @@ -270,7 +270,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target); m_apiLevel = AndroidManager::deviceApiLevel(target); - m_extraEnvVars = runControl->aspect()->environment(); + m_extraEnvVars = runControl->aspect()->environment; qCDebug(androidRunWorkerLog) << "Environment variables for the app" << m_extraEnvVars.toStringList(); @@ -279,14 +279,14 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa } if (auto aspect = runControl->aspect(Constants::ANDROID_AM_START_ARGS)) { - QTC_CHECK(aspect->value().type() == QVariant::String); - const QString startArgs = aspect->value().toString(); + QTC_CHECK(aspect->value.type() == QVariant::String); + const QString startArgs = aspect->value.toString(); m_amStartExtraArgs = ProcessArgs::splitArgs(startArgs, OsTypeOtherUnix); } if (auto aspect = runControl->aspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) { - QTC_CHECK(aspect->value().type() == QVariant::String); - const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts); + QTC_CHECK(aspect->value.type() == QVariant::String); + const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts); for (const QString &shellCmd : commands) m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); } @@ -295,8 +295,8 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd)); if (auto aspect = runControl->aspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) { - QTC_CHECK(aspect->value().type() == QVariant::String); - const QStringList commands = aspect->value().toString().split('\n', Qt::SkipEmptyParts); + QTC_CHECK(aspect->value.type() == QVariant::String); + const QStringList commands = aspect->value.toString().split('\n', Qt::SkipEmptyParts); for (const QString &shellCmd : commands) m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd)); } diff --git a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp index db1722043c3..3d737b90741 100644 --- a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp @@ -166,7 +166,7 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool, const auto exeAspect = runControl->aspect(); QTC_ASSERT(exeAspect, return false); - const FilePath bin = exeAspect->executable(); + const FilePath bin = exeAspect->executable; if (bin.isEmpty()) { errorMessage = BareMetalDebugSupport::tr( "Cannot debug: Local executable is not set."); @@ -184,7 +184,7 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool, inferior.extraData.insert(Debugger::Constants::kPeripheralDescriptionFile, m_peripheralDescriptionFile.toVariant()); if (const auto argAspect = runControl->aspect()) - inferior.command.setArguments(argAspect->arguments(runControl->macroExpander())); + inferior.command.setArguments(argAspect->arguments); runTool->setInferior(inferior); runTool->setSymbolFile(bin); runTool->setStartMode(AttachToRemoteServer); diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp index 4887549dab8..19c4b07ad55 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp @@ -194,7 +194,7 @@ bool UvscServerProvider::aboutToRun(DebuggerRunTool *runTool, QString &errorMess const auto exeAspect = runControl->aspect(); QTC_ASSERT(exeAspect, return false); - const FilePath bin = exeAspect->executable(); + const FilePath bin = exeAspect->executable; if (bin.isEmpty()) { errorMessage = BareMetalDebugSupport::tr("Cannot debug: Local executable is not set."); return false; diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index a6cccc3d09a..d11d0a51c24 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -95,6 +95,7 @@ CorePlugin::CorePlugin() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); m_instance = this; setupSystemEnvironment(); } diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp index 553dfafe875..4a339db3d79 100644 --- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp +++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp @@ -182,6 +182,11 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target) return builder.emerge(false); }); + addDataExtractor(this, &DebuggerRunConfigurationAspect::useCppDebugger, &Data::useCppDebugger); + addDataExtractor(this, &DebuggerRunConfigurationAspect::useQmlDebugger, &Data::useQmlDebugger); + addDataExtractor(this, &DebuggerRunConfigurationAspect::useMultiProcess, &Data::useMultiProcess); + addDataExtractor(this, &DebuggerRunConfigurationAspect::overrideStartup, &Data::overrideStartup); + m_cppAspect = new DebuggerLanguageAspect; m_cppAspect->setLabel(tr("Enable C++")); m_cppAspect->setSettingsKey("RunConfiguration.UseCppDebugger"); diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.h b/src/plugins/debugger/debuggerrunconfigurationaspect.h index bd2a0a0e00e..4f390d65f60 100644 --- a/src/plugins/debugger/debuggerrunconfigurationaspect.h +++ b/src/plugins/debugger/debuggerrunconfigurationaspect.h @@ -56,6 +56,14 @@ public: int portsUsedByDebugger() const; + struct Data : BaseAspect::Data + { + bool useCppDebugger; + bool useQmlDebugger; + bool useMultiProcess; + QString overrideStartup; + }; + private: Internal::DebuggerLanguageAspect *m_cppAspect; Internal::DebuggerLanguageAspect *m_qmlAspect; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index c0d0889b99e..86d8e1fba9b 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -868,11 +868,11 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm m_runParameters.displayName = runControl->displayName(); if (auto symbolsAspect = runControl->aspect()) - m_runParameters.symbolFile = symbolsAspect->filePath(); + m_runParameters.symbolFile = symbolsAspect->filePath; if (auto terminalAspect = runControl->aspect()) - m_runParameters.useTerminal = terminalAspect->useTerminal(); + m_runParameters.useTerminal = terminalAspect->useTerminal; if (auto runAsRootAspect = runControl->aspect()) - m_runParameters.runAsRoot = runAsRootAspect->value(); + m_runParameters.runAsRoot = runAsRootAspect->value; Kit *kit = runControl->kit(); QTC_ASSERT(kit, return); @@ -886,13 +886,13 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm m_runParameters.qtPackageSourceLocation = qtVersion->qtPackageSourcePath().toString(); if (auto aspect = runControl->aspect()) { - if (!aspect->useCppDebugger()) + if (!aspect->useCppDebugger) m_runParameters.cppEngineType = NoEngineType; - m_runParameters.isQmlDebugging = aspect->useQmlDebugger(); - m_runParameters.multiProcess = aspect->useMultiProcess(); - m_runParameters.additionalStartupCommands = aspect->overrideStartup(); + m_runParameters.isQmlDebugging = aspect->useQmlDebugger; + m_runParameters.multiProcess = aspect->useMultiProcess; + m_runParameters.additionalStartupCommands = aspect->overrideStartup; - if (aspect->useCppDebugger()) { + if (aspect->useCppDebugger) { if (DebuggerKitAspect::debugger(kit)) { const Tasks tasks = DebuggerKitAspect::validateDebugger(kit); for (const Task &t : tasks) { diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp index fbee8c56f74..7c480ebc4a5 100644 --- a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp +++ b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp @@ -92,7 +92,7 @@ public: const Target *target = runControl->target(); Runnable r; r.command = {cmakeFilePath(target), - runControl->runConfiguration()->aspect()->value(), + runControl->aspect()->value, CommandLine::Raw}; r.workingDirectory = target->activeBuildConfiguration()->buildDirectory(); r.environment = target->activeBuildConfiguration()->environment(); diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp index f638d14c903..d47af61c128 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp @@ -115,9 +115,9 @@ public: { setId("LocalPerfRecordWorker"); - auto perfAspect = static_cast(runControl->aspect(Constants::PerfSettingsId)); + auto perfAspect = runControl->aspect(); QTC_ASSERT(perfAspect, return); - PerfSettings *settings = static_cast(perfAspect->currentSettings()); + PerfSettings *settings = static_cast(perfAspect->currentSettings); QTC_ASSERT(settings, return); m_perfRecordArguments = settings->perfRecordArguments(); } diff --git a/src/plugins/projectexplorer/customparser.cpp b/src/plugins/projectexplorer/customparser.cpp index 0229a5287ce..7d19d57560c 100644 --- a/src/plugins/projectexplorer/customparser.cpp +++ b/src/plugins/projectexplorer/customparser.cpp @@ -182,6 +182,7 @@ CustomParsersAspect::CustomParsersAspect(Target *target) setId("CustomOutputParsers"); setSettingsKey("CustomOutputParsers"); setDisplayName(tr("Custom Output Parsers")); + addDataExtractor(this, &CustomParsersAspect::parsers, &Data::parsers); setConfigWidgetCreator([this] { const auto widget = new Internal::CustomParsersSelectionWidget; widget->setSelectedParsers(m_parsers); diff --git a/src/plugins/projectexplorer/customparser.h b/src/plugins/projectexplorer/customparser.h index b0df82c3f92..125ac3bd923 100644 --- a/src/plugins/projectexplorer/customparser.h +++ b/src/plugins/projectexplorer/customparser.h @@ -100,7 +100,12 @@ public: CustomParsersAspect(Target *target); void setParsers(const QList &parsers) { m_parsers = parsers; } - const QList parsers() const { return m_parsers; } + QList parsers() const { return m_parsers; } + + struct Data : BaseAspect::Data + { + QList parsers; + }; private: void fromMap(const QVariantMap &map) override; diff --git a/src/plugins/projectexplorer/environmentaspect.cpp b/src/plugins/projectexplorer/environmentaspect.cpp index d34b32170fc..f926c636f84 100644 --- a/src/plugins/projectexplorer/environmentaspect.cpp +++ b/src/plugins/projectexplorer/environmentaspect.cpp @@ -46,6 +46,7 @@ EnvironmentAspect::EnvironmentAspect() setDisplayName(tr("Environment")); setId("EnvironmentAspect"); setConfigWidgetCreator([this] { return new EnvironmentAspectWidget(this); }); + addDataExtractor(this, &EnvironmentAspect::environment, &Data::environment); } int EnvironmentAspect::baseEnvironmentBase() const diff --git a/src/plugins/projectexplorer/environmentaspect.h b/src/plugins/projectexplorer/environmentaspect.h index 79c1d622e85..8e1095738ff 100644 --- a/src/plugins/projectexplorer/environmentaspect.h +++ b/src/plugins/projectexplorer/environmentaspect.h @@ -70,6 +70,11 @@ public: bool isLocal() const { return m_isLocal; } + struct Data : BaseAspect::Data + { + Utils::Environment environment; + }; + signals: void baseEnvironmentChanged(); void userEnvironmentChangesChanged(const Utils::EnvironmentItems &diff); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 430eadb8dae..01c68a9620e 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -93,7 +93,10 @@ void ISettingsAspect::setConfigWidgetCreator(const ConfigWidgetCreator &configWi // /////////////////////////////////////////////////////////////////////// -GlobalOrProjectAspect::GlobalOrProjectAspect() = default; +GlobalOrProjectAspect::GlobalOrProjectAspect() +{ + addDataExtractor(this, &GlobalOrProjectAspect::currentSettings, &Data::currentSettings); +} GlobalOrProjectAspect::~GlobalOrProjectAspect() { @@ -264,14 +267,20 @@ void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory) theAspectFactories.push_back(aspectFactory); } -QMap RunConfiguration::aspectData() const +QMap RunConfiguration::settingsData() const { QMap data; - for (BaseAspect *aspect : qAsConst(m_aspects)) + for (BaseAspect *aspect : m_aspects) aspect->toActiveMap(data[aspect->id()]); return data; } +void RunConfiguration::storeAspectData(AspectContainerData *storage) const +{ + for (BaseAspect *aspect : m_aspects) + storage->append(aspect->extractData(&m_expander)); +} + BuildSystem *RunConfiguration::activeBuildSystem() const { return target()->buildSystem(); diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index fe0ebb530be..a5d3a85fc2b 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -105,6 +105,11 @@ public: ISettingsAspect *globalSettings() const { return m_globalSettings; } ISettingsAspect *currentSettings() const; + struct Data : Utils::BaseAspect::Data + { + ISettingsAspect *currentSettings = nullptr; + }; + protected: friend class RunConfiguration; void fromMap(const QVariantMap &map) override; @@ -163,7 +168,8 @@ public: addAspectFactory([](Target *target) { return new T(target); }); } - QMap aspectData() const; + QMap settingsData() const; // FIXME: Merge into aspectData? + void storeAspectData(Utils::AspectContainerData *storage) const; void update(); @@ -276,3 +282,5 @@ private: }; } // namespace ProjectExplorer + +Q_DECLARE_METATYPE(ProjectExplorer::ISettingsAspect *); diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 2291a86fbda..08ae45d1775 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -65,6 +65,8 @@ TerminalAspect::TerminalAspect() setDisplayName(tr("Terminal")); setId("TerminalAspect"); setSettingsKey("RunConfiguration.UseTerminal"); + addDataExtractor(this, &TerminalAspect::useTerminal, &Data::useTerminal); + addDataExtractor(this, &TerminalAspect::isUserSet, &Data::isUserSet); calculateUseTerminal(); connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, this, &TerminalAspect::calculateUseTerminal); @@ -320,6 +322,9 @@ ArgumentsAspect::ArgumentsAspect() setDisplayName(tr("Arguments")); setId("ArgumentsAspect"); setSettingsKey("RunConfiguration.Arguments"); + + addDataExtractor(this, &ArgumentsAspect::arguments, &Data::arguments); + m_labelText = tr("Command line arguments:"); } @@ -514,6 +519,9 @@ ExecutableAspect::ExecutableAspect() setDisplayName(tr("Executable")); setId("ExecutableAspect"); setExecutablePathStyle(HostOsInfo::hostOs()); + + addDataExtractor(this, &ExecutableAspect::executable, &Data::executable); + m_executable.setPlaceHolderText(tr("")); m_executable.setLabelText(tr("Executable:")); m_executable.setDisplayStyle(StringAspect::LabelDisplay); diff --git a/src/plugins/projectexplorer/runconfigurationaspects.h b/src/plugins/projectexplorer/runconfigurationaspects.h index 1f8a6933fb6..7426c82fa26 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.h +++ b/src/plugins/projectexplorer/runconfigurationaspects.h @@ -55,6 +55,12 @@ public: bool isUserSet() const; + struct Data : BaseAspect::Data + { + bool useTerminal; + bool isUserSet; + }; + private: void fromMap(const QVariantMap &map) override; void toMap(QVariantMap &map) const override; @@ -115,6 +121,11 @@ public: void setResetter(const std::function &resetter); void resetArguments(); + struct Data : BaseAspect::Data + { + QString arguments; + }; + private: void fromMap(const QVariantMap &map) override; void toMap(QVariantMap &map) const override; @@ -178,6 +189,11 @@ public: void setEnvironmentChange(const Utils::EnvironmentChange &change); void setDisplayStyle(Utils::StringAspect::DisplayStyle style); + struct Data : BaseAspect::Data + { + Utils::FilePath executable; + }; + protected: void fromMap(const QVariantMap &map) override; void toMap(QVariantMap &map) const override; diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 1ea65831037..34c4df84e01 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -351,6 +351,7 @@ public: Utils::Icon icon; const MacroExpander *macroExpander = nullptr; QPointer runConfiguration; // Not owned. Avoid use. + AspectContainerData aspectData; QString buildKey; QMap settingsData; Utils::Id runConfigId; @@ -390,7 +391,9 @@ void RunControl::setRunConfiguration(RunConfiguration *runConfig) d->runnable = runConfig->runnable(); d->displayName = runConfig->expandedDisplayName(); d->buildKey = runConfig->buildKey(); - d->settingsData = runConfig->aspectData(); + d->settingsData = runConfig->settingsData(); + + runConfig->storeAspectData(&d->aspectData); setTarget(runConfig->target()); @@ -857,9 +860,8 @@ void RunControlPrivate::showError(const QString &msg) void RunControl::setupFormatter(OutputFormatter *formatter) const { QList parsers = OutputFormatterFactory::createFormatters(target()); - if (const auto customParsersAspect - = (runConfiguration() ? runConfiguration()->aspect() : nullptr)) { - for (const Utils::Id id : customParsersAspect->parsers()) { + if (const auto customParsersAspect = aspect()) { + for (const Id id : qAsConst(customParsersAspect->parsers)) { if (CustomParser * const parser = CustomParser::createFromId(id)) parsers << parser; } @@ -938,12 +940,17 @@ const MacroExpander *RunControl::macroExpander() const return d->macroExpander; } -BaseAspect *RunControl::aspect(Utils::Id id) const +const BaseAspect::Data *RunControl::aspect(Id instanceId) const { - return d->runConfiguration ? d->runConfiguration->aspect(id) : nullptr; + return d->aspectData.aspect(instanceId); } -QVariantMap RunControl::settingsData(Utils::Id id) const +const BaseAspect::Data *RunControl::aspect(BaseAspect::Data::ClassId classId) const +{ + return d->aspectData.aspect(classId); +} + +QVariantMap RunControl::settingsData(Id id) const { return d->settingsData.value(id); } @@ -1181,9 +1188,9 @@ SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl) { setId("SimpleTargetRunner"); if (auto terminalAspect = runControl->aspect()) - m_useTerminal = terminalAspect->useTerminal(); + m_useTerminal = terminalAspect->useTerminal; if (auto runAsRootAspect = runControl->aspect()) - m_runAsRoot = runAsRootAspect->value(); + m_runAsRoot = runAsRootAspect->value; } void SimpleTargetRunner::start() diff --git a/src/plugins/projectexplorer/runcontrol.h b/src/plugins/projectexplorer/runcontrol.h index 7a6ca088478..d436252c467 100644 --- a/src/plugins/projectexplorer/runcontrol.h +++ b/src/plugins/projectexplorer/runcontrol.h @@ -229,9 +229,11 @@ public: Project *project() const; Kit *kit() const; const Utils::MacroExpander *macroExpander() const; - Utils::BaseAspect *aspect(Utils::Id id) const; - template T *aspect() const { - return runConfiguration() ? runConfiguration()->aspect() : nullptr; + + const Utils::BaseAspect::Data *aspect(Utils::Id instanceId) const; + const Utils::BaseAspect::Data *aspect(Utils::BaseAspect::Data::ClassId classId) const; + template const typename T::Data *aspect() const { + return dynamic_cast(aspect(&T::staticMetaObject)); } QString buildKey() const; diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.cpp b/src/plugins/qmlpreview/qmlpreviewplugin.cpp index 6bd695ac72b..2f76fd54f02 100644 --- a/src/plugins/qmlpreview/qmlpreviewplugin.cpp +++ b/src/plugins/qmlpreview/qmlpreviewplugin.cpp @@ -449,7 +449,8 @@ void QmlPreviewPluginPrivate::setDirty() void QmlPreviewPluginPrivate::addPreview(ProjectExplorer::RunControl *preview) { m_runningPreviews.append(preview); - if (auto multiLanguageAspect = preview->aspect()) { + if (auto multiLanguageAspect = + preview->runConfiguration()->aspect()) { connect(multiLanguageAspect, &QmlProjectManager::QmlMultiLanguageAspect::changed, preview, &ProjectExplorer::RunControl::initiateStop); } diff --git a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp index 22c9db93cb2..23eeb0b33e0 100644 --- a/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp +++ b/src/plugins/qmlpreview/qmlpreviewruncontrol.cpp @@ -134,8 +134,8 @@ LocalQmlPreviewSupport::LocalQmlPreviewSupport(ProjectExplorer::RunControl *runC const auto *qmlBuildSystem = qobject_cast(currentTarget->buildSystem()); if (const auto aspect = runControl->aspect()) { - const QString mainScript = aspect->mainScript(); - const QString currentFile = aspect->currentFile(); + const QString mainScript = aspect->mainScript; + const QString currentFile = aspect->currentFile; const QString mainScriptFromProject = qmlBuildSystem->targetFile( Utils::FilePath::fromString(mainScript)).toString(); diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 74243a574bd..030625bd64e 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -311,9 +311,8 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker) { d->m_toolBusy = true; auto runControl = runWorker->runControl(); - if (auto aspect = static_cast( - runControl->aspect(Constants::SETTINGS))) { - if (auto settings = static_cast(aspect->currentSettings())) { + if (auto aspect = runControl->aspect()) { + if (auto settings = static_cast(aspect->currentSettings)) { d->m_profilerConnections->setFlushInterval(settings->flushEnabled.value() ? settings->flushInterval.value() : 0); d->m_profilerModelManager->setAggregateTraces(settings->aggregateTraces.value()); diff --git a/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp b/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp index 602a880fad5..c16d96616a8 100644 --- a/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp +++ b/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp @@ -37,14 +37,14 @@ #include #include +#include #include #include -#include - using namespace Core; using namespace ProjectExplorer; +using namespace Utils; namespace QmlProjectManager { @@ -60,6 +60,9 @@ QmlMainFileAspect::QmlMainFileAspect(Target *target) : m_target(target) , m_scriptFile(M_CURRENT_FILE) { + addDataExtractor(this, &QmlMainFileAspect::mainScript, &Data::mainScript); + addDataExtractor(this, &QmlMainFileAspect::currentFile, &Data::currentFile); + connect(EditorManager::instance(), &EditorManager::currentEditorChanged, this, &QmlMainFileAspect::changeCurrentFile); connect(EditorManager::instance(), &EditorManager::currentDocumentStateChanged, diff --git a/src/plugins/qmlprojectmanager/qmlmainfileaspect.h b/src/plugins/qmlprojectmanager/qmlmainfileaspect.h index 7eacb128b22..ede3d8f4117 100644 --- a/src/plugins/qmlprojectmanager/qmlmainfileaspect.h +++ b/src/plugins/qmlprojectmanager/qmlmainfileaspect.h @@ -47,6 +47,7 @@ class QmlBuildSystem; class QMLPROJECTMANAGER_EXPORT QmlMainFileAspect : public Utils::BaseAspect { Q_OBJECT + public: explicit QmlMainFileAspect(ProjectExplorer::Target *target); ~QmlMainFileAspect() override; @@ -57,6 +58,12 @@ public: FileInSettings }; + struct Data : BaseAspect::Data + { + QString mainScript; + QString currentFile; + }; + void addToLayout(Utils::LayoutBuilder &builder) final; void toMap(QVariantMap &map) const final; void fromMap(const QVariantMap &map) final; @@ -74,7 +81,6 @@ public: QmlBuildSystem *qmlBuildSystem() const; public: - ProjectExplorer::Target *m_target = nullptr; QPointer m_fileListCombo; QStandardItemModel m_fileListModel; diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index 3abb35d2b2e..6f3c1415719 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -45,7 +45,7 @@ Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl) : RunWorker(runControl) { setId("Slog2InfoRunner"); - m_applicationId = runControl->aspect()->executable().fileName(); + m_applicationId = runControl->aspect()->executable.fileName(); // See QTCREATORBUG-10712 for details. // We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info. diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index 6b34dc809dc..6f1fc91be96 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -87,7 +87,7 @@ void ValgrindToolRunner::start() m_runner.setDebuggee(runnable()); if (auto aspect = runControl()->aspect()) - m_runner.setUseTerminal(aspect->useTerminal()); + m_runner.setUseTerminal(aspect->useTerminal); connect(&m_runner, &ValgrindRunner::processOutputReceived, this, &ValgrindToolRunner::receiveProcessOutput); diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.cpp b/src/plugins/webassembly/webassemblyrunconfiguration.cpp index 54f6d5cb47e..057e84ea1be 100644 --- a/src/plugins/webassembly/webassemblyrunconfiguration.cpp +++ b/src/plugins/webassembly/webassemblyrunconfiguration.cpp @@ -120,7 +120,7 @@ public: setStarter([this, runControl, portsGatherer] { Runnable r; const QString browserId = - runControl->aspect()->currentBrowser(); + runControl->aspect()->currentBrowser; r.command = emrunCommand(runControl->runConfiguration(), browserId, QString::number(portsGatherer->findEndPoint().port())); diff --git a/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp index b022c5147dc..14573001161 100644 --- a/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp +++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp @@ -89,6 +89,8 @@ WebBrowserSelectionAspect::WebBrowserSelectionAspect(ProjectExplorer::Target *ta setDisplayName(tr("Web Browser")); setId("WebBrowserAspect"); setSettingsKey("RunConfiguration.WebBrowser"); + + addDataExtractor(this, &WebBrowserSelectionAspect::currentBrowser, &Data::currentBrowser); } void WebBrowserSelectionAspect::addToLayout(LayoutBuilder &builder) diff --git a/src/plugins/webassembly/webassemblyrunconfigurationaspects.h b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h index b1360a79faf..312ed40adf2 100644 --- a/src/plugins/webassembly/webassemblyrunconfigurationaspects.h +++ b/src/plugins/webassembly/webassemblyrunconfigurationaspects.h @@ -49,6 +49,11 @@ public: QString currentBrowser() const; + struct Data : BaseAspect::Data + { + QString currentBrowser; + }; + private: QComboBox *m_webBrowserComboBox = nullptr; QString m_currentBrowser;