forked from qt-creator/qt-creator
QmlPreview: Get rid of permanent thread
Use TaskTree with AsyncTask instead, on demand. Change-Id: I227858eceef822c4106165c561f8ede56dfb78ca Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -11,6 +11,8 @@
|
|||||||
#include "tests/qmlpreviewplugin_test.h"
|
#include "tests/qmlpreviewplugin_test.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <android/androidconstants.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
@@ -40,10 +42,11 @@
|
|||||||
#include <qtsupport/qtversionmanager.h>
|
#include <qtsupport/qtversionmanager.h>
|
||||||
#include <qtsupport/baseqtversion.h>
|
#include <qtsupport/baseqtversion.h>
|
||||||
|
|
||||||
|
#include <solutions/tasking/tasktreerunner.h>
|
||||||
|
|
||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
|
|
||||||
#include <android/androidconstants.h>
|
#include <utils/async.h>
|
||||||
|
|
||||||
#include <utils/icon.h>
|
#include <utils/icon.h>
|
||||||
#include <utils/mimeconstants.h>
|
#include <utils/mimeconstants.h>
|
||||||
#include <utils/proxyaction.h>
|
#include <utils/proxyaction.h>
|
||||||
@@ -55,22 +58,10 @@
|
|||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Tasking;
|
||||||
|
|
||||||
namespace QmlPreview {
|
namespace QmlPreview {
|
||||||
|
|
||||||
class QmlPreviewParser : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
QmlPreviewParser();
|
|
||||||
void parse(const QString &name, const QByteArray &contents,
|
|
||||||
QmlJS::Dialect::Enum dialect);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void success(const QString &changedFile, const QByteArray &contents);
|
|
||||||
void failure();
|
|
||||||
};
|
|
||||||
|
|
||||||
static QByteArray defaultFileLoader(const QString &filename, bool *success)
|
static QByteArray defaultFileLoader(const QString &filename, bool *success)
|
||||||
{
|
{
|
||||||
if (Core::DocumentModel::Entry *entry
|
if (Core::DocumentModel::Entry *entry
|
||||||
@@ -119,9 +110,9 @@ public:
|
|||||||
void checkEditor();
|
void checkEditor();
|
||||||
void checkFile(const QString &fileName);
|
void checkFile(const QString &fileName);
|
||||||
void triggerPreview(const QString &changedFile, const QByteArray &contents);
|
void triggerPreview(const QString &changedFile, const QByteArray &contents);
|
||||||
|
void checkDocument(const QString &name, const QByteArray &contents, QmlJS::Dialect::Enum dialect);
|
||||||
|
|
||||||
QmlPreviewPlugin *q = nullptr;
|
QmlPreviewPlugin *q = nullptr;
|
||||||
QThread m_parseThread;
|
|
||||||
QString m_previewedFile;
|
QString m_previewedFile;
|
||||||
QPointer<Core::IEditor> m_lastEditor;
|
QPointer<Core::IEditor> m_lastEditor;
|
||||||
QmlPreviewRunControlList m_runningPreviews;
|
QmlPreviewRunControlList m_runningPreviews;
|
||||||
@@ -132,6 +123,8 @@ public:
|
|||||||
|
|
||||||
QmlPreviewRunnerSetting m_settings;
|
QmlPreviewRunnerSetting m_settings;
|
||||||
QmlPreviewRunWorkerFactory runWorkerFactory;
|
QmlPreviewRunWorkerFactory runWorkerFactory;
|
||||||
|
|
||||||
|
TaskTreeRunner m_parseRunner;
|
||||||
};
|
};
|
||||||
|
|
||||||
QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
|
QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
|
||||||
@@ -210,13 +203,7 @@ QmlPreviewPluginPrivate::QmlPreviewPluginPrivate(QmlPreviewPlugin *parent)
|
|||||||
toolBar->insertAction(nullptr, action);
|
toolBar->insertAction(nullptr, action);
|
||||||
});
|
});
|
||||||
|
|
||||||
m_parseThread.start();
|
|
||||||
QmlPreviewParser *parser = new QmlPreviewParser;
|
|
||||||
parser->moveToThread(&m_parseThread);
|
|
||||||
connect(&m_parseThread, &QThread::finished, parser, &QObject::deleteLater);
|
|
||||||
connect(q, &QmlPreviewPlugin::checkDocument, parser, &QmlPreviewParser::parse);
|
|
||||||
connect(q, &QmlPreviewPlugin::previewedFileChanged, this, &QmlPreviewPluginPrivate::checkFile);
|
connect(q, &QmlPreviewPlugin::previewedFileChanged, this, &QmlPreviewPluginPrivate::checkFile);
|
||||||
connect(parser, &QmlPreviewParser::success, this, &QmlPreviewPluginPrivate::triggerPreview);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlPreviewPlugin::~QmlPreviewPlugin()
|
QmlPreviewPlugin::~QmlPreviewPlugin()
|
||||||
@@ -234,13 +221,6 @@ void QmlPreviewPlugin::initialize()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtensionSystem::IPlugin::ShutdownFlag QmlPreviewPlugin::aboutToShutdown()
|
|
||||||
{
|
|
||||||
d->m_parseThread.quit();
|
|
||||||
d->m_parseThread.wait();
|
|
||||||
return SynchronousShutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QmlPreviewPlugin::previewedFile() const
|
QString QmlPreviewPlugin::previewedFile() const
|
||||||
{
|
{
|
||||||
return d->m_previewedFile;
|
return d->m_previewedFile;
|
||||||
@@ -405,7 +385,7 @@ void QmlPreviewPluginPrivate::onEditorAboutToClose(Core::IEditor *editor)
|
|||||||
void QmlPreviewPluginPrivate::setDirty()
|
void QmlPreviewPluginPrivate::setDirty()
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
QTimer::singleShot(1000, this, [&](){
|
QTimer::singleShot(1000, this, [this] {
|
||||||
if (m_dirty && m_lastEditor) {
|
if (m_dirty && m_lastEditor) {
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
checkEditor();
|
checkEditor();
|
||||||
@@ -479,7 +459,7 @@ void QmlPreviewPluginPrivate::checkEditor()
|
|||||||
dialect = QmlJS::Dialect::QmlQtQuick2Ui;
|
dialect = QmlJS::Dialect::QmlQtQuick2Ui;
|
||||||
else
|
else
|
||||||
dialect = QmlJS::Dialect::NoLanguage;
|
dialect = QmlJS::Dialect::NoLanguage;
|
||||||
emit q->checkDocument(doc->filePath().toString(), doc->contents(), dialect);
|
checkDocument(doc->filePath().toString(), doc->contents(), dialect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlPreviewPluginPrivate::checkFile(const QString &fileName)
|
void QmlPreviewPluginPrivate::checkFile(const QString &fileName)
|
||||||
@@ -491,11 +471,8 @@ void QmlPreviewPluginPrivate::checkFile(const QString &fileName)
|
|||||||
const QByteArray contents = m_settings.fileLoader(fileName, &success);
|
const QByteArray contents = m_settings.fileLoader(fileName, &success);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
emit q->checkDocument(fileName,
|
checkDocument(fileName, contents, QmlJS::ModelManagerInterface::guessLanguageOfFile(
|
||||||
contents,
|
Utils::FilePath::fromUserInput(fileName)).dialect());
|
||||||
QmlJS::ModelManagerInterface::guessLanguageOfFile(
|
|
||||||
Utils::FilePath::fromUserInput(fileName))
|
|
||||||
.dialect());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,29 +484,29 @@ void QmlPreviewPluginPrivate::triggerPreview(const QString &changedFile, const Q
|
|||||||
emit q->updatePreviews(m_previewedFile, changedFile, contents);
|
emit q->updatePreviews(m_previewedFile, changedFile, contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlPreviewParser::QmlPreviewParser()
|
static void parse(QPromise<void> &promise, const QString &name, const QByteArray &contents,
|
||||||
{
|
|
||||||
static const int dialectMeta = qRegisterMetaType<QmlJS::Dialect::Enum>();
|
|
||||||
Q_UNUSED(dialectMeta)
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlPreviewParser::parse(const QString &name, const QByteArray &contents,
|
|
||||||
QmlJS::Dialect::Enum dialect)
|
QmlJS::Dialect::Enum dialect)
|
||||||
{
|
{
|
||||||
if (!QmlJS::Dialect(dialect).isQmlLikeOrJsLanguage()) {
|
if (!QmlJS::Dialect(dialect).isQmlLikeOrJsLanguage())
|
||||||
emit success(name, contents);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
auto qmljsDoc = QmlJS::Document::create(Utils::FilePath::fromString(name), dialect);
|
||||||
|
if (promise.isCanceled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
qmljsDoc->setSource(QString::fromUtf8(contents));
|
||||||
|
if (!qmljsDoc->parse())
|
||||||
|
promise.future().cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlJS::Document::MutablePtr qmljsDoc = QmlJS::Document::create(Utils::FilePath::fromString(name),
|
void QmlPreviewPluginPrivate::checkDocument(const QString &name, const QByteArray &contents,
|
||||||
dialect);
|
QmlJS::Dialect::Enum dialect)
|
||||||
qmljsDoc->setSource(QString::fromUtf8(contents));
|
{
|
||||||
if (qmljsDoc->parse())
|
const auto onParseSetup = [name, contents, dialect](Utils::Async<void> &async) {
|
||||||
emit success(name, contents);
|
async.setConcurrentCallData(parse, name, contents, dialect);
|
||||||
else
|
};
|
||||||
emit failure();
|
const auto onParseDone = [this, name, contents] { triggerPreview(name, contents); };
|
||||||
|
m_parseRunner.start({Utils::AsyncTask<void>(onParseSetup, onParseDone, CallDoneIf::Success)});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlPreview
|
} // namespace QmlPreview
|
||||||
|
|
||||||
#include <qmlpreviewplugin.moc>
|
|
||||||
|
@@ -6,13 +6,9 @@
|
|||||||
#include "qmlpreview_global.h"
|
#include "qmlpreview_global.h"
|
||||||
#include "qmldebugtranslationclient.h"
|
#include "qmldebugtranslationclient.h"
|
||||||
|
|
||||||
#include <projectexplorer/runcontrol.h>
|
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
#include <qmljs/qmljsdialect.h>
|
#include <qmljs/qmljsdialect.h>
|
||||||
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
namespace Core { class IEditor; }
|
namespace Core { class IEditor; }
|
||||||
|
|
||||||
namespace ProjectExplorer { class RunControl; }
|
namespace ProjectExplorer { class RunControl; }
|
||||||
@@ -50,7 +46,6 @@ public:
|
|||||||
~QmlPreviewPlugin() override;
|
~QmlPreviewPlugin() override;
|
||||||
|
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
ShutdownFlag aboutToShutdown() override;
|
|
||||||
|
|
||||||
QString previewedFile() const;
|
QString previewedFile() const;
|
||||||
void setPreviewedFile(const QString &previewedFile);
|
void setPreviewedFile(const QString &previewedFile);
|
||||||
@@ -80,8 +75,6 @@ public:
|
|||||||
void removePreview(ProjectExplorer::RunControl *preview);
|
void removePreview(ProjectExplorer::RunControl *preview);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void checkDocument(const QString &name, const QByteArray &contents,
|
|
||||||
QmlJS::Dialect::Enum dialect);
|
|
||||||
void updatePreviews(const QString &previewedFile, const QString &changedFile,
|
void updatePreviews(const QString &previewedFile, const QString &changedFile,
|
||||||
const QByteArray &contents);
|
const QByteArray &contents);
|
||||||
void previewedFileChanged(const QString &previewedFile);
|
void previewedFileChanged(const QString &previewedFile);
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/runconfiguration.h>
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <projectexplorer/runcontrol.h>
|
||||||
|
|
||||||
namespace QmlPreview {
|
namespace QmlPreview {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user