Skip to content
Permalink
Browse files

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>
  • Loading branch information
hunger committed May 22, 2015
1 parent b5e3f2e commit 25f2f8e1ee43c2656a9c273f541a3735a7841273
@@ -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();

@@ -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();
@@ -123,15 +123,12 @@ class CORE_EXPORT ICore : public QObject
};
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();
@@ -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(); });
}
@@ -38,6 +38,8 @@
#include <QObject>
#include <QString>

#include <functional>

namespace Core {

namespace Internal { class CorePlugin; }
@@ -87,6 +89,9 @@ class CORE_EXPORT IWizardFactory
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 @@ class CORE_EXPORT IWizardFactory
FeatureSet pluginFeatures() const;

private:
static void initialize();
static void destroyFeatureProvider();

IWizardFactory::WizardKind m_kind;
@@ -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()
{
@@ -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);

@@ -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() +
@@ -102,7 +102,7 @@ class PROJECTEXPLORER_EXPORT CustomWizard : public Core::BaseFileWizardFactory

// 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();
@@ -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;
@@ -95,7 +95,7 @@ class PROJECTEXPLORER_EXPORT JsonWizardFactory : public Core::IWizardFactory
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();
@@ -284,7 +284,6 @@ class ProjectExplorerPluginPrivate : public QObject
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);
@@ -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));

0 comments on commit 25f2f8e

Please sign in to comment.
You can’t perform that action at this time.