diff --git a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h b/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h index 233941ed962..6c2f1e7931c 100644 --- a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h @@ -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(); diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp index a7883f506c8..2a47feb46a0 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp @@ -29,13 +29,62 @@ #include "localqmlprofilerrunner.h" #include "qmlprofilerplugin.h" +#include "qmlprofilerengine.h" + +#include +#include +#include +#include +#include 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(runConfiguration); + LocalApplicationRunConfiguration *rc2 = + qobject_cast(runConfiguration); + QTC_ASSERT(rc1 || rc2, return 0); + ProjectExplorer::EnvironmentAspect *environment + = runConfiguration->extraAspect(); + 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 ..."); diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.h b/src/plugins/qmlprofiler/localqmlprofilerrunner.h index 26a9b451618..37591917dae 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.h @@ -35,9 +35,13 @@ #include #include +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 diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp index f1c9f845309..7ce9e7a07f1 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -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(runConfiguration); - LocalApplicationRunConfiguration *rc2 = - qobject_cast(runConfiguration); - // Supports only local run configurations - if (!rc1 && !rc2) - return 0; - - ProjectExplorer::EnvironmentAspect *environment - = runConfiguration->extraAspect(); - 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(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: diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.h b/src/plugins/qmlprofiler/qmlprofilerengine.h index 2a7d24998f4..aea3c8bf8d8 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.h +++ b/src/plugins/qmlprofiler/qmlprofilerengine.h @@ -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(); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp index 453a37f5597..b956039d3c6 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -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(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; }