Utils: Add a way to (shutdown-)guard pre-created objects

Some classes use private c'tors and a friend function for creation.

Since friendship is not transitive this cannot (nicely) be extended
to the GuardedObject implementation.

In the quest to achieve a uniform 'void setupFoo()' signature to
the outside, keep the creation of the guarded object were it is,
but allow it to be taken over bey a GuardedObject.

This setup still requires the _d_'tor to be public, but less
"dangerous" then a public c'tor - assuming there is some danger
in having that at all.

Use it for the PythoSettings and LanguageClientManager setup.

Change-Id: Ica114a0bb901d33d79c847910a2383ac1bc9e49a
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
hjk
2025-01-13 15:31:04 +01:00
parent 927f919c0b
commit 3f55bbc18c
7 changed files with 22 additions and 17 deletions

View File

@@ -18,15 +18,18 @@ template <class T>
class GuardedObject
{
public:
GuardedObject()
: m_object(new T)
GuardedObject(T *obj)
: m_object(obj)
{
QObject::connect(shutdownGuard(), &QObject::destroyed, shutdownGuard(), [this] {
delete m_object;
m_object = nullptr;
});
}
~GuardedObject() = default;
GuardedObject()
: GuardedObject(new T)
{}
T *get() const { return m_object; }

View File

@@ -29,6 +29,7 @@
#include <utils/algorithm.h>
#include <utils/theme/theme.h>
#include <utils/shutdownguard.h>
#include <utils/utilsicons.h>
#include <QTimer>
@@ -50,8 +51,7 @@ class LanguageClientManagerPrivate
LanguageFunctionsFilter m_functionFilter;
};
LanguageClientManager::LanguageClientManager(QObject *parent)
: QObject(parent)
LanguageClientManager::LanguageClientManager()
{
setObjectName("LanguageClientManager");
@@ -742,9 +742,9 @@ bool LanguageClientManager::isShutdownFinished()
&& managerInstance->m_scheduledForDeletion.isEmpty();
}
void setupLanguageClientManager(QObject *guard)
void setupLanguageClientManager()
{
(void) new LanguageClientManager(guard);
static Utils::GuardedObject theLanguageClientManager{new LanguageClientManager};
}
} // namespace LanguageClient

View File

@@ -33,6 +33,8 @@ class LANGUAGECLIENT_EXPORT LanguageClientManager : public QObject
Q_DISABLE_COPY_MOVE(LanguageClientManager)
public:
~LanguageClientManager() override;
static void clientStarted(Client *client);
static void clientFinished(Client *client);
static Client *startClient(const BaseSettings *setting, ProjectExplorer::Project *project = nullptr);
@@ -98,10 +100,9 @@ signals:
void openCallHierarchy();
private:
explicit LanguageClientManager(QObject *parent);
~LanguageClientManager() override;
LanguageClientManager();
friend void setupLanguageClientManager(QObject *guard);
friend void setupLanguageClientManager();
void updateProject(ProjectExplorer::Project *project);
void projectAdded(ProjectExplorer::Project *project);
@@ -127,6 +128,6 @@ template<typename T> bool LanguageClientManager::hasClients()
});
}
void setupLanguageClientManager(QObject *guard);
void setupLanguageClientManager();
} // namespace LanguageClient

View File

@@ -50,7 +50,7 @@ void LanguageClientPlugin::initialize()
setupCallHierarchyFactory();
setupTypeHierarchyFactory();
setupLanguageClientProjectPanel();
setupLanguageClientManager(this);
setupLanguageClientManager();
setupLanguageClientOutline();
#ifdef WITH_TESTS

View File

@@ -90,7 +90,7 @@ class PythonPlugin final : public ExtensionSystem::IPlugin
setupPythonDebugWorker();
setupPythonOutputParser();
setupPythonSettings(this);
setupPythonSettings();
setupPythonWizard();
setupPipSupport(this);

View File

@@ -36,6 +36,7 @@
#include <utils/qtcassert.h>
#include <utils/treemodel.h>
#include <utils/utilsicons.h>
#include <utils/shutdownguard.h>
#include <QCheckBox>
#include <QComboBox>
@@ -1169,10 +1170,9 @@ Interpreter PythonSettings::interpreter(const QString &interpreterId)
Utils::equal(&Interpreter::id, interpreterId));
}
void setupPythonSettings(QObject *guard)
void setupPythonSettings()
{
new PythonSettings; // Initializes settingsInstance
settingsInstance->setParent(guard);
static GuardedObject thePythonSettings{new PythonSettings};
}
Utils::ListModel<ProjectExplorer::Interpreter> *createInterpreterModel(QObject *parent)

View File

@@ -78,7 +78,8 @@ private:
static void saveSettings();
};
void setupPythonSettings(QObject *guard);
void setupPythonSettings();
Utils::ListModel<ProjectExplorer::Interpreter> *createInterpreterModel(QObject *parent);
} // Python::Internal