forked from qt-creator/qt-creator
QmlProfiler: Separate out LocalQmlProfilerRunner from engine
Change-Id: I6f9245179090bebb98b6d9849a7a696105e43a3a Reviewed-by: Christiaan Janssen <christiaan.janssen@digia.com> Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
This commit is contained in:
@@ -43,11 +43,12 @@ class AbstractQmlProfilerRunner : public QObject
|
||||
public:
|
||||
explicit AbstractQmlProfilerRunner(QObject *parent = 0) : QObject(parent) { }
|
||||
|
||||
virtual quint16 debugPort() const = 0;
|
||||
|
||||
public slots:
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
virtual quint16 debugPort() const = 0;
|
||||
|
||||
signals:
|
||||
void started();
|
||||
void stopped();
|
||||
|
||||
@@ -29,13 +29,62 @@
|
||||
|
||||
#include "localqmlprofilerrunner.h"
|
||||
#include "qmlprofilerplugin.h"
|
||||
#include "qmlprofilerengine.h"
|
||||
|
||||
#include <analyzerbase/analyzerstartparameters.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <qmlprojectmanager/qmlprojectrunconfiguration.h>
|
||||
#include <projectexplorer/localapplicationrunconfiguration.h>
|
||||
#include <projectexplorer/environmentaspect.h>
|
||||
|
||||
using namespace QmlProfiler;
|
||||
using namespace QmlProfiler::Internal;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, QObject *parent) :
|
||||
AbstractQmlProfilerRunner(parent),
|
||||
m_configuration(configuration)
|
||||
LocalQmlProfilerRunner *LocalQmlProfilerRunner::createLocalRunner(
|
||||
RunConfiguration *runConfiguration,
|
||||
const Analyzer::AnalyzerStartParameters &sp,
|
||||
QString *errorMessage,
|
||||
QmlProfilerEngine *engine)
|
||||
{
|
||||
QmlProjectManager::QmlProjectRunConfiguration *rc1 =
|
||||
qobject_cast<QmlProjectManager::QmlProjectRunConfiguration *>(runConfiguration);
|
||||
LocalApplicationRunConfiguration *rc2 =
|
||||
qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration);
|
||||
QTC_ASSERT(rc1 || rc2, return 0);
|
||||
ProjectExplorer::EnvironmentAspect *environment
|
||||
= runConfiguration->extraAspect<ProjectExplorer::EnvironmentAspect>();
|
||||
QTC_ASSERT(environment, return 0);
|
||||
Configuration conf;
|
||||
if (rc1) {
|
||||
// This is a "plain" .qmlproject.
|
||||
conf.executable = rc1->observerPath();
|
||||
conf.executableArguments = rc1->viewerArguments();
|
||||
conf.workingDirectory = rc1->workingDirectory();
|
||||
conf.environment = environment->environment();
|
||||
} else {
|
||||
// FIXME: Check.
|
||||
conf.executable = rc2->executable();
|
||||
conf.executableArguments = rc2->commandLineArguments();
|
||||
conf.workingDirectory = rc2->workingDirectory();
|
||||
conf.environment = environment->environment();
|
||||
}
|
||||
|
||||
conf.port = sp.analyzerPort;
|
||||
|
||||
if (conf.executable.isEmpty()) {
|
||||
if (errorMessage)
|
||||
*errorMessage = tr("No executable file to launch.");
|
||||
return 0;
|
||||
}
|
||||
return new LocalQmlProfilerRunner(conf, engine);
|
||||
}
|
||||
|
||||
LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration,
|
||||
QmlProfilerEngine *engine) :
|
||||
AbstractQmlProfilerRunner(engine),
|
||||
m_configuration(configuration),
|
||||
m_engine(engine)
|
||||
{
|
||||
connect(&m_launcher, SIGNAL(appendMessage(QString,Utils::OutputFormat)),
|
||||
this, SIGNAL(appendMessage(QString,Utils::OutputFormat)));
|
||||
@@ -48,6 +97,9 @@ LocalQmlProfilerRunner::~LocalQmlProfilerRunner()
|
||||
|
||||
void LocalQmlProfilerRunner::start()
|
||||
{
|
||||
if (m_engine->mode() != Analyzer::StartQml)
|
||||
return;
|
||||
|
||||
QString arguments = QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_configuration.port);
|
||||
|
||||
if (!m_configuration.executableArguments.isEmpty())
|
||||
@@ -78,6 +130,9 @@ void LocalQmlProfilerRunner::spontaneousStop(int exitCode)
|
||||
|
||||
void LocalQmlProfilerRunner::stop()
|
||||
{
|
||||
if (m_engine->mode() != Analyzer::StartQml)
|
||||
return;
|
||||
|
||||
if (QmlProfilerPlugin::debugOutput)
|
||||
qWarning("QmlProfiler: Stopping application ...");
|
||||
|
||||
|
||||
@@ -35,9 +35,13 @@
|
||||
#include <utils/environment.h>
|
||||
#include <projectexplorer/applicationlauncher.h>
|
||||
|
||||
namespace ProjectExplorer { class RunConfiguration; }
|
||||
namespace Analyzer { class AnalyzerStartParameters; }
|
||||
|
||||
namespace QmlProfiler {
|
||||
namespace Internal {
|
||||
|
||||
class QmlProfilerEngine;
|
||||
class LocalQmlProfilerRunner : public AbstractQmlProfilerRunner
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -51,7 +55,11 @@ public:
|
||||
Utils::Environment environment;
|
||||
};
|
||||
|
||||
explicit LocalQmlProfilerRunner(const Configuration &configuration, QObject *parent = 0);
|
||||
static LocalQmlProfilerRunner *createLocalRunner(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||
const Analyzer::AnalyzerStartParameters &sp,
|
||||
QString *errorMessage,
|
||||
QmlProfilerEngine *engine);
|
||||
|
||||
~LocalQmlProfilerRunner();
|
||||
|
||||
// AbstractQmlProfilerRunner
|
||||
@@ -59,14 +67,16 @@ public:
|
||||
virtual void stop();
|
||||
virtual quint16 debugPort() const;
|
||||
|
||||
bool hasExecutable() const { return !m_configuration.executable.isEmpty(); }
|
||||
|
||||
private slots:
|
||||
void spontaneousStop(int exitCode);
|
||||
|
||||
private:
|
||||
LocalQmlProfilerRunner(const Configuration &configuration, QmlProfilerEngine *engine);
|
||||
|
||||
private:
|
||||
Configuration m_configuration;
|
||||
ProjectExplorer::ApplicationLauncher m_launcher;
|
||||
QmlProfilerEngine *m_engine;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -64,64 +64,20 @@ namespace Internal {
|
||||
class QmlProfilerEngine::QmlProfilerEnginePrivate
|
||||
{
|
||||
public:
|
||||
QmlProfilerEnginePrivate(QmlProfilerEngine *qq, const AnalyzerStartParameters &sp) : q(qq), m_runner(0), sp(sp) {}
|
||||
~QmlProfilerEnginePrivate() { delete m_runner; }
|
||||
QmlProfilerEnginePrivate(QmlProfilerEngine *qq, const AnalyzerStartParameters &sp) : q(qq), sp(sp), m_running(false) {}
|
||||
|
||||
bool attach(const QString &address, uint port);
|
||||
AbstractQmlProfilerRunner *createRunner(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||
QObject *parent);
|
||||
|
||||
QmlProfilerEngine *q;
|
||||
|
||||
QmlProfilerStateManager *m_profilerState;
|
||||
|
||||
AbstractQmlProfilerRunner *m_runner;
|
||||
QTimer m_noDebugOutputTimer;
|
||||
QmlDebug::QmlOutputParser m_outputParser;
|
||||
const AnalyzerStartParameters sp;
|
||||
bool m_running;
|
||||
};
|
||||
|
||||
AbstractQmlProfilerRunner *
|
||||
QmlProfilerEngine::QmlProfilerEnginePrivate::createRunner(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||
QObject *parent)
|
||||
{
|
||||
AbstractQmlProfilerRunner *runner = 0;
|
||||
if (!runConfiguration) // attaching
|
||||
return 0;
|
||||
|
||||
QmlProjectManager::QmlProjectRunConfiguration *rc1 =
|
||||
qobject_cast<QmlProjectManager::QmlProjectRunConfiguration *>(runConfiguration);
|
||||
LocalApplicationRunConfiguration *rc2 =
|
||||
qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration);
|
||||
// Supports only local run configurations
|
||||
if (!rc1 && !rc2)
|
||||
return 0;
|
||||
|
||||
ProjectExplorer::EnvironmentAspect *environment
|
||||
= runConfiguration->extraAspect<ProjectExplorer::EnvironmentAspect>();
|
||||
QTC_ASSERT(environment, return 0);
|
||||
LocalQmlProfilerRunner::Configuration conf;
|
||||
if (rc1) {
|
||||
// This is a "plain" .qmlproject.
|
||||
conf.executable = rc1->observerPath();
|
||||
conf.executableArguments = rc1->viewerArguments();
|
||||
conf.workingDirectory = rc1->workingDirectory();
|
||||
conf.environment = environment->environment();
|
||||
} else {
|
||||
// FIXME: Check.
|
||||
conf.executable = rc2->executable();
|
||||
conf.executableArguments = rc2->commandLineArguments();
|
||||
conf.workingDirectory = rc2->workingDirectory();
|
||||
conf.environment = environment->environment();
|
||||
}
|
||||
const ProjectExplorer::IDevice::ConstPtr device =
|
||||
ProjectExplorer::DeviceKitInformation::device(runConfiguration->target()->kit());
|
||||
QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0);
|
||||
conf.port = sp.analyzerPort;
|
||||
runner = new LocalQmlProfilerRunner(conf, parent);
|
||||
return runner;
|
||||
}
|
||||
|
||||
//
|
||||
// QmlProfilerEngine
|
||||
//
|
||||
@@ -160,11 +116,6 @@ bool QmlProfilerEngine::start()
|
||||
{
|
||||
QTC_ASSERT(d->m_profilerState, return false);
|
||||
|
||||
if (d->m_runner) {
|
||||
delete d->m_runner;
|
||||
d->m_runner = 0;
|
||||
}
|
||||
|
||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStarting);
|
||||
|
||||
if (QmlProjectManager::QmlProjectRunConfiguration *rc =
|
||||
@@ -177,31 +128,14 @@ bool QmlProfilerEngine::start()
|
||||
}
|
||||
}
|
||||
|
||||
d->m_runner = d->createRunner(runConfiguration(), this);
|
||||
|
||||
if (LocalQmlProfilerRunner *qmlRunner = qobject_cast<LocalQmlProfilerRunner *>(d->m_runner)) {
|
||||
if (!qmlRunner->hasExecutable()) {
|
||||
showNonmodalWarning(tr("No executable file to launch."));
|
||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::Idle);
|
||||
AnalyzerManager::stopTool();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->m_runner) {
|
||||
connect(d->m_runner, SIGNAL(stopped()), this, SLOT(notifyRemoteFinished()));
|
||||
connect(d->m_runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)),
|
||||
this, SLOT(logApplicationMessage(QString,Utils::OutputFormat)));
|
||||
d->m_runner->start();
|
||||
d->m_noDebugOutputTimer.start();
|
||||
} else if (d->sp.startMode == StartQmlRemote) {
|
||||
if (d->sp.startMode == StartQmlRemote || d->sp.startMode == StartLocal) {
|
||||
d->m_noDebugOutputTimer.start();
|
||||
} else {
|
||||
emit processRunning(startParameters().analyzerPort);
|
||||
}
|
||||
|
||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
|
||||
emit starting(this);
|
||||
engineStarted();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -242,7 +176,7 @@ void QmlProfilerEngine::notifyRemoteFinished(bool success)
|
||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppKilled);
|
||||
AnalyzerManager::stopTool();
|
||||
|
||||
emit finished();
|
||||
engineFinished();
|
||||
break;
|
||||
}
|
||||
case QmlProfilerStateManager::AppStopped :
|
||||
@@ -262,10 +196,6 @@ void QmlProfilerEngine::cancelProcess()
|
||||
{
|
||||
QTC_ASSERT(d->m_profilerState, return);
|
||||
|
||||
// no process to be canceled? (there might be multiple engines, but only one runs a process)
|
||||
if (!d->m_runner)
|
||||
return;
|
||||
|
||||
switch (d->m_profilerState->currentState()) {
|
||||
case QmlProfilerStateManager::AppReadyToStop : {
|
||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStopped);
|
||||
@@ -282,10 +212,7 @@ void QmlProfilerEngine::cancelProcess()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->m_runner)
|
||||
d->m_runner->stop();
|
||||
emit finished();
|
||||
engineFinished();
|
||||
}
|
||||
|
||||
void QmlProfilerEngine::logApplicationMessage(const QString &msg, Utils::OutputFormat format)
|
||||
@@ -314,7 +241,7 @@ void QmlProfilerEngine::wrongSetupMessageBox(const QString &errorMessage)
|
||||
// KILL
|
||||
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
|
||||
AnalyzerManager::stopTool();
|
||||
emit finished();
|
||||
engineFinished();
|
||||
}
|
||||
|
||||
void QmlProfilerEngine::wrongSetupMessageBoxFinished(int button)
|
||||
@@ -350,8 +277,18 @@ void QmlProfilerEngine::processIsRunning(quint16 port)
|
||||
|
||||
if (port > 0)
|
||||
emit processRunning(port);
|
||||
else if (d->m_runner)
|
||||
emit processRunning(d->m_runner->debugPort());
|
||||
}
|
||||
|
||||
void QmlProfilerEngine::engineStarted()
|
||||
{
|
||||
d->m_running = true;
|
||||
emit starting(this);
|
||||
}
|
||||
|
||||
void QmlProfilerEngine::engineFinished()
|
||||
{
|
||||
d->m_running = false;
|
||||
emit finished();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
@@ -373,17 +310,12 @@ void QmlProfilerEngine::profilerStateChanged()
|
||||
{
|
||||
switch (d->m_profilerState->currentState()) {
|
||||
case QmlProfilerStateManager::AppReadyToStop : {
|
||||
cancelProcess();
|
||||
if (d->m_running)
|
||||
cancelProcess();
|
||||
break;
|
||||
}
|
||||
case QmlProfilerStateManager::Idle : {
|
||||
// When all the profiling is done, delete the profiler runner
|
||||
// (a new one will be created at start)
|
||||
d->m_noDebugOutputTimer.stop();
|
||||
if (d->m_runner) {
|
||||
delete d->m_runner;
|
||||
d->m_runner = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -69,6 +69,8 @@ private slots:
|
||||
void wrongSetupMessageBox(const QString &errorMessage);
|
||||
void wrongSetupMessageBoxFinished(int);
|
||||
void processIsRunning(quint16 port = 0);
|
||||
void engineStarted();
|
||||
void engineFinished();
|
||||
|
||||
private slots:
|
||||
void profilerStateChanged();
|
||||
|
||||
@@ -77,7 +77,26 @@ RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfigurat
|
||||
AnalyzerStartParameters sp = tool->createStartParameters(runConfiguration, mode);
|
||||
sp.toolId = tool->id();
|
||||
|
||||
// only desktop device is supported
|
||||
const ProjectExplorer::IDevice::ConstPtr device =
|
||||
ProjectExplorer::DeviceKitInformation::device(runConfiguration->target()->kit());
|
||||
QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0);
|
||||
|
||||
AnalyzerRunControl *rc = new AnalyzerRunControl(tool, sp, runConfiguration);
|
||||
QmlProfilerEngine *engine = qobject_cast<QmlProfilerEngine *>(rc->engine());
|
||||
if (!engine) {
|
||||
delete rc;
|
||||
return 0;
|
||||
}
|
||||
LocalQmlProfilerRunner *runner = LocalQmlProfilerRunner::createLocalRunner(runConfiguration, sp, errorMessage, engine);
|
||||
if (!runner)
|
||||
return 0;
|
||||
connect(runner, SIGNAL(stopped()), engine, SLOT(notifyRemoteFinished()));
|
||||
connect(runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)),
|
||||
engine, SLOT(logApplicationMessage(QString,Utils::OutputFormat)));
|
||||
connect(engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)), runner,
|
||||
SLOT(start()));
|
||||
connect(rc, SIGNAL(finished()), runner, SLOT(stop()));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user