QmlPreview: A dedicated class for the QmlPreviewRunWorkerFactory

Change-Id: I994f339ac1ca35e9b1dc7e2572682c4bcdb485ea
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2023-01-05 13:53:41 +01:00
parent c151835834
commit 4a21700175
4 changed files with 131 additions and 126 deletions

View File

@@ -42,6 +42,7 @@
#include <android/androidconstants.h> #include <android/androidconstants.h>
#include <QAction> #include <QAction>
#include <QTimer>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -90,20 +91,16 @@ static std::unique_ptr<QmlDebugTranslationClient> defaultCreateDebugTranslationC
{ {
auto client = std::make_unique<QmlPreview::QmlDebugTranslationClient>(connection); auto client = std::make_unique<QmlPreview::QmlDebugTranslationClient>(connection);
return client; return client;
}; }
class QmlPreviewPluginPrivate : public QObject class QmlPreviewPluginPrivate : public QObject
{ {
public: public:
explicit QmlPreviewPluginPrivate(QmlPreviewPlugin *parent); explicit QmlPreviewPluginPrivate(QmlPreviewPlugin *parent);
void previewCurrentFile();
void onEditorChanged(Core::IEditor *editor); void onEditorChanged(Core::IEditor *editor);
void onEditorAboutToClose(Core::IEditor *editor); void onEditorAboutToClose(Core::IEditor *editor);
void setDirty(); void setDirty();
void addPreview(ProjectExplorer::RunControl *preview);
void removePreview(ProjectExplorer::RunControl *preview);
void attachToEditor(); void attachToEditor();
void checkEditor(); void checkEditor();
void checkFile(const QString &fileName); void checkFile(const QString &fileName);
@@ -114,7 +111,7 @@ public:
QmlPreviewRunControlList runningPreviews() const; QmlPreviewRunControlList runningPreviews() const;
QmlPreviewFileClassifier fileClassifier() const; QmlPreviewFileClassifier fileClassifier() const;
void setFileClassifier(QmlPreviewFileClassifier fileClassifer); void setFileClassifier(QmlPreviewFileClassifier fileClassifier);
float zoomFactor() const; float zoomFactor() const;
void setZoomFactor(float zoomFactor); void setZoomFactor(float zoomFactor);
@@ -128,60 +125,24 @@ public:
QmlPreviewPlugin *q = nullptr; QmlPreviewPlugin *q = nullptr;
QThread m_parseThread; QThread m_parseThread;
QString m_previewedFile; QString m_previewedFile;
QmlPreviewFileLoader m_fileLoader = nullptr;
Core::IEditor *m_lastEditor = nullptr; Core::IEditor *m_lastEditor = nullptr;
QmlPreviewRunControlList m_runningPreviews; QmlPreviewRunControlList m_runningPreviews;
bool m_dirty = false; bool m_dirty = false;
QmlPreview::QmlPreviewFileClassifier m_fileClassifer = nullptr;
float m_zoomFactor = -1.0;
QmlPreview::QmlPreviewFpsHandler m_fpsHandler = nullptr;
QString m_localeIsoCode; QString m_localeIsoCode;
QmlDebugTranslationClientCreator m_createDebugTranslationClientMethod;
LocalQmlPreviewSupportFactory localRunWorkerFactory; LocalQmlPreviewSupportFactory localRunWorkerFactory;
RunWorkerFactory runWorkerFactory{ QmlPreviewRunnerSetting m_settings;
[this](RunControl *runControl) { QmlPreviewRunWorkerFactory runWorkerFactory;
QmlPreviewRunner *runner = new QmlPreviewRunner(QmlPreviewRunnerSetting{
runControl,
m_fileLoader,
m_fileClassifer,
m_fpsHandler,
m_zoomFactor,
m_localeIsoCode,
m_createDebugTranslationClientMethod
});
connect(q, &QmlPreviewPlugin::updatePreviews,
runner, &QmlPreviewRunner::loadFile);
connect(q, &QmlPreviewPlugin::rerunPreviews,
runner, &QmlPreviewRunner::rerun);
connect(runner, &QmlPreviewRunner::ready,
this, &QmlPreviewPluginPrivate::previewCurrentFile);
connect(q, &QmlPreviewPlugin::zoomFactorChanged,
runner, &QmlPreviewRunner::zoom);
connect(q, &QmlPreviewPlugin::localeIsoCodeChanged,
runner, &QmlPreviewRunner::language);
connect(runner, &RunWorker::started, this, [this, runControl] {
addPreview(runControl);
});
connect(runner, &RunWorker::stopped, this, [this, runControl] {
removePreview(runControl);
});
return runner;
},
{Constants::QML_PREVIEW_RUNNER}
};
}; };
QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent) QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
: q(parent) : q(parent), runWorkerFactory(parent, &m_settings)
{ {
m_fileLoader = &defaultFileLoader; m_settings.fileLoader = &defaultFileLoader;
m_fileClassifer = &defaultFileClassifier; m_settings.fileClassifier = &defaultFileClassifier;
m_fpsHandler = &defaultFpsHandler; m_settings.fpsHandler = &defaultFpsHandler;
m_createDebugTranslationClientMethod = &defaultCreateDebugTranslationClientMethod; m_settings.createDebugTranslationClientMethod = &defaultCreateDebugTranslationClientMethod;
Core::ActionContainer *menu = Core::ActionManager::actionContainer( Core::ActionContainer *menu = Core::ActionManager::actionContainer(
Constants::M_BUILDPROJECT); Constants::M_BUILDPROJECT);
@@ -211,7 +172,7 @@ QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
action, [action](const QmlPreviewRunControlList &previews) { action, [action](const QmlPreviewRunControlList &previews) {
action->setEnabled(!previews.isEmpty()); action->setEnabled(!previews.isEmpty());
}); });
connect(action, &QAction::triggered, this, &QmlPreviewPluginPrivate::previewCurrentFile); connect(action, &QAction::triggered, q, &QmlPreviewPlugin::previewCurrentFile);
menu->addAction( menu->addAction(
Core::ActionManager::registerAction(action, "QmlPreview.PreviewFile", Core::Context(Constants::C_PROJECT_TREE)), Core::ActionManager::registerAction(action, "QmlPreview.PreviewFile", Core::Context(Constants::C_PROJECT_TREE)),
Constants::G_FILE_OTHER); Constants::G_FILE_OTHER);
@@ -285,49 +246,49 @@ QmlPreviewRunControlList QmlPreviewPlugin::runningPreviews() const
QmlPreviewFileLoader QmlPreviewPlugin::fileLoader() const QmlPreviewFileLoader QmlPreviewPlugin::fileLoader() const
{ {
return d->m_fileLoader; return d->m_settings.fileLoader;
} }
QmlPreviewFileClassifier QmlPreviewPlugin::fileClassifier() const QmlPreviewFileClassifier QmlPreviewPlugin::fileClassifier() const
{ {
return d->m_fileClassifer; return d->m_settings.fileClassifier;
} }
void QmlPreviewPlugin::setFileClassifier(QmlPreviewFileClassifier fileClassifer) void QmlPreviewPlugin::setFileClassifier(QmlPreviewFileClassifier fileClassifier)
{ {
if (d->m_fileClassifer == fileClassifer) if (d->m_settings.fileClassifier == fileClassifier)
return; return;
d->m_fileClassifer = fileClassifer; d->m_settings.fileClassifier = fileClassifier;
emit fileClassifierChanged(d->m_fileClassifer); emit fileClassifierChanged(d->m_settings.fileClassifier);
} }
float QmlPreviewPlugin::zoomFactor() const float QmlPreviewPlugin::zoomFactor() const
{ {
return d->m_zoomFactor; return d->m_settings.zoomFactor;
} }
void QmlPreviewPlugin::setZoomFactor(float zoomFactor) void QmlPreviewPlugin::setZoomFactor(float zoomFactor)
{ {
if (d->m_zoomFactor == zoomFactor) if (d->m_settings.zoomFactor == zoomFactor)
return; return;
d->m_zoomFactor = zoomFactor; d->m_settings.zoomFactor = zoomFactor;
emit zoomFactorChanged(d->m_zoomFactor); emit zoomFactorChanged(d->m_settings.zoomFactor);
} }
QmlPreviewFpsHandler QmlPreviewPlugin::fpsHandler() const QmlPreviewFpsHandler QmlPreviewPlugin::fpsHandler() const
{ {
return d->m_fpsHandler; return d->m_settings.fpsHandler;
} }
void QmlPreviewPlugin::setFpsHandler(QmlPreviewFpsHandler fpsHandler) void QmlPreviewPlugin::setFpsHandler(QmlPreviewFpsHandler fpsHandler)
{ {
if (d->m_fpsHandler == fpsHandler) if (d->m_settings.fpsHandler == fpsHandler)
return; return;
d->m_fpsHandler = fpsHandler; d->m_settings.fpsHandler = fpsHandler;
emit fpsHandlerChanged(d->m_fpsHandler); emit fpsHandlerChanged(d->m_settings.fpsHandler);
} }
QString QmlPreviewPlugin::localeIsoCode() const QString QmlPreviewPlugin::localeIsoCode() const
@@ -348,19 +309,19 @@ void QmlPreviewPlugin::setLocaleIsoCode(const QString &localeIsoCode)
void QmlPreviewPlugin::setQmlDebugTranslationClientCreator(QmlDebugTranslationClientCreator creator) void QmlPreviewPlugin::setQmlDebugTranslationClientCreator(QmlDebugTranslationClientCreator creator)
{ {
d->m_createDebugTranslationClientMethod = creator; d->m_settings.createDebugTranslationClientMethod = creator;
} }
void QmlPreviewPlugin::setFileLoader(QmlPreviewFileLoader fileLoader) void QmlPreviewPlugin::setFileLoader(QmlPreviewFileLoader fileLoader)
{ {
if (d->m_fileLoader == fileLoader) if (d->m_settings.fileLoader == fileLoader)
return; return;
d->m_fileLoader = fileLoader; d->m_settings.fileLoader = fileLoader;
emit fileLoaderChanged(d->m_fileLoader); emit fileLoaderChanged(d->m_settings.fileLoader);
} }
void QmlPreviewPluginPrivate::previewCurrentFile() void QmlPreviewPlugin::previewCurrentFile()
{ {
const Node *currentNode = ProjectTree::currentNode(); const Node *currentNode = ProjectTree::currentNode();
if (!currentNode || !currentNode->asFileNode() if (!currentNode || !currentNode->asFileNode()
@@ -368,10 +329,10 @@ void QmlPreviewPluginPrivate::previewCurrentFile()
return; return;
const QString file = currentNode->filePath().toString(); const QString file = currentNode->filePath().toString();
if (file != m_previewedFile) if (file != d->m_previewedFile)
q->setPreviewedFile(file); setPreviewedFile(file);
else else
checkFile(file); d->checkFile(file);
} }
void QmlPreviewPluginPrivate::onEditorChanged(Core::IEditor *editor) void QmlPreviewPluginPrivate::onEditorChanged(Core::IEditor *editor)
@@ -420,16 +381,16 @@ void QmlPreviewPluginPrivate::setDirty()
}); });
} }
void QmlPreviewPluginPrivate::addPreview(ProjectExplorer::RunControl *preview) void QmlPreviewPlugin::addPreview(RunControl *preview)
{ {
m_runningPreviews.append(preview); d->m_runningPreviews.append(preview);
emit q->runningPreviewsChanged(m_runningPreviews); emit runningPreviewsChanged(d->m_runningPreviews);
} }
void QmlPreviewPluginPrivate::removePreview(ProjectExplorer::RunControl *preview) void QmlPreviewPlugin::removePreview(RunControl *preview)
{ {
m_runningPreviews.removeOne(preview); d->m_runningPreviews.removeOne(preview);
emit q->runningPreviewsChanged(m_runningPreviews); emit runningPreviewsChanged(d->m_runningPreviews);
} }
void QmlPreviewPluginPrivate::attachToEditor() void QmlPreviewPluginPrivate::attachToEditor()
@@ -472,11 +433,11 @@ void QmlPreviewPluginPrivate::checkEditor()
void QmlPreviewPluginPrivate::checkFile(const QString &fileName) void QmlPreviewPluginPrivate::checkFile(const QString &fileName)
{ {
if (!m_fileLoader) if (!m_settings.fileLoader)
return; return;
bool success = false; bool success = false;
const QByteArray contents = m_fileLoader(fileName, &success); const QByteArray contents = m_settings.fileLoader(fileName, &success);
if (success) { if (success) {
emit q->checkDocument(fileName, emit q->checkDocument(fileName,
@@ -490,7 +451,7 @@ void QmlPreviewPluginPrivate::checkFile(const QString &fileName)
void QmlPreviewPluginPrivate::triggerPreview(const QString &changedFile, const QByteArray &contents) void QmlPreviewPluginPrivate::triggerPreview(const QString &changedFile, const QByteArray &contents)
{ {
if (m_previewedFile.isEmpty()) if (m_previewedFile.isEmpty())
previewCurrentFile(); q->previewCurrentFile();
else else
emit q->updatePreviews(m_previewedFile, changedFile, contents); emit q->updatePreviews(m_previewedFile, changedFile, contents);
} }

View File

@@ -15,15 +15,18 @@
namespace Core { class IEditor; } namespace Core { class IEditor; }
namespace ProjectExplorer { class RunControl; }
namespace QmlDebug { class QmlDebugConnection; } namespace QmlDebug { class QmlDebugConnection; }
namespace QmlPreview { namespace QmlPreview {
typedef bool (*QmlPreviewFileClassifier) (const QString &); using QmlPreviewFileClassifier = bool (*)(const QString &);
typedef QByteArray (*QmlPreviewFileLoader)(const QString &, bool *); using QmlPreviewFileLoader = QByteArray (*)(const QString &, bool *);
typedef void (*QmlPreviewFpsHandler)(quint16[8]); using QmlPreviewFpsHandler = void (*)(quint16[8]);
typedef QList<ProjectExplorer::RunControl *> QmlPreviewRunControlList; using QmlPreviewRunControlList = QList<ProjectExplorer::RunControl *>;
typedef std::function<std::unique_ptr<QmlDebugTranslationClient>(QmlDebug::QmlDebugConnection *)> QmlDebugTranslationClientCreator; using QmlDebugTranslationClientCreator =
std::function<std::unique_ptr<QmlDebugTranslationClient>(QmlDebug::QmlDebugConnection *)>;
class QMLPREVIEW_EXPORT QmlPreviewPlugin : public ExtensionSystem::IPlugin class QMLPREVIEW_EXPORT QmlPreviewPlugin : public ExtensionSystem::IPlugin
{ {
@@ -70,6 +73,10 @@ public:
void setQmlDebugTranslationClientCreator(QmlDebugTranslationClientCreator creator); void setQmlDebugTranslationClientCreator(QmlDebugTranslationClientCreator creator);
void previewCurrentFile();
void addPreview(ProjectExplorer::RunControl *preview);
void removePreview(ProjectExplorer::RunControl *preview);
signals: signals:
void checkDocument(const QString &name, const QByteArray &contents, void checkDocument(const QString &name, const QByteArray &contents,
QmlJS::Dialect::Enum dialect); QmlJS::Dialect::Enum dialect);

View File

@@ -1,6 +1,7 @@
// Copyright (C) 2019 The Qt Company Ltd. // Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qmlpreviewconnectionmanager.h"
#include "qmlpreviewruncontrol.h" #include "qmlpreviewruncontrol.h"
#include <qmlprojectmanager/qmlproject.h> #include <qmlprojectmanager/qmlproject.h>
@@ -22,13 +23,39 @@
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;
using namespace QmlPreview::Internal;
namespace QmlPreview { namespace QmlPreview {
static const QString QmlServerUrl = "QmlServerUrl"; static const QString QmlServerUrl = "QmlServerUrl";
QmlPreviewRunner::QmlPreviewRunner(const QmlPreviewRunnerSetting &settings) class QmlPreviewRunner : public ProjectExplorer::RunWorker
: RunWorker(settings.runControl) {
Q_OBJECT
public:
QmlPreviewRunner(ProjectExplorer::RunControl *runControl,
const QmlPreviewRunnerSetting &settings);
void setServerUrl(const QUrl &serverUrl);
QUrl serverUrl() const;
signals:
void loadFile(const QString &previewedFile, const QString &changedFile,
const QByteArray &contents);
void language(const QString &locale);
void zoom(float zoomFactor);
void rerun();
void ready();
private:
void start() override;
void stop() override;
Internal::QmlPreviewConnectionManager m_connectionManager;
};
QmlPreviewRunner::QmlPreviewRunner(RunControl *runControl, const QmlPreviewRunnerSetting &settings)
: RunWorker(runControl)
{ {
setId("QmlPreviewRunner"); setId("QmlPreviewRunner");
m_connectionManager.setFileLoader(settings.fileLoader); m_connectionManager.setFileLoader(settings.fileLoader);
@@ -38,37 +65,36 @@ QmlPreviewRunner::QmlPreviewRunner(const QmlPreviewRunnerSetting &settings)
settings.createDebugTranslationClientMethod); settings.createDebugTranslationClientMethod);
connect(this, &QmlPreviewRunner::loadFile, connect(this, &QmlPreviewRunner::loadFile,
&m_connectionManager, &Internal::QmlPreviewConnectionManager::loadFile); &m_connectionManager, &QmlPreviewConnectionManager::loadFile);
connect(this, &QmlPreviewRunner::rerun, connect(this, &QmlPreviewRunner::rerun,
&m_connectionManager, &Internal::QmlPreviewConnectionManager::rerun); &m_connectionManager, &QmlPreviewConnectionManager::rerun);
connect(this, &QmlPreviewRunner::zoom, connect(this, &QmlPreviewRunner::zoom,
&m_connectionManager, &Internal::QmlPreviewConnectionManager::zoom); &m_connectionManager, &QmlPreviewConnectionManager::zoom);
connect(this, &QmlPreviewRunner::language, connect(this, &QmlPreviewRunner::language,
&m_connectionManager, &Internal::QmlPreviewConnectionManager::language); &m_connectionManager, &QmlPreviewConnectionManager::language);
connect(&m_connectionManager, &Internal::QmlPreviewConnectionManager::connectionOpened, connect(&m_connectionManager, &QmlPreviewConnectionManager::connectionOpened,
this, [this, settings]() { this, [this, settings]() {
if (settings.zoom > 0) if (settings.zoomFactor > 0)
emit zoom(settings.zoom); emit zoom(settings.zoomFactor);
if (!settings.language.isEmpty()) if (!settings.language.isEmpty())
emit language(settings.language); emit language(settings.language);
emit ready(); emit ready();
}); });
connect(&m_connectionManager, &Internal::QmlPreviewConnectionManager::restart, connect(&m_connectionManager, &QmlPreviewConnectionManager::restart, runControl, [this, runControl] {
runControl(), [this]() { if (!runControl->isRunning())
if (!runControl()->isRunning())
return; return;
this->connect(runControl(), &RunControl::stopped, [this] { this->connect(runControl, &RunControl::stopped, [this, runControl] {
auto rc = new RunControl(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE); auto rc = new RunControl(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE);
rc->copyDataFromRunControl(runControl()); rc->copyDataFromRunControl(runControl);
ProjectExplorerPlugin::startRunControl(rc); ProjectExplorerPlugin::startRunControl(rc);
}); });
runControl()->initiateStop(); runControl->initiateStop();
}); });
} }
@@ -95,6 +121,34 @@ QUrl QmlPreviewRunner::serverUrl() const
return recordedData(QmlServerUrl).toUrl(); return recordedData(QmlServerUrl).toUrl();
} }
QmlPreviewRunWorkerFactory::QmlPreviewRunWorkerFactory(QmlPreviewPlugin *plugin,
const QmlPreviewRunnerSetting *runnerSettings)
{
setProducer([this, plugin, runnerSettings](RunControl *runControl) {
auto runner = new QmlPreviewRunner(runControl, *runnerSettings);
QObject::connect(plugin, &QmlPreviewPlugin::updatePreviews,
runner, &QmlPreviewRunner::loadFile);
QObject::connect(plugin, &QmlPreviewPlugin::rerunPreviews,
runner, &QmlPreviewRunner::rerun);
QObject::connect(runner, &QmlPreviewRunner::ready,
plugin, &QmlPreviewPlugin::previewCurrentFile);
QObject::connect(plugin, &QmlPreviewPlugin::zoomFactorChanged,
runner, &QmlPreviewRunner::zoom);
QObject::connect(plugin, &QmlPreviewPlugin::localeIsoCodeChanged,
runner, &QmlPreviewRunner::language);
QObject::connect(runner, &RunWorker::started, plugin, [plugin, runControl] {
plugin->addPreview(runControl);
});
QObject::connect(runner, &RunWorker::stopped, plugin, [plugin, runControl] {
plugin->removePreview(runControl);
});
return runner;
});
addSupportedRunMode(Constants::QML_PREVIEW_RUNNER);
}
class LocalQmlPreviewSupport final : public SimpleTargetRunner class LocalQmlPreviewSupport final : public SimpleTargetRunner
{ {
public: public:
@@ -150,3 +204,5 @@ LocalQmlPreviewSupportFactory::LocalQmlPreviewSupportFactory()
} }
} // QmlPreview } // QmlPreview
#include "qmlpreviewruncontrol.moc"

View File

@@ -3,45 +3,26 @@
#pragma once #pragma once
#include "qmlpreviewconnectionmanager.h"
#include "qmlpreviewfileontargetfinder.h"
#include "qmlpreviewplugin.h" #include "qmlpreviewplugin.h"
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
namespace QmlPreview { namespace QmlPreview {
struct QmlPreviewRunnerSetting { struct QmlPreviewRunnerSetting
ProjectExplorer::RunControl *runControl = nullptr; {
QmlPreviewFileLoader fileLoader; QmlPreviewFileLoader fileLoader;
QmlPreviewFileClassifier fileClassifier; QmlPreviewFileClassifier fileClassifier;
QmlPreviewFpsHandler fpsHandler; QmlPreviewFpsHandler fpsHandler;
float zoom = 1.0; float zoomFactor = 1.0;
QString language; QString language;
QmlDebugTranslationClientCreator createDebugTranslationClientMethod; QmlDebugTranslationClientCreator createDebugTranslationClientMethod;
}; };
class QmlPreviewRunner : public ProjectExplorer::RunWorker class QmlPreviewRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory
{ {
Q_OBJECT
public: public:
QmlPreviewRunner(const QmlPreviewRunnerSetting &settings); QmlPreviewRunWorkerFactory(QmlPreviewPlugin *plugin, const QmlPreviewRunnerSetting *runnerSettings);
void setServerUrl(const QUrl &serverUrl);
QUrl serverUrl() const;
signals:
void loadFile(const QString &previewedFile, const QString &changedFile,
const QByteArray &contents);
void language(const QString &locale);
void zoom(float zoomFactor);
void rerun();
void ready();
private:
void start() override;
void stop() override;
Internal::QmlPreviewConnectionManager m_connectionManager;
}; };
class LocalQmlPreviewSupportFactory final : public ProjectExplorer::RunWorkerFactory class LocalQmlPreviewSupportFactory final : public ProjectExplorer::RunWorkerFactory