From 25f2f8e1ee43c2656a9c273f541a3735a7841273 Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@theqtcompany.com> Date: Fri, 22 May 2015 17:16:36 +0200 Subject: [PATCH] IWizardFactory: Create wizards with factoryCreators Do not use the object pool to hold potential wizards. Register FactoryCreator functions with IWizardFactory instead and use those to create the wizards when necessary. This saves us a couple of cycles during startup since we can now delay construction of all wizards and it makes us more flexible wrt. managing the lifecycle of the wizard factories. Change-Id: I95d6a6dfcdf0fd995e1934a9fefcd96c6a676753 Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com> --- src/plugins/coreplugin/coreplugin.cpp | 2 + src/plugins/coreplugin/icore.cpp | 5 -- src/plugins/coreplugin/icore.h | 3 -- src/plugins/coreplugin/iwizardfactory.cpp | 47 +++++++++++++++++-- src/plugins/coreplugin/iwizardfactory.h | 6 +++ src/plugins/designer/formeditorplugin.cpp | 31 ++++++------ .../genericprojectplugin.cpp | 3 +- .../customwizard/customwizard.cpp | 4 +- .../customwizard/customwizard.h | 2 +- .../jsonwizard/jsonwizardfactory.cpp | 4 +- .../jsonwizard/jsonwizardfactory.h | 2 +- .../projectexplorer/projectexplorer.cpp | 23 +++------ .../qmakeprojectmanagerplugin.cpp | 11 +++-- 13 files changed, 85 insertions(+), 58 deletions(-) diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index ffa050e5a05..e4ce23df18a 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -185,6 +185,8 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) InfoBar::initializeGloballySuppressed(); } + IWizardFactory::initialize(); + // Make sure we respect the process's umask when creating new files SaveFile::initializeUmask(); diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index dce4a74a21f..3550d827bdd 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -533,11 +533,6 @@ void ICore::openFiles(const QStringList &arguments, ICore::OpenFilesFlags flags) m_mainwindow->openFiles(arguments, flags); } -void ICore::emitNewItemsDialogRequested() -{ - emit m_instance->newItemsDialogRequested(); -} - void ICore::saveSettings() { emit m_instance->saveSettingsRequested(); diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index ffb45dcd7c4..61df88c61b2 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -123,15 +123,12 @@ public: }; static void openFiles(const QStringList &fileNames, OpenFilesFlags flags = None); - static void emitNewItemsDialogRequested(); - public slots: static void saveSettings(); signals: void coreAboutToOpen(); void coreOpened(); - void newItemsDialogRequested(); void newItemDialogRunningChanged(); void saveSettingsRequested(); void optionsDialogRequested(); diff --git a/src/plugins/coreplugin/iwizardfactory.cpp b/src/plugins/coreplugin/iwizardfactory.cpp index 4262b4abc53..0feac766a19 100644 --- a/src/plugins/coreplugin/iwizardfactory.cpp +++ b/src/plugins/coreplugin/iwizardfactory.cpp @@ -147,16 +147,18 @@ using namespace Core; + namespace { static QList<IFeatureProvider *> s_providerList; +QList<IWizardFactory *> s_allFactories; +QList<IWizardFactory::FactoryCreator> s_factoryCreators; +bool s_areFactoriesLoaded = false; } /* A utility to find all wizards supporting a view mode and matching a predicate */ template <class Predicate> QList<IWizardFactory*> findWizardFactories(Predicate predicate) { - // Hack: Trigger delayed creation of wizards - ICore::emitNewItemsDialogRequested(); // Filter all wizards const QList<IWizardFactory*> allFactories = IWizardFactory::allWizardFactories(); QList<IWizardFactory*> rc; @@ -169,9 +171,33 @@ template <class Predicate> QList<IWizardFactory*> IWizardFactory::allWizardFactories() { - // Hack: Trigger delayed creation of wizards - ICore::emitNewItemsDialogRequested(); - return ExtensionSystem::PluginManager::getObjects<IWizardFactory>(); + if (!s_areFactoriesLoaded) { + QTC_ASSERT(s_allFactories.isEmpty(), return s_allFactories); + + s_areFactoriesLoaded = true; + + QHash<Id, IWizardFactory *> sanityCheck; + foreach (const FactoryCreator &fc, s_factoryCreators) { + QList<IWizardFactory *> tmp = fc(); + foreach (IWizardFactory *newFactory, tmp) { + QTC_ASSERT(newFactory, continue); + IWizardFactory *existingFactory = sanityCheck.value(newFactory->id()); + + QTC_ASSERT(existingFactory != newFactory, continue); + if (existingFactory) { + qWarning("%s", qPrintable(tr("Factory with id=\"%1\" already registered. Deleting.") + .arg(existingFactory->id().toString()))); + delete newFactory; + continue; + } + + sanityCheck.insert(newFactory->id(), newFactory); + s_allFactories << newFactory; + } + } + } + + return s_allFactories; } // Utility to find all registered wizards of a certain kind @@ -211,6 +237,11 @@ QStringList IWizardFactory::supportedPlatforms() const return stringList; } +void IWizardFactory::registerFactoryCreator(const IWizardFactory::FactoryCreator &creator) +{ + s_factoryCreators << creator; +} + QStringList IWizardFactory::allAvailablePlatforms() { QStringList platforms; @@ -257,3 +288,9 @@ FeatureSet IWizardFactory::pluginFeatures() const } return plugins; } + +void IWizardFactory::initialize() +{ + connect(ICore::instance(), &ICore::coreAboutToClose, + ICore::instance(), []() { qDeleteAll(s_allFactories); s_allFactories.clear(); }); +} diff --git a/src/plugins/coreplugin/iwizardfactory.h b/src/plugins/coreplugin/iwizardfactory.h index df5a4e81399..0d52a0e54a3 100644 --- a/src/plugins/coreplugin/iwizardfactory.h +++ b/src/plugins/coreplugin/iwizardfactory.h @@ -38,6 +38,8 @@ #include <QObject> #include <QString> +#include <functional> + namespace Core { namespace Internal { class CorePlugin; } @@ -87,6 +89,9 @@ public: bool isAvailable(const QString &platformName) const; QStringList supportedPlatforms() const; + typedef std::function<QList<IWizardFactory *>()> FactoryCreator; + static void registerFactoryCreator(const FactoryCreator &creator); + // Utility to find all registered wizards static QList<IWizardFactory*> allWizardFactories(); // Utility to find all registered wizards of a certain kind @@ -100,6 +105,7 @@ protected: FeatureSet pluginFeatures() const; private: + static void initialize(); static void destroyFeatureProvider(); IWizardFactory::WizardKind m_kind; diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp index 58bade244aa..97a3ec314dd 100644 --- a/src/plugins/designer/formeditorplugin.cpp +++ b/src/plugins/designer/formeditorplugin.cpp @@ -85,7 +85,21 @@ bool FormEditorPlugin::initialize(const QStringList &arguments, QString *error) { Q_UNUSED(arguments) - initializeTemplates(); +#ifdef CPP_ENABLED + IWizardFactory::registerFactoryCreator( + []() -> QList<IWizardFactory *> { + IWizardFactory *wizard = new FormClassWizard; + wizard->setWizardKind(IWizardFactory::FileWizard); + wizard->setCategory(QLatin1String(Core::Constants::WIZARD_CATEGORY_QT)); + wizard->setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::WIZARD_TR_CATEGORY_QT)); + wizard->setDisplayName(tr("Qt Designer Form Class")); + wizard->setId("C.FormClass"); + wizard->setDescription(tr("Creates a Qt Designer form along with a matching class (C++ header and source file) " + "for implementation purposes. You can add the form and class to an existing Qt Widget Project.")); + + return QList<IWizardFactory *>() << wizard; + }); +#endif ProjectExplorer::JsonWizardFactory::registerPageFactory(new Internal::FormPageFactory); addAutoReleasedObject(new FormEditorFactory); @@ -130,21 +144,6 @@ void FormEditorPlugin::extensionsInitialized() // //////////////////////////////////////////////////// -void FormEditorPlugin::initializeTemplates() -{ -#ifdef CPP_ENABLED - IWizardFactory *wizard = new FormClassWizard; - wizard->setWizardKind(IWizardFactory::FileWizard); - wizard->setCategory(QLatin1String(Core::Constants::WIZARD_CATEGORY_QT)); - wizard->setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::WIZARD_TR_CATEGORY_QT)); - wizard->setDisplayName(tr("Qt Designer Form Class")); - wizard->setId("C.FormClass"); - wizard->setDescription(tr("Creates a Qt Designer form along with a matching class (C++ header and source file) " - "for implementation purposes. You can add the form and class to an existing Qt Widget Project.")); - addAutoReleasedObject(wizard); -#endif -} - // Find out current existing editor file static QString currentFile() { diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 2b784b24346..2a595b4d26a 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -70,9 +70,10 @@ bool GenericProjectPlugin::initialize(const QStringList &, QString *errorMessage addAutoReleasedObject(new Manager); addAutoReleasedObject(new ProjectFilesFactory); addAutoReleasedObject(new GenericMakeStepFactory); - addAutoReleasedObject(new GenericProjectWizard); addAutoReleasedObject(new GenericBuildConfigurationFactory); + IWizardFactory::registerFactoryCreator([]() { return QList<IWizardFactory *>() << new GenericProjectWizard; }); + ActionContainer *mproject = ActionManager::actionContainer(ProjectExplorer::Constants::M_PROJECTCONTEXT); diff --git a/src/plugins/projectexplorer/customwizard/customwizard.cpp b/src/plugins/projectexplorer/customwizard/customwizard.cpp index bccd1d35d7f..2336f57f923 100644 --- a/src/plugins/projectexplorer/customwizard/customwizard.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizard.cpp @@ -356,9 +356,9 @@ CustomWizard *CustomWizard::createWizard(const CustomProjectWizard::CustomWizard containing valid configuration files and parse them into wizards. */ -QList<CustomWizard*> CustomWizard::createWizards() +QList<Core::IWizardFactory *> CustomWizard::createWizards() { - QList<CustomWizard*> rc; + QList<Core::IWizardFactory *> rc; QString errorMessage; QString verboseLog; const QString templateDirName = Core::ICore::resourcePath() + diff --git a/src/plugins/projectexplorer/customwizard/customwizard.h b/src/plugins/projectexplorer/customwizard/customwizard.h index f31b956b1fa..6974ad9be22 100644 --- a/src/plugins/projectexplorer/customwizard/customwizard.h +++ b/src/plugins/projectexplorer/customwizard/customwizard.h @@ -102,7 +102,7 @@ public: // Create all wizards. As other plugins might register factories for derived // classes, call it in extensionsInitialized(). - static QList<CustomWizard*> createWizards(); + static QList<IWizardFactory *> createWizards(); static void setVerbose(int); static int verbose(); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp index e889bd040a1..ce23bc51f8b 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp @@ -205,13 +205,13 @@ static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMe return p; } -QList<JsonWizardFactory *> JsonWizardFactory::createWizardFactories() +QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories() { QString errorMessage; QString verboseLog; const QString wizardFileName = QLatin1String(WIZARD_FILE); - QList <JsonWizardFactory *> result; + QList <Core::IWizardFactory *> result; foreach (const Utils::FileName &path, searchPaths()) { if (path.isEmpty()) continue; diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h index ff7389d088d..5098930bfb9 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h @@ -95,7 +95,7 @@ public: private: // Create all wizards. As other plugins might register factories for derived // classes. Called when the new file dialog is shown for the first time. - static QList<JsonWizardFactory *> createWizardFactories(); + static QList<IWizardFactory *> createWizardFactories(); static JsonWizardFactory *createWizardFactory(const QVariantMap &data, const QDir &baseDir, QString *errorMessage); static QList<Utils::FileName> &searchPaths(); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 609b24bd56d..18e3e63cfea 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -284,7 +284,6 @@ public: void slotUpdateRunActions(); void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode); - void loadCustomWizards(); void updateWelcomePage(); @@ -490,8 +489,12 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er addAutoReleasedObject(new TaskHub); - connect(ICore::instance(), &ICore::newItemsDialogRequested, - dd, &ProjectExplorerPluginPrivate::loadCustomWizards); + IWizardFactory::registerFactoryCreator([]() -> QList<IWizardFactory *> { + QList<IWizardFactory *> result; + result << CustomWizard::createWizards(); + result << JsonWizardFactory::createWizardFactories(); + return result; + }); dd->m_welcomePage = new ProjectWelcomePage; connect(dd->m_welcomePage, &ProjectWelcomePage::manageSessions, @@ -1504,20 +1507,6 @@ void ProjectExplorerPlugin::extensionsInitialized() dd->m_kitManager->restoreKits(); } -void ProjectExplorerPluginPrivate::loadCustomWizards() -{ - // Add custom wizards, for which other plugins might have registered - // class factories - static bool firstTime = true; - if (firstTime) { - firstTime = false; - foreach (IWizardFactory *cpw, CustomWizard::createWizards()) - m_instance->addAutoReleasedObject(cpw); - foreach (IWizardFactory *cpw, JsonWizardFactory::createWizardFactories()) - m_instance->addAutoReleasedObject(cpw); - } -} - void ProjectExplorerPluginPrivate::updateRunWithoutDeployMenu() { m_runWithoutDeployAction->setVisible(m_projectExplorerSettings.deployBeforeRun); diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index c402e2f2f78..9500d0d6d9d 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -106,11 +106,12 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString ProjectExplorer::KitManager::registerKitInformation(new QmakeKitInformation); - addAutoReleasedObject(new SubdirsProjectWizard); - addAutoReleasedObject(new GuiAppWizard); - addAutoReleasedObject(new LibraryWizard); - addAutoReleasedObject(new TestWizard); - addAutoReleasedObject(new CustomWidgetWizard); + IWizardFactory::registerFactoryCreator([]() { + QList<IWizardFactory *> result; + result << new SubdirsProjectWizard << new GuiAppWizard << new LibraryWizard + << new TestWizard << new CustomWidgetWizard; + return result; + }); addAutoReleasedObject(new CustomWizardMetaFactory<CustomQmakeProjectWizard> (QLatin1String("qmakeproject"), IWizardFactory::ProjectWizard)); -- GitLab