From 76185b3b0911c6187c705aa9fa3c4239a47178c3 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 29 May 2017 13:14:16 +0200 Subject: [PATCH] QmlProfiler: Convert to a RunWorker based setup This also re-enables the remote linux case and enables the recording of a single run of events. Change-Id: I9ea55017c8e5f2f17e6f32c5453df48093e41931 Reviewed-by: Christian Kandeler Reviewed-by: Christian Stenger --- .../qmlprofiler/localqmlprofilerrunner.cpp | 22 ++++--- .../qmlprofiler/localqmlprofilerrunner.h | 5 +- .../qmlprofiler/qmlprofilermodelmanager.cpp | 2 + .../qmlprofiler/qmlprofilerruncontrol.cpp | 58 +++++++++---------- .../qmlprofiler/qmlprofilerruncontrol.h | 16 ++--- .../qmlprofilerruncontrolfactory.cpp | 5 +- src/plugins/qmlprofiler/qmlprofilertool.cpp | 31 +++++----- src/plugins/qmlprofiler/qmlprofilertool.h | 7 ++- .../tests/localqmlprofilerrunner_test.cpp | 15 +++-- 9 files changed, 90 insertions(+), 71 deletions(-) diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp index ec686bfaf5a..bd3fe0aa95d 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp @@ -25,11 +25,13 @@ #include "localqmlprofilerrunner.h" #include "qmlprofilerplugin.h" +#include "qmlprofilerruncontrol.h" #include #include #include #include +#include #include #include @@ -67,14 +69,16 @@ Utils::Port LocalQmlProfilerRunner::findFreePort(QString &host) } LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, - RunControl *runControl) : - QObject(runControl), + QmlProfilerRunner *runner) : + QObject(runner->runControl()), + m_runControl(runner->runControl()), m_configuration(configuration) { + auto runControl = runner->runControl(); connect(&m_launcher, &ApplicationLauncher::appendMessage, this, &LocalQmlProfilerRunner::appendMessage); connect(this, &LocalQmlProfilerRunner::stopped, - runControl, &RunControl::notifyRemoteFinished); + runner, &QmlProfilerRunner::notifyRemoteFinished); connect(this, &LocalQmlProfilerRunner::appendMessage, runControl, &RunControl::appendMessage); connect(runControl, &RunControl::starting, @@ -92,23 +96,27 @@ LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuratio }); connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, - runControl, [this, runControl](Utils::Port port) { + runControl, [this, runControl, runner](Utils::Port port) { runControl->notifyRemoteSetupDone(port); + runner->notifyRemoteSetupDone(port); }); connect(&m_outputParser, &QmlDebug::QmlOutputParser::noOutputMessage, - runControl, [this, runControl]() { + runControl, [this, runControl, runner]() { runControl->notifyRemoteSetupDone(Utils::Port()); + runner->notifyRemoteSetupDone(Utils::Port()); }); connect(&m_outputParser, &QmlDebug::QmlOutputParser::connectingToSocketMessage, - runControl, [this, runControl]() { + runControl, [this, runControl, runner]() { runControl->notifyRemoteSetupDone(Utils::Port()); + runner->notifyRemoteSetupDone(Utils::Port()); }); connect(&m_outputParser, &QmlDebug::QmlOutputParser::errorMessage, - runControl, [this, runControl](const QString &message) { + runControl, [this, runControl, runner](const QString &message) { runControl->notifyRemoteSetupFailed(message); + runner->notifyRemoteSetupFailed(message); }); } diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.h b/src/plugins/qmlprofiler/localqmlprofilerrunner.h index 62e8c26d619..4758405a7aa 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.h @@ -34,6 +34,8 @@ namespace QmlProfiler { +class QmlProfilerRunner; + class QMLPROFILER_EXPORT LocalQmlProfilerRunner : public QObject { Q_OBJECT @@ -46,7 +48,7 @@ public: }; LocalQmlProfilerRunner(const Configuration &configuration, - ProjectExplorer::RunControl *runControl); + QmlProfilerRunner *runner); static Utils::Port findFreePort(QString &host); static QString findFreeSocket(); @@ -61,6 +63,7 @@ private: void start(); void stop(); + ProjectExplorer::RunControl *m_runControl; Configuration m_configuration; ProjectExplorer::ApplicationLauncher m_launcher; QmlDebug::QmlOutputParser m_outputParser; diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index cc884256da2..3902167af26 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -251,6 +251,8 @@ void QmlProfilerModelManager::addEvents(const QVector &events) void QmlProfilerModelManager::addEvent(const QmlEvent &event) { d->eventStream << event; + QTC_ASSERT(event.typeIndex() < d->eventTypes.size(), + d->eventTypes.resize(event.typeIndex() + 1)); d->dispatch(event, d->eventTypes.at(event.typeIndex())); } diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp index bc537fbb781..337467dfb78 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp @@ -64,7 +64,7 @@ namespace QmlProfiler { // QmlProfilerRunControlPrivate // -class QmlProfilerRunControl::QmlProfilerRunControlPrivate +class QmlProfilerRunner::QmlProfilerRunnerPrivate { public: QmlProfilerStateManager *m_profilerState = 0; @@ -75,12 +75,12 @@ public: // QmlProfilerRunControl // -QmlProfilerRunControl::QmlProfilerRunControl(RunConfiguration *runConfiguration) - : RunControl(runConfiguration, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) - , d(new QmlProfilerRunControlPrivate) +QmlProfilerRunner::QmlProfilerRunner(RunControl *runControl) + : RunWorker(runControl) + , d(new QmlProfilerRunnerPrivate) { - setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR); - setSupportsReRunning(false); + runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR); + runControl->setSupportsReRunning(false); // Only wait 4 seconds for the 'Waiting for connection' on application output, then just try to connect // (application output might be redirected / blocked) @@ -91,20 +91,20 @@ QmlProfilerRunControl::QmlProfilerRunControl(RunConfiguration *runConfiguration) }); } -QmlProfilerRunControl::~QmlProfilerRunControl() +QmlProfilerRunner::~QmlProfilerRunner() { - if (isRunning() && d->m_profilerState) - stop(); + if (runControl()->isRunning() && d->m_profilerState) + runControl()->stop(); delete d; } -void QmlProfilerRunControl::start() +void QmlProfilerRunner::start() { - reportApplicationStart(); + runControl()->reportApplicationStart(); Internal::QmlProfilerTool::instance()->finalizeRunControl(this); - QTC_ASSERT(d->m_profilerState, reportApplicationStop(); return); + QTC_ASSERT(d->m_profilerState, runControl()->reportApplicationStop(); return); - QTC_ASSERT(connection().is(), reportApplicationStop(); return); + QTC_ASSERT(connection().is(), runControl()->reportApplicationStop(); return); auto conn = connection().as(); if (conn.analyzerPort.isValid()) @@ -113,10 +113,10 @@ void QmlProfilerRunControl::start() d->m_noDebugOutputTimer.start(); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); - emit starting(); + emit runControl()->starting(); } -void QmlProfilerRunControl::stop() +void QmlProfilerRunner::stop() { QTC_ASSERT(d->m_profilerState, return); @@ -141,14 +141,14 @@ void QmlProfilerRunControl::stop() } } -void QmlProfilerRunControl::notifyRemoteFinished() +void QmlProfilerRunner::notifyRemoteFinished() { QTC_ASSERT(d->m_profilerState, return); switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::AppRunning: d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying); - reportApplicationStop(); + runControl()->reportApplicationStop(); break; case QmlProfilerStateManager::Idle: break; @@ -160,7 +160,7 @@ void QmlProfilerRunControl::notifyRemoteFinished() } } -void QmlProfilerRunControl::cancelProcess() +void QmlProfilerRunner::cancelProcess() { QTC_ASSERT(d->m_profilerState, return); @@ -177,10 +177,10 @@ void QmlProfilerRunControl::cancelProcess() return; } } - reportApplicationStop(); + runControl()->reportApplicationStop(); } -void QmlProfilerRunControl::notifyRemoteSetupFailed(const QString &errorMessage) +void QmlProfilerRunner::notifyRemoteSetupFailed(const QString &errorMessage) { QMessageBox *infoBox = new QMessageBox(ICore::mainWindow()); infoBox->setIcon(QMessageBox::Critical); @@ -193,17 +193,17 @@ void QmlProfilerRunControl::notifyRemoteSetupFailed(const QString &errorMessage) infoBox->setModal(true); connect(infoBox, &QDialog::finished, - this, &QmlProfilerRunControl::wrongSetupMessageBoxFinished); + this, &QmlProfilerRunner::wrongSetupMessageBoxFinished); infoBox->show(); // KILL d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying); d->m_noDebugOutputTimer.stop(); - reportApplicationStop(); + runControl()->reportApplicationStop(); } -void QmlProfilerRunControl::wrongSetupMessageBoxFinished(int button) +void QmlProfilerRunner::wrongSetupMessageBoxFinished(int button) { if (button == QMessageBox::Help) { HelpManager::handleHelpRequest(QLatin1String("qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html" @@ -211,7 +211,7 @@ void QmlProfilerRunControl::wrongSetupMessageBoxFinished(int button) } } -void QmlProfilerRunControl::notifyRemoteSetupDone(Utils::Port port) +void QmlProfilerRunner::notifyRemoteSetupDone(Utils::Port port) { d->m_noDebugOutputTimer.stop(); @@ -223,26 +223,26 @@ void QmlProfilerRunControl::notifyRemoteSetupDone(Utils::Port port) emit processRunning(port); } -void QmlProfilerRunControl::registerProfilerStateManager( QmlProfilerStateManager *profilerState ) +void QmlProfilerRunner::registerProfilerStateManager( QmlProfilerStateManager *profilerState ) { // disconnect old if (d->m_profilerState) disconnect(d->m_profilerState, &QmlProfilerStateManager::stateChanged, - this, &QmlProfilerRunControl::profilerStateChanged); + this, &QmlProfilerRunner::profilerStateChanged); d->m_profilerState = profilerState; // connect if (d->m_profilerState) connect(d->m_profilerState, &QmlProfilerStateManager::stateChanged, - this, &QmlProfilerRunControl::profilerStateChanged); + this, &QmlProfilerRunner::profilerStateChanged); } -void QmlProfilerRunControl::profilerStateChanged() +void QmlProfilerRunner::profilerStateChanged() { switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::Idle: - reportApplicationStop(); + runControl()->reportApplicationStop(); d->m_noDebugOutputTimer.stop(); break; default: diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h index 9ece8c50675..9ff6106d36f 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h @@ -32,22 +32,22 @@ namespace QmlProfiler { -class QmlProfilerRunControl : public ProjectExplorer::RunControl +class QmlProfilerRunner : public ProjectExplorer::RunWorker { Q_OBJECT public: - QmlProfilerRunControl(ProjectExplorer::RunConfiguration *runConfiguration); - ~QmlProfilerRunControl() override; + QmlProfilerRunner(ProjectExplorer::RunControl *runControl); + ~QmlProfilerRunner() override; void registerProfilerStateManager( QmlProfilerStateManager *profilerState ); - void notifyRemoteSetupDone(Utils::Port port) override; - void notifyRemoteSetupFailed(const QString &errorMessage) override; + void notifyRemoteSetupDone(Utils::Port port); + void notifyRemoteSetupFailed(const QString &errorMessage); void start() override; void stop() override; void cancelProcess(); - void notifyRemoteFinished() override; + void notifyRemoteFinished(); signals: void processRunning(Utils::Port port); @@ -56,8 +56,8 @@ private: void wrongSetupMessageBoxFinished(int); void profilerStateChanged(); - class QmlProfilerRunControlPrivate; - QmlProfilerRunControlPrivate *d; + class QmlProfilerRunnerPrivate; + QmlProfilerRunnerPrivate *d; }; } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp index 577564f3d27..e6cf9ee79ea 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -92,7 +92,8 @@ RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfigurat connection.analyzerPort = LocalQmlProfilerRunner::findFreePort(connection.analyzerHost); } - auto runControl = new QmlProfilerRunControl(runConfiguration); + auto runControl = new RunControl(runConfiguration, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + auto runWorker = runControl->createWorker(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); runControl->setRunnable(runnable); runControl->setConnection(connection); @@ -103,7 +104,7 @@ RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfigurat conf.socket = connection.analyzerSocket; conf.port = connection.analyzerPort; - (void) new LocalQmlProfilerRunner(conf, runControl); + (void) new LocalQmlProfilerRunner(conf, qobject_cast(runWorker)); return runControl; } diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 09d884e4d16..0c57588fc15 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -248,8 +248,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) d->m_profilerModelManager->populateFileFinder(); auto runWorkerCreator = [this](RunControl *runControl) { -// return createRunControl(runConfiguration); - return nullptr; // FIXME + return createRunner(runControl, Debugger::startupRunConfiguration()); }; QString description = tr("The QML Profiler can be used to find performance " @@ -329,7 +328,7 @@ void QmlProfilerTool::updateRunActions() } } -RunControl *QmlProfilerTool::createRunControl(RunConfiguration *runConfiguration) +RunWorker *QmlProfilerTool::createRunner(RunControl *runControl, RunConfiguration *runConfiguration) { d->m_toolBusy = true; if (runConfiguration) { @@ -344,27 +343,27 @@ RunControl *QmlProfilerTool::createRunControl(RunConfiguration *runConfiguration } } - auto runControl = new QmlProfilerRunControl(runConfiguration); + auto runWorker = new QmlProfilerRunner(runControl); connect(runControl, &RunControl::finished, this, [this, runControl] { d->m_toolBusy = false; updateRunActions(); disconnect(d->m_stopAction, &QAction::triggered, runControl, &RunControl::stop); }); - connect(d->m_stopAction, &QAction::triggered, runControl, &QmlProfilerRunControl::stop); + connect(d->m_stopAction, &QAction::triggered, runControl, &RunControl::stop); updateRunActions(); - return runControl; + return runWorker; } -void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl) +void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker) { - runControl->registerProfilerStateManager(d->m_profilerState); + runWorker->registerProfilerStateManager(d->m_profilerState); QmlProfilerClientManager *clientManager = d->m_profilerConnections; - QTC_ASSERT(runControl->connection().is(), return); + QTC_ASSERT(runWorker->connection().is(), return); // FIXME: Check that there's something sensible in sp.connParams - auto connection = runControl->connection().as(); + auto connection = runWorker->connection().as(); if (!connection.analyzerSocket.isEmpty()) { clientManager->setLocalSocket(connection.analyzerSocket); // We open the server and the application connects to it, so let's do that right away. @@ -377,6 +376,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl) // Initialize m_projectFinder // + auto runControl = runWorker->runControl(); RunConfiguration *runConfiguration = runControl->runConfiguration(); if (runConfiguration) { d->m_profilerModelManager->populateFileFinder(runConfiguration); @@ -384,14 +384,14 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl) if (connection.analyzerSocket.isEmpty()) { QString host = connection.analyzerHost; - connect(runControl, &QmlProfilerRunControl::processRunning, + connect(runWorker, &QmlProfilerRunner::processRunning, clientManager, [clientManager, host](Utils::Port port) { clientManager->setTcpConnection(host, port); clientManager->connectToTcpServer(); }); } connect(clientManager, &QmlProfilerClientManager::connectionFailed, - runControl, [this, clientManager, runControl]() { + runWorker, [this, clientManager, runWorker]() { QMessageBox *infoBox = new QMessageBox(ICore::mainWindow()); infoBox->setIcon(QMessageBox::Critical); infoBox->setWindowTitle(tr("Qt Creator")); @@ -401,7 +401,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl) infoBox->setDefaultButton(QMessageBox::Retry); infoBox->setModal(true); - connect(infoBox, &QDialog::finished, runControl, [clientManager, runControl](int result) { + connect(infoBox, &QDialog::finished, runWorker, [clientManager, runWorker](int result) { switch (result) { case QMessageBox::Retry: clientManager->retryConnect(); @@ -412,7 +412,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl) case QMessageBox::Cancel: // The actual error message has already been logged. logState(tr("Failed to connect.")); - runControl->cancelProcess(); + runWorker->cancelProcess(); break; } }); @@ -612,7 +612,8 @@ void QmlProfilerTool::startRemoteTool() Debugger::selectPerspective(Constants::QmlProfilerPerspectiveId); RunConfiguration *rc = Debugger::startupRunConfiguration(); - auto runControl = qobject_cast(createRunControl(rc)); + auto runControl = new RunControl(rc, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + runControl->createWorker(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); runControl->setConnection(connection); ProjectExplorerPlugin::startRunControl(runControl); diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index c9600051b3f..aeffca178b7 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -37,7 +37,7 @@ QT_END_NAMESPACE namespace QmlProfiler { -class QmlProfilerRunControl; +class QmlProfilerRunner; namespace Internal { @@ -51,8 +51,9 @@ public: static QmlProfilerTool *instance(); - ProjectExplorer::RunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration = 0); - void finalizeRunControl(QmlProfilerRunControl *runControl); + ProjectExplorer::RunWorker *createRunner(ProjectExplorer::RunControl *runControl, + ProjectExplorer::RunConfiguration *runConfiguration = 0); + void finalizeRunControl(QmlProfilerRunner *runWorker); bool prepareTool(); void startRemoteTool(); diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp index 2171f45f60d..48d31654926 100644 --- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp +++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp @@ -60,9 +60,10 @@ void LocalQmlProfilerRunnerTest::testRunner() // should not be used anywhere but cannot be empty configuration.socket = connection.analyzerSocket = QString("invalid"); - rc = new QmlProfilerRunControl(nullptr); + rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + auto worker = new QmlProfilerRunner(rc); rc->setConnection(connection); - auto runner = new LocalQmlProfilerRunner(configuration, rc); + auto runner = new LocalQmlProfilerRunner(configuration, worker); connectRunner(runner); rc->initiateStart(); @@ -81,9 +82,10 @@ void LocalQmlProfilerRunnerTest::testRunner1() configuration.debuggee.commandLineArguments = QString("-test QmlProfiler,"); delete rc; - rc = new QmlProfilerRunControl(nullptr); + rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + auto worker = new QmlProfilerRunner(rc); rc->setConnection(connection); - auto runner = new LocalQmlProfilerRunner(configuration, rc); + auto runner = new LocalQmlProfilerRunner(configuration, worker); connectRunner(runner); rc->initiateStart(); QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2); @@ -101,9 +103,10 @@ void LocalQmlProfilerRunnerTest::testRunner2() connection.analyzerSocket.clear(); configuration.port = connection.analyzerPort = LocalQmlProfilerRunner::findFreePort(connection.analyzerHost); - rc = new QmlProfilerRunControl(nullptr); + rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + auto worker = new QmlProfilerRunner(rc); rc->setConnection(connection); - auto runner = new LocalQmlProfilerRunner(configuration, rc); + auto runner = new LocalQmlProfilerRunner(configuration, worker); connectRunner(runner); rc->initiateStart();