Commit 38b4dec7 authored by hjk's avatar hjk

QmlProfiler: Re-organize local run

Having the overall runworker setup closer to the general pattern
allows to re-use SimpleTargetRunner.

Change-Id: Iff151cbebaa6ae6615b933f4277b0581a43d7f7f
Reviewed-by: Christian Kandeler's avatarChristian Kandeler <christian.kandeler@qt.io>
parent f53a0795
...@@ -192,7 +192,7 @@ public: ...@@ -192,7 +192,7 @@ public:
} }
bool canReUseOutputPane(const Runnable &other) const; bool canReUseOutputPane(const Runnable &other) const;
QString displayName() const { return d->displayName(); } QString displayName() const { return d ? d->displayName() : QString(); }
private: private:
std::unique_ptr<Concept> d; std::unique_ptr<Concept> d;
......
...@@ -85,7 +85,8 @@ void FlameGraphView::onVisibleFeaturesChanged(quint64 features) ...@@ -85,7 +85,8 @@ void FlameGraphView::onVisibleFeaturesChanged(quint64 features)
if (features & (1ULL << featureFromRangeType(RangeType(rangeType)))) if (features & (1ULL << featureFromRangeType(RangeType(rangeType))))
rangeTypeMask |= (1 << rangeType); rangeTypeMask |= (1 << rangeType);
} }
m_content->rootObject()->setProperty("visibleRangeTypes", rangeTypeMask); if (m_content->rootObject())
m_content->rootObject()->setProperty("visibleRangeTypes", rangeTypeMask);
} }
void FlameGraphView::contextMenuEvent(QContextMenuEvent *ev) void FlameGraphView::contextMenuEvent(QContextMenuEvent *ev)
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
#include <projectexplorer/runnables.h> #include <projectexplorer/runnables.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtsupportconstants.h>
#include <qmldebug/qmloutputparser.h> #include <qmldebug/qmloutputparser.h>
...@@ -74,9 +76,6 @@ class QmlProfilerRunner::QmlProfilerRunnerPrivate ...@@ -74,9 +76,6 @@ class QmlProfilerRunner::QmlProfilerRunnerPrivate
public: public:
QmlProfilerStateManager *m_profilerState = 0; QmlProfilerStateManager *m_profilerState = 0;
QTimer m_noDebugOutputTimer; QTimer m_noDebugOutputTimer;
bool m_isAutoStart = false;
ProjectExplorer::ApplicationLauncher m_launcher;
QmlDebug::QmlOutputParser m_outputParser;
}; };
// //
...@@ -124,25 +123,7 @@ void QmlProfilerRunner::start() ...@@ -124,25 +123,7 @@ void QmlProfilerRunner::start()
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
if (d->m_isAutoStart) { reportStarted();
StandardRunnable debuggee = runnable().as<StandardRunnable>();
QString arguments = QmlDebug::qmlDebugArguments(QmlDebug::QmlProfilerServices, serverUrl);
if (!debuggee.commandLineArguments.isEmpty())
arguments += ' ' + debuggee.commandLineArguments;
debuggee.commandLineArguments = arguments;
debuggee.runMode = ApplicationLauncher::Gui;
// queue this, as the process can already die in the call to start().
// We want the started() signal to be emitted before the stopped() signal.
connect(&d->m_launcher, &ApplicationLauncher::processExited,
this, &QmlProfilerRunner::spontaneousStop,
Qt::QueuedConnection);
d->m_launcher.start(debuggee);
emit localRunnerStarted();
}
} }
void QmlProfilerRunner::stop() void QmlProfilerRunner::stop()
...@@ -294,58 +275,64 @@ QUrl QmlProfilerRunner::serverUrl() const ...@@ -294,58 +275,64 @@ QUrl QmlProfilerRunner::serverUrl() const
return connection().as<UrlConnection>(); return connection().as<UrlConnection>();
} }
void QmlProfilerRunner::setAutoStart() //
// LocalQmlProfilerSupport
//
static QUrl localServerUrl(RunControl *runControl)
{ {
d->m_isAutoStart = true; QUrl serverUrl;
connect(&d->m_launcher, &ApplicationLauncher::appendMessage, RunConfiguration *runConfiguration = runControl->runConfiguration();
this, &QmlProfilerRunner::appendMessage); Kit *kit = runConfiguration->target()->kit();
connect(this, &QmlProfilerRunner::localRunnerStopped, const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
this, &QmlProfilerRunner::notifyRemoteFinished); if (version) {
connect(runControl(), &RunControl::finished, if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0))
this, &QmlProfilerRunner::stopLocalRunner); serverUrl = UrlConnection::localSocket();
else
d->m_outputParser.setNoOutputText(ApplicationLauncher::msgWinCannotRetrieveDebuggingOutput()); serverUrl = UrlConnection::localHostAndFreePort();
} else {
connect(runControl(), &RunControl::appendMessageRequested, qWarning("Running QML profiler on Kit without Qt version?");
this, [this](RunControl *, const QString &msg, Utils::OutputFormat) { serverUrl = UrlConnection::localHostAndFreePort();
d->m_outputParser.processOutput(msg); }
}); return serverUrl;
}
connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl)
this, [this](Utils::Port port) { : LocalQmlProfilerSupport(runControl, localServerUrl(runControl))
notifyRemoteSetupDone(port); {
}); }
connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::noOutputMessage, LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const QUrl &serverUrl)
this, [this] { : RunWorker(runControl)
notifyRemoteSetupDone(Utils::Port()); {
}); m_profiler = new QmlProfilerRunner(runControl);
m_profiler->setServerUrl(serverUrl);
m_profiler->addDependency(this);
connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::connectingToSocketMessage, StandardRunnable debuggee = runnable().as<StandardRunnable>();
this, [this] { QString arguments = QmlDebug::qmlDebugArguments(QmlDebug::QmlProfilerServices, serverUrl);
notifyRemoteSetupDone(Utils::Port());
});
connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::errorMessage, if (!debuggee.commandLineArguments.isEmpty())
this, [this](const QString &message) { arguments += ' ' + debuggee.commandLineArguments;
notifyRemoteSetupFailed(message);
}); debuggee.commandLineArguments = arguments;
debuggee.runMode = ApplicationLauncher::Gui;
m_profilee = new SimpleTargetRunner(runControl);
m_profilee->setRunnable(debuggee);
addDependency(m_profilee);
} }
void QmlProfilerRunner::spontaneousStop(int exitCode, QProcess::ExitStatus status) void LocalQmlProfilerSupport::start()
{ {
Q_UNUSED(exitCode); reportStarted();
Q_UNUSED(status); emit localRunnerStarted();
disconnect(&d->m_launcher, &ApplicationLauncher::processExited,
this, &QmlProfilerRunner::spontaneousStop);
emit localRunnerStopped();
} }
void QmlProfilerRunner::stopLocalRunner() void LocalQmlProfilerSupport::stop()
{ {
if (d->m_launcher.isRunning()) reportStopped();
d->m_launcher.stop(); emit localRunnerStopped();
} }
} // namespace QmlProfiler } // namespace QmlProfiler
...@@ -54,11 +54,6 @@ public: ...@@ -54,11 +54,6 @@ public:
void notifyRemoteSetupFailed(const QString &errorMessage); void notifyRemoteSetupFailed(const QString &errorMessage);
void cancelProcess(); void cancelProcess();
void notifyRemoteFinished(); void notifyRemoteFinished();
void setAutoStart();
signals:
void localRunnerStarted();
void localRunnerStopped();
private: private:
void start() override; void start() override;
...@@ -67,12 +62,29 @@ private: ...@@ -67,12 +62,29 @@ private:
void wrongSetupMessageBoxFinished(int); void wrongSetupMessageBoxFinished(int);
void profilerStateChanged(); void profilerStateChanged();
void spontaneousStop(int exitCode, QProcess::ExitStatus status);
void startLocalRunner();
void stopLocalRunner();
class QmlProfilerRunnerPrivate; class QmlProfilerRunnerPrivate;
QmlProfilerRunnerPrivate *d; QmlProfilerRunnerPrivate *d;
}; };
class LocalQmlProfilerSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT
public:
LocalQmlProfilerSupport(ProjectExplorer::RunControl *runControl);
LocalQmlProfilerSupport(ProjectExplorer::RunControl *runControl,
const QUrl &serverUrl);
void start() override;
void stop() override;
signals:
void localRunnerStarted();
void localRunnerStopped();
private:
ProjectExplorer::SimpleTargetRunner *m_profilee;
QmlProfilerRunner *m_profiler;
};
} // namespace QmlProfiler } // namespace QmlProfiler
...@@ -27,22 +27,12 @@ ...@@ -27,22 +27,12 @@
#include "qmlprofilerruncontrol.h" #include "qmlprofilerruncontrol.h"
#include "qmlprofilerrunconfigurationaspect.h" #include "qmlprofilerrunconfigurationaspect.h"
#include <debugger/analyzer/analyzermanager.h>
#include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/environmentaspect.h> #include <projectexplorer/environmentaspect.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
using namespace Debugger;
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace QmlProfiler { namespace QmlProfiler {
...@@ -69,28 +59,8 @@ bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, Co ...@@ -69,28 +59,8 @@ bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, Co
RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *) RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *)
{ {
QTC_ASSERT(canRun(runConfiguration, mode), return 0); auto runControl = new RunControl(runConfiguration, mode);
QTC_ASSERT(runConfiguration->runnable().is<StandardRunnable>(), return 0); (void) new LocalQmlProfilerSupport(runControl);
Kit *kit = runConfiguration->target()->kit();
QUrl serverUrl;
const QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit);
if (version) {
if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0))
serverUrl = UrlConnection::localSocket();
else
serverUrl = UrlConnection::localHostAndFreePort();
} else {
qWarning("Running QML profiler on Kit without Qt version?");
serverUrl = UrlConnection::localHostAndFreePort();
}
auto runControl = new RunControl(runConfiguration, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
runControl->setConnection(UrlConnection(serverUrl));
auto runner = new QmlProfilerRunner(runControl);
runner->setServerUrl(serverUrl);
runner->setAutoStart();
return runControl; return runControl;
} }
......
...@@ -43,18 +43,23 @@ LocalQmlProfilerRunnerTest::LocalQmlProfilerRunnerTest(QObject *parent) : QObjec ...@@ -43,18 +43,23 @@ LocalQmlProfilerRunnerTest::LocalQmlProfilerRunnerTest(QObject *parent) : QObjec
{ {
} }
void LocalQmlProfilerRunnerTest::connectRunner(QmlProfilerRunner *runner) void LocalQmlProfilerRunnerTest::start()
{ {
runner->setAutoStart(); delete runControl;
connect(runner, &QmlProfilerRunner::localRunnerStarted, this, [this] { runControl = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
runControl->setRunnable(debuggee);
auto runner = new LocalQmlProfilerSupport(runControl, serverUrl);
connect(runner, &LocalQmlProfilerSupport::localRunnerStarted, this, [this] {
QVERIFY(!running); QVERIFY(!running);
++runCount; ++runCount;
running = true; running = true;
}); });
connect(runner, &QmlProfilerRunner::localRunnerStopped, this, [this] { connect(runner, &LocalQmlProfilerSupport::localRunnerStopped, this, [this] {
QVERIFY(running); QVERIFY(running);
running = false; running = false;
}); });
runControl->initiateStart();
} }
void LocalQmlProfilerRunnerTest::testRunner() void LocalQmlProfilerRunnerTest::testRunner()
...@@ -65,13 +70,8 @@ void LocalQmlProfilerRunnerTest::testRunner() ...@@ -65,13 +70,8 @@ void LocalQmlProfilerRunnerTest::testRunner()
// should not be used anywhere but cannot be empty // should not be used anywhere but cannot be empty
serverUrl.setPath("invalid"); serverUrl.setPath("invalid");
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); start();
rc->setRunnable(debuggee);
auto runner = new QmlProfilerRunner(rc);
runner->setServerUrl(serverUrl);
connectRunner(runner);
rc->initiateStart();
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner1); QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner1);
} }
...@@ -86,13 +86,8 @@ void LocalQmlProfilerRunnerTest::testRunner1() ...@@ -86,13 +86,8 @@ void LocalQmlProfilerRunnerTest::testRunner1()
// comma is used to specify a test function. In this case, an invalid one. // comma is used to specify a test function. In this case, an invalid one.
debuggee.commandLineArguments = QString("-test QmlProfiler,"); debuggee.commandLineArguments = QString("-test QmlProfiler,");
delete rc; start();
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
rc->setRunnable(debuggee);
auto runner = new QmlProfilerRunner(rc);
runner->setServerUrl(serverUrl);
connectRunner(runner);
rc->initiateStart();
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2); QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner2);
} }
...@@ -101,16 +96,10 @@ void LocalQmlProfilerRunnerTest::testRunner2() ...@@ -101,16 +96,10 @@ void LocalQmlProfilerRunnerTest::testRunner2()
QTRY_COMPARE_WITH_TIMEOUT(runCount, 2, 10000); QTRY_COMPARE_WITH_TIMEOUT(runCount, 2, 10000);
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000); QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
delete rc;
debuggee.commandLineArguments.clear(); debuggee.commandLineArguments.clear();
serverUrl = UrlConnection::localHostAndFreePort(); serverUrl = UrlConnection::localHostAndFreePort();
rc = new ProjectExplorer::RunControl(nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
rc->setRunnable(debuggee); start();
auto runner = new QmlProfilerRunner(rc);
runner->setServerUrl(serverUrl);
connectRunner(runner);
rc->initiateStart();
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner3); QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner3);
} }
...@@ -118,14 +107,14 @@ void LocalQmlProfilerRunnerTest::testRunner2() ...@@ -118,14 +107,14 @@ void LocalQmlProfilerRunnerTest::testRunner2()
void LocalQmlProfilerRunnerTest::testRunner3() void LocalQmlProfilerRunnerTest::testRunner3()
{ {
QTRY_COMPARE_WITH_TIMEOUT(runCount, 3, 10000); QTRY_COMPARE_WITH_TIMEOUT(runCount, 3, 10000);
rc->initiateStop(); runControl->initiateStop();
QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner4); QTimer::singleShot(0, this, &LocalQmlProfilerRunnerTest::testRunner4);
} }
void LocalQmlProfilerRunnerTest::testRunner4() void LocalQmlProfilerRunnerTest::testRunner4()
{ {
QTRY_VERIFY_WITH_TIMEOUT(!running, 10000); QTRY_VERIFY_WITH_TIMEOUT(!running, 10000);
delete rc; delete runControl;
} }
void LocalQmlProfilerRunnerTest::testFindFreePort() void LocalQmlProfilerRunnerTest::testFindFreePort()
......
...@@ -45,7 +45,7 @@ private slots: ...@@ -45,7 +45,7 @@ private slots:
void testFindFreeSocket(); void testFindFreeSocket();
private: private:
void connectRunner(QmlProfilerRunner *runner); void start();
void testRunner1(); void testRunner1();
void testRunner2(); void testRunner2();
void testRunner3(); void testRunner3();
...@@ -53,7 +53,7 @@ private: ...@@ -53,7 +53,7 @@ private:
bool running = false; bool running = false;
int runCount = 0; int runCount = 0;
ProjectExplorer::RunControl *rc = nullptr; ProjectExplorer::RunControl *runControl = nullptr;
ProjectExplorer::StandardRunnable debuggee; ProjectExplorer::StandardRunnable debuggee;
ProjectExplorer::UrlConnection serverUrl; ProjectExplorer::UrlConnection serverUrl;
}; };
......
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