Commit cc883023 authored by hjk's avatar hjk
Browse files

De-emphasize PluginManager::getObjects<Type>()



... by additionally keeping local (currently non-owning) pools per
"interesting" type.

Current situation:
  - The global object pool does not scale well for looking up
    objects, as iteration plus qobject_cast typically iterates
    over all pooled objects.
  - User code that can use typed results from the object
    pool need to have access to the full type definition anyway,
    i.e.  depend on the plugin of the target class anyway.

The patch here solves the scaling problem is to have local
type-specific pools to which objects register in their
constructors and deregister in their destructors.

This patch here does *not* change the ownership model of the
pooled objects, however, it opens the possibility to change
the ownership model per type (e.g. by not putting things into
the global pool at all anymore and make the local pool 'owning')
and the intent is to handle that in later patchs.

Even without the follow-up patches this here is a performance
improvement for the cases that access the local pools instead
the global one, i.e. "practically all".

Change-Id: Ib11a42df2c4ecf5e1155534730083a520dd1995b
Reviewed-by: Eike Ziller's avatarEike Ziller <eike.ziller@qt.io>
Reviewed-by: Christian Kandeler's avatarChristian Kandeler <christian.kandeler@qt.io>
parent 32762e27
......@@ -227,6 +227,23 @@
namespace Core {
static QList<IFindFilter *> g_findFilters;
IFindFilter::IFindFilter()
{
g_findFilters.append(this);
}
IFindFilter::~IFindFilter()
{
g_findFilters.removeOne(this);
}
const QList<IFindFilter *> IFindFilter::allFindFilters()
{
return g_findFilters;
}
QKeySequence IFindFilter::defaultShortcut() const
{
return QKeySequence();
......
......@@ -39,9 +39,12 @@ namespace Core {
class CORE_EXPORT IFindFilter : public QObject
{
Q_OBJECT
public:
IFindFilter();
virtual ~IFindFilter();
virtual ~IFindFilter() {}
static const QList<IFindFilter *> allFindFilters();
virtual QString id() const = 0;
virtual QString displayName() const = 0;
......
......@@ -26,26 +26,26 @@
#include "findplaceholder.h"
#include "find/findtoolbar.h"
#include <extensionsystem/pluginmanager.h>
#include <QVBoxLayout>
using namespace Core;
FindToolBarPlaceHolder *FindToolBarPlaceHolder::m_current = 0;
static QList<FindToolBarPlaceHolder *> g_findToolBarPlaceHolders;
FindToolBarPlaceHolder::FindToolBarPlaceHolder(QWidget *owner, QWidget *parent)
: QWidget(parent), m_owner(owner), m_subWidget(0), m_lightColored(false)
{
g_findToolBarPlaceHolders.append(this);
setLayout(new QVBoxLayout);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
layout()->setMargin(0);
ExtensionSystem::PluginManager::addObject(this);
}
FindToolBarPlaceHolder::~FindToolBarPlaceHolder()
{
ExtensionSystem::PluginManager::removeObject(this);
g_findToolBarPlaceHolders.removeOne(this);
if (m_subWidget) {
m_subWidget->setVisible(false);
m_subWidget->setParent(0);
......@@ -54,6 +54,11 @@ FindToolBarPlaceHolder::~FindToolBarPlaceHolder()
m_current = 0;
}
const QList<FindToolBarPlaceHolder *> FindToolBarPlaceHolder::allFindToolbarPlaceHolders()
{
return g_findToolBarPlaceHolders;
}
QWidget *FindToolBarPlaceHolder::owner() const
{
return m_owner;
......
......@@ -39,6 +39,9 @@ class CORE_EXPORT FindToolBarPlaceHolder : public QWidget
public:
explicit FindToolBarPlaceHolder(QWidget *owner, QWidget *parent = 0);
~FindToolBarPlaceHolder();
static const QList<FindToolBarPlaceHolder *> allFindToolbarPlaceHolders();
QWidget *owner() const;
bool isUsedByWidget(QWidget *widget);
......
......@@ -29,6 +29,24 @@
namespace Core {
static QList<IDocumentFactory *> g_documentFactories;
IDocumentFactory::IDocumentFactory(QObject *parent)
: QObject(parent)
{
g_documentFactories.append(this);
}
IDocumentFactory::~IDocumentFactory()
{
g_documentFactories.removeOne(this);
}
const QList<IDocumentFactory *> IDocumentFactory::allDocumentFactories()
{
return g_documentFactories;
}
IDocument *IDocumentFactory::open(const QString &filename)
{
QTC_ASSERT(m_opener, return 0);
......
......@@ -41,7 +41,10 @@ class CORE_EXPORT IDocumentFactory : public QObject
Q_OBJECT
public:
IDocumentFactory(QObject *parent = 0) : QObject(parent) {}
IDocumentFactory(QObject *parent = nullptr);
~IDocumentFactory();
static const QList<IDocumentFactory *> allDocumentFactories();
typedef std::function<IDocument *(const QString &fileName)> Opener;
IDocument *open(const QString &filename);
......
......@@ -48,6 +48,10 @@ class CORE_EXPORT IFileWizardExtension : public QObject
{
Q_OBJECT
public:
IFileWizardExtension();
~IFileWizardExtension();
static QList<IFileWizardExtension *> allFileWizardExtensions();
/* Return a list of pages to be added to the Wizard (empty list if not
* applicable). */
virtual QList<QWizardPage *> extensionPages(const IWizardFactory *wizard) = 0;
......
......@@ -85,12 +85,25 @@
using namespace Core;
static QList<INavigationWidgetFactory *> g_navigationWidgetFactories;
/*!
Creates a \l{Core::NavigationViewFactory}.
*/
INavigationWidgetFactory::INavigationWidgetFactory()
: m_priority(0)
{
g_navigationWidgetFactories.append(this);
}
INavigationWidgetFactory::~INavigationWidgetFactory()
{
g_navigationWidgetFactories.removeOne(this);
}
const QList<INavigationWidgetFactory *> INavigationWidgetFactory::allNavigationFactories()
{
return g_navigationWidgetFactories;
}
/*!
......
......@@ -53,6 +53,9 @@ class CORE_EXPORT INavigationWidgetFactory : public QObject
public:
INavigationWidgetFactory();
~INavigationWidgetFactory();
static const QList<INavigationWidgetFactory *> allNavigationFactories();
void setDisplayName(const QString &displayName);
void setPriority(int priority);
......
......@@ -42,7 +42,8 @@ class CORE_EXPORT IOutputPane : public QObject
Q_OBJECT
public:
IOutputPane(QObject *parent = 0) : QObject(parent) {}
IOutputPane(QObject *parent = nullptr);
~IOutputPane();
virtual QWidget *outputWidget(QWidget *parent) = 0;
virtual QList<QWidget *> toolBarWidgets() const = 0;
......
......@@ -41,12 +41,21 @@ using namespace Utils;
namespace Core {
static QList<IWelcomePage *> g_welcomePages;
const QList<IWelcomePage *> IWelcomePage::allWelcomePages()
{
return g_welcomePages;
}
IWelcomePage::IWelcomePage()
{
g_welcomePages.append(this);
}
IWelcomePage::~IWelcomePage()
{
g_welcomePages.removeOne(this);
}
static QPalette buttonPalette(bool isActive, bool isCursorInside, bool forText)
......
......@@ -55,6 +55,8 @@ public:
virtual int priority() const { return 0; }
virtual Core::Id id() const = 0;
virtual QWidget *createWidget() const = 0;
static const QList<IWelcomePage *> allWelcomePages();
};
class WelcomePageButtonPrivate;
......
......@@ -48,12 +48,25 @@ using namespace Core;
The filter is added to \uicontrol Tools > \uicontrol Locate.
*/
static QList<ILocatorFilter *> g_locatorFilters;
/*!
Constructs a locator filter with \a parent. Call from subclasses.
*/
ILocatorFilter::ILocatorFilter(QObject *parent):
QObject(parent)
{
g_locatorFilters.append(this);
}
ILocatorFilter::~ILocatorFilter()
{
g_locatorFilters.removeOne(this);
}
const QList<ILocatorFilter *> ILocatorFilter::allLocatorFilters()
{
return g_locatorFilters;
}
/*!
......
......@@ -107,8 +107,10 @@ class CORE_EXPORT ILocatorFilter : public QObject
public:
enum Priority {Highest = 0, High = 1, Medium = 2, Low = 3};
ILocatorFilter(QObject *parent = 0);
virtual ~ILocatorFilter() {}
ILocatorFilter(QObject *parent = nullptr);
virtual ~ILocatorFilter();
static const QList<ILocatorFilter *> allLocatorFilters();
Id id() const;
Id actionId() const;
......
......@@ -139,7 +139,7 @@ void Locator::initialize(CorePlugin *corePlugin, const QStringList &, QString *)
void Locator::extensionsInitialized()
{
m_filters = ExtensionSystem::PluginManager::getObjects<ILocatorFilter>();
m_filters = ILocatorFilter::allLocatorFilters();
Utils::sort(m_filters, [](const ILocatorFilter *first, const ILocatorFilter *second) -> bool {
if (first->priority() != second->priority())
return first->priority() < second->priority();
......
......@@ -341,8 +341,8 @@ void MainWindow::extensionsInitialized()
m_statusBarManager->extensionsInitalized();
OutputPaneManager::instance()->init();
m_vcsManager->extensionsInitialized();
m_leftNavigationWidget->setFactories(PluginManager::getObjects<INavigationWidgetFactory>());
m_rightNavigationWidget->setFactories(PluginManager::getObjects<INavigationWidgetFactory>());
m_leftNavigationWidget->setFactories(INavigationWidgetFactory::allNavigationFactories());
m_rightNavigationWidget->setFactories(INavigationWidgetFactory::allNavigationFactories());
readSettings();
updateContext();
......@@ -808,7 +808,7 @@ IDocument *MainWindow::openFiles(const QStringList &fileNames,
ICore::OpenFilesFlags flags,
const QString &workingDirectory)
{
QList<IDocumentFactory*> documentFactories = PluginManager::getObjects<IDocumentFactory>();
const QList<IDocumentFactory*> documentFactories = IDocumentFactory::allDocumentFactories();
IDocument *res = nullptr;
foreach (const QString &fileName, fileNames) {
......
......@@ -37,8 +37,6 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/styledbar.h>
......@@ -66,6 +64,22 @@
using namespace Utils;
namespace Core {
// OutputPane
static QList<IOutputPane *> g_outputPanes;
IOutputPane::IOutputPane(QObject *parent)
: QObject(parent)
{
g_outputPanes.append(this);
}
IOutputPane::~IOutputPane()
{
g_outputPanes.removeOne(this);
}
namespace Internal {
static char outputPaneSettingsKeyC[] = "OutputPaneVisibility";
......@@ -256,7 +270,7 @@ void OutputPaneManager::init()
QFontMetrics titleFm = m_titleLabel->fontMetrics();
int minTitleWidth = 0;
m_panes = ExtensionSystem::PluginManager::getObjects<IOutputPane>();
m_panes = g_outputPanes;
Utils::sort(m_panes, [](IOutputPane *p1, IOutputPane *p2) {
return p1->priorityInStatusBar() > p2->priorityInStatusBar();
});
......
......@@ -49,8 +49,6 @@ class CPPEDITOR_EXPORT CppQuickFixFactory: public TextEditor::QuickFixFactory
Q_OBJECT
public:
CppQuickFixFactory() {}
void matchingOperations(const TextEditor::QuickFixInterface &interface,
TextEditor::QuickFixOperations &result);
......
......@@ -34,7 +34,7 @@
#include <cplusplus/ASTPath.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
using namespace TextEditor;
......@@ -59,10 +59,9 @@ IAssistProcessor *CppQuickFixAssistProvider::createProcessor() const
QList<QuickFixFactory *> CppQuickFixAssistProvider::quickFixFactories() const
{
QList<QuickFixFactory *> results;
foreach (CppQuickFixFactory *f, ExtensionSystem::PluginManager::getObjects<CppQuickFixFactory>())
results.append(f);
return results;
return Utils::filtered(QuickFixFactory::allQuickFixFactories(), [](QuickFixFactory *f) {
return qobject_cast<CppQuickFixFactory *>(f) != nullptr;
});
}
// --------------------------
......
......@@ -41,7 +41,6 @@
#include <projectexplorer/projectexplorer.h>
#include <texteditor/textdocument.h>
#include <extensionsystem/pluginmanager.h>
#include <cplusplus/CppDocument.h>
#include <cplusplus/TranslationUnit.h>
#include <utils/algorithm.h>
......@@ -448,33 +447,31 @@ void RunAllQuickFixesTokenAction::run(CppEditorWidget *editorWidget)
// Calling editorWidget->invokeAssist(QuickFix) would be not enough
// since we also want to execute the ones that match.
const QList<CppQuickFixFactory *> quickFixFactories
= ExtensionSystem::PluginManager::getObjects<CppQuickFixFactory>();
QVERIFY(!quickFixFactories.isEmpty());
CppQuickFixInterface qfi(editorWidget, ExplicitlyInvoked);
// This guard is important since the Quick Fixes expect to get a non-empty path().
if (qfi.path().isEmpty())
return;
foreach (CppQuickFixFactory *quickFixFactory, quickFixFactories) {
QuickFixOperations operations;
// Some Quick Fixes pop up a dialog and are therefore inappropriate for this test.
// Where possible, use a guiless version of the factory.
if (qobject_cast<InsertVirtualMethods *>(quickFixFactory)) {
QScopedPointer<CppQuickFixFactory> factoryProducingGuiLessOperations;
factoryProducingGuiLessOperations.reset(InsertVirtualMethods::createTestFactory());
factoryProducingGuiLessOperations->match(qfi, operations);
} else {
quickFixFactory->match(qfi, operations);
}
for (QuickFixFactory *quickFixFactory : QuickFixFactory::allQuickFixFactories()) {
if (auto cppQuickFixFactory = qobject_cast<CppQuickFixFactory *>(quickFixFactory)) {
QuickFixOperations operations;
// Some Quick Fixes pop up a dialog and are therefore inappropriate for this test.
// Where possible, use a guiless version of the factory.
if (qobject_cast<InsertVirtualMethods *>(cppQuickFixFactory)) {
QScopedPointer<CppQuickFixFactory> factoryProducingGuiLessOperations;
factoryProducingGuiLessOperations.reset(InsertVirtualMethods::createTestFactory());
factoryProducingGuiLessOperations->match(qfi, operations);
} else {
cppQuickFixFactory->match(qfi, operations);
}
foreach (QuickFixOperation::Ptr operation, operations) {
qDebug() << " -- Performing Quick Fix" << operation->description();
operation->perform();
TestActionsTestCase::escape();
TestActionsTestCase::undoChangesInAllEditorWidgets();
QApplication::processEvents();
foreach (QuickFixOperation::Ptr operation, operations) {
qDebug() << " -- Performing Quick Fix" << operation->description();
operation->perform();
TestActionsTestCase::escape();
TestActionsTestCase::undoChangesInAllEditorWidgets();
QApplication::processEvents();
}
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment