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