From 585e651310edccae8acab8511cccd85e6c2fe74f Mon Sep 17 00:00:00 2001 From: Christiaan Janssen <christiaan.janssen@nokia.com> Date: Mon, 13 Feb 2012 15:26:57 +0100 Subject: [PATCH] QmlProfiler: manage server-side start tracing message also QmlProfiler: refactor eventlist state If unexpected data is received, assuming server stopped profiling. Also, introducing a eventlist state instead of relying on signals sent around. This is part of a coming bigger patch where the profiler client is refactored. Change-Id: Ibed9007903956daf03cc0fcb90f77b5ad2d3cf90 Reviewed-by: Kai Koehne <kai.koehne@nokia.com> --- .../qmljsdebugclient/qmlprofilereventlist.cpp | 68 ++++++++++++++++--- .../qmljsdebugclient/qmlprofilereventlist.h | 15 ++-- .../qmlprofilertraceclient.cpp | 18 ++++- .../qmljsdebugclient/qmlprofilertraceclient.h | 1 + src/plugins/qmlprofiler/qml/Label.qml | 18 +++-- src/plugins/qmlprofiler/qml/MainView.qml | 28 +++++--- src/plugins/qmlprofiler/qml/Overview.qml | 5 +- src/plugins/qmlprofiler/qmlprofilerengine.cpp | 9 ++- src/plugins/qmlprofiler/qmlprofilerengine.h | 1 + .../qmlprofiler/qmlprofilereventview.cpp | 27 ++++++-- .../qmlprofiler/qmlprofilereventview.h | 5 ++ src/plugins/qmlprofiler/qmlprofilertool.cpp | 38 +++++++---- src/plugins/qmlprofiler/qmlprofilertool.h | 2 + src/plugins/qmlprofiler/tracewindow.cpp | 64 ++++++++++++++--- src/plugins/qmlprofiler/tracewindow.h | 11 ++- 15 files changed, 246 insertions(+), 64 deletions(-) diff --git a/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp b/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp index 3d5327bbc19..b49976cb076 100644 --- a/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp +++ b/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp @@ -267,6 +267,8 @@ public: QmlProfilerEventList *q; + QmlProfilerEventList::State m_state; + // convenience functions void clearQmlRootEvent(); void clearV8RootEvent(); @@ -309,6 +311,8 @@ QmlProfilerEventList::QmlProfilerEventList(QObject *parent) : { setObjectName("QmlProfilerEventStatistics"); + d->m_state = Empty; + d->m_traceEndTime = 0; d->m_traceStartTime = -1; d->m_qmlMeasuredTime = 0; @@ -357,7 +361,7 @@ void QmlProfilerEventList::clear() d->m_minimumAnimationCount = 0; emit countChanged(); - emit dataClear(); + setState(Empty); } QList <QmlEventData *> QmlProfilerEventList::getEventDescriptions() const @@ -395,7 +399,7 @@ void QmlProfilerEventList::addRangedEvent(int type, qint64 startTime, qint64 len QString displayName, eventHashStr, details; QmlJsDebugClient::QmlEventLocation eventLocation = location; - emit processingData(); + setState(AcquiringData); // generate details string if (data.isEmpty()) @@ -466,11 +470,14 @@ void QmlProfilerEventList::addV8Event(int depth, const QString &function, const QString displayName = filename.mid(filename.lastIndexOf(QLatin1Char('/')) + 1) + QLatin1Char(':') + QString::number(lineNumber); QV8EventData *eventData = 0; + setState(AcquiringData); + // time is given in milliseconds, but internally we store it in microseconds totalTime *= 1e6; selfTime *= 1e6; // cumulate information + // TODO: use hashes foreach (QV8EventData *v8event, d->m_v8EventList) { if (v8event->displayName == displayName && v8event->functionName == function) { eventData = v8event; @@ -529,7 +536,7 @@ void QmlProfilerEventList::addFrameEvent(qint64 time, int framerate, int animati { QString displayName, eventHashStr, details; - emit processingData(); + setState(AcquiringData); details = tr("Animation Timer Update"); displayName = tr("<Animation Update>"); @@ -636,7 +643,7 @@ void QmlProfilerEventList::setTraceStartTime( qint64 time ) void QmlProfilerEventList::complete() { - emit postProcessing(); + setState(ProcessingData); d->collectV8Statistics(); postProcess(); } @@ -1030,9 +1037,10 @@ void QmlProfilerEventList::postProcess() reloadDetails(); compileStatistics(traceStartTime(), traceEndTime()); prepareForDisplay(); + setState(Done); + } else { + setState(Empty); } - // data is ready even when there's no data - emit dataReady(); } void QmlProfilerEventList::linkEndsToStarts() @@ -1398,7 +1406,7 @@ void QmlProfilerEventList::load() return; } - emit processingData(); + setState(AcquiringData); // erase current clear(); @@ -1645,8 +1653,6 @@ void QmlProfilerEventList::load() if (!validVersion) { clear(); - emit countChanged(); - emit dataReady(); emit error(tr("Invalid version of QML Trace file.")); return; } @@ -1697,7 +1703,7 @@ void QmlProfilerEventList::load() descriptionBuffer.clear(); - emit postProcessing(); + setState(ProcessingData); d->collectV8Statistics(); postProcess(); } @@ -1830,4 +1836,46 @@ int QmlProfilerEventList::eventPosInType(int index) const return d->m_typeCounts[eventType]->eventIds.indexOf(d->m_startTimeSortedList[index].description->eventId); } +///////////////////////////////////////// +QmlProfilerEventList::State QmlProfilerEventList::currentState() const +{ + return d->m_state; +} + +int QmlProfilerEventList::getCurrentStateFromQml() const +{ + return (int)d->m_state; +} + +void QmlProfilerEventList::setState(QmlProfilerEventList::State state) +{ + // It's not an error, we are continuously calling "AcquiringData" for example + if (d->m_state == state) + return; + + switch (state) { + case Empty: + // if it's not empty, complain but go on + QTC_ASSERT(count() == 0, /**/); + break; + case AcquiringData: + // we're not supposed to receive new data while processing older data + QTC_ASSERT(d->m_state != ProcessingData, return); + break; + case ProcessingData: + QTC_ASSERT(d->m_state == AcquiringData, return); + break; + case Done: + QTC_ASSERT(d->m_state == ProcessingData, return); + break; + default: + qDebug() << "Trying to set unknown state in events list at" << __FILE__ << __LINE__; + break; + } + + d->m_state = state; + emit stateChanged(); + return; +} + } // namespace QmlJsDebugClient diff --git a/src/libs/qmljsdebugclient/qmlprofilereventlist.h b/src/libs/qmljsdebugclient/qmlprofilereventlist.h index ab44900870c..32f5203c2a0 100644 --- a/src/libs/qmljsdebugclient/qmlprofilereventlist.h +++ b/src/libs/qmljsdebugclient/qmlprofilereventlist.h @@ -115,6 +115,12 @@ class QMLJSDEBUGCLIENT_EXPORT QmlProfilerEventList : public QObject { Q_OBJECT public: + enum State { + Empty, + AcquiringData, + ProcessingData, + Done + }; explicit QmlProfilerEventList(QObject *parent = 0); ~QmlProfilerEventList(); @@ -167,13 +173,13 @@ public: void showErrorDialog(const QString &st ) const; void compileStatistics(qint64 startTime, qint64 endTime); + State currentState() const; + Q_INVOKABLE int getCurrentStateFromQml() const; + signals: - void dataReady(); + void stateChanged(); void countChanged(); void error(const QString &error); - void dataClear(); - void processingData(); - void postProcessing(); void requestDetailsForLocation(int eventType, const QmlJsDebugClient::QmlEventLocation &location); void detailsChanged(int eventId, const QString &newString); @@ -212,6 +218,7 @@ private: void reloadDetails(); void findBindingLoops(qint64 startTime, qint64 endTime); bool checkBindingLoop(QmlEventData *from, QmlEventData *current, QList<QmlEventData *>visited); + void setState(State state); private: class QmlProfilerEventListPrivate; diff --git a/src/libs/qmljsdebugclient/qmlprofilertraceclient.cpp b/src/libs/qmljsdebugclient/qmlprofilertraceclient.cpp index 89586779359..cc130bba736 100644 --- a/src/libs/qmljsdebugclient/qmlprofilertraceclient.cpp +++ b/src/libs/qmljsdebugclient/qmlprofilertraceclient.cpp @@ -89,6 +89,11 @@ QmlProfilerTraceClient::~QmlProfilerTraceClient() void QmlProfilerTraceClient::clearData() { ::memset(d->rangeCount, 0, MaximumQmlEventType * sizeof(int)); + for (int eventType = 0; eventType < MaximumQmlEventType; eventType++) { + d->rangeDatas[eventType].clear(); + d->rangeLocations[eventType].clear(); + d->rangeStartTimes[eventType].clear(); + } emit cleared(); } @@ -121,6 +126,14 @@ void QmlProfilerTraceClient::setRecording(bool v) emit recordingChanged(v); } +void QmlProfilerTraceClient::setRecordingFromServer(bool v) +{ + if (v == d->recording) + return; + d->recording = v; + emit recordingChanged(v); +} + void QmlProfilerTraceClient::statusChanged(Status /*status*/) { emit enabledChanged(); @@ -136,8 +149,6 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) stream >> time >> messageType; -// qDebug() << __FUNCTION__ << messageType; - if (messageType >= MaximumMessage) return; @@ -158,6 +169,9 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) emit this->frame(time, frameRate, animationCount); d->maximumTime = qMax(time, d->maximumTime); } else if (event == StartTrace) { + // special: StartTrace is now asynchronous + if (!d->recording) + setRecordingFromServer(true); emit this->traceStarted(time); d->maximumTime = time; } else if (event < MaximumEventType) { diff --git a/src/libs/qmljsdebugclient/qmlprofilertraceclient.h b/src/libs/qmljsdebugclient/qmlprofilertraceclient.h index 37309ce715e..4d37c067e36 100644 --- a/src/libs/qmljsdebugclient/qmlprofilertraceclient.h +++ b/src/libs/qmljsdebugclient/qmlprofilertraceclient.h @@ -83,6 +83,7 @@ public: public slots: void setRecording(bool); + void setRecordingFromServer(bool); void clearData(); void sendRecordingStatus(); diff --git a/src/plugins/qmlprofiler/qml/Label.qml b/src/plugins/qmlprofiler/qml/Label.qml index a3d8a1d792f..0d89c057abd 100644 --- a/src/plugins/qmlprofiler/qml/Label.qml +++ b/src/plugins/qmlprofiler/qml/Label.qml @@ -81,12 +81,18 @@ Item { Connections { target: qmlEventList onReloadDetailLabels: getDescriptions(); - onDataReady: getDescriptions(); - onDataClear: { - descriptions = []; - eventIds = []; - extdescriptions = []; - updateHeight(); + onStateChanged: { + // Empty + if (qmlEventList.getCurrentStateFromQml() == 0) { + descriptions = []; + eventIds = []; + extdescriptions = []; + updateHeight(); + } else + // Done + if (qmlEventList.getCurrentStateFromQml() == 3) { + getDescriptions(); + } } } diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml index 557d8279e6b..6aa07199669 100644 --- a/src/plugins/qmlprofiler/qml/MainView.qml +++ b/src/plugins/qmlprofiler/qml/MainView.qml @@ -111,23 +111,29 @@ Rectangle { root.progress = 0; } } - - onProcessingData: { - root.dataAvailable = false; - } - - onPostProcessing: { - root.progress = 0.9; // jump to 90% - } - - onDataReady: { - if (eventCount > 0) { + onStateChanged: { + switch (qmlEventList.getCurrentStateFromQml()) { + case 0: { + root.clearAll(); + break; + } + case 1: { + root.dataAvailable = false; + break; + } + case 2: { + root.progress = 0.9; // jump to 90% + break; + } + case 3: { view.clearData(); progress = 1.0; dataAvailable = true; view.visible = true; view.requestPaint(); zoomControl.setRange(qmlEventList.traceStartTime(), qmlEventList.traceStartTime() + qmlEventList.traceDuration()/10); + break; + } } } } diff --git a/src/plugins/qmlprofiler/qml/Overview.qml b/src/plugins/qmlprofiler/qml/Overview.qml index 5d0a7496feb..55265021690 100644 --- a/src/plugins/qmlprofiler/qml/Overview.qml +++ b/src/plugins/qmlprofiler/qml/Overview.qml @@ -77,8 +77,9 @@ Canvas2D { Connections { target: qmlEventList - onDataReady: { - if (qmlEventList.count() > 0) { + onStateChanged: { + // State is "done" + if (qmlEventList.getCurrentStateFromQml() == 3) { dataAvailable = true; requestRedraw(); } diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp index f485dec462f..6a835ac52aa 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -217,15 +217,15 @@ bool QmlProfilerEngine::start() void QmlProfilerEngine::stop() { - // keep the flag for the next restart - d->m_fetchDataFromStart = d->m_fetchingData; if (d->m_fetchingData) { if (d->m_running) d->m_delayedDelete = true; // will result in dataReceived() call emit stopRecording(); + d->m_fetchDataFromStart = true; } else { finishProcess(); + d->m_fetchDataFromStart = false; } } @@ -242,8 +242,9 @@ void QmlProfilerEngine::stopped() d->m_running = false; d->m_runningTimer.stop(); - AnalyzerManager::stopTool(); // FIXME: Needed? + AnalyzerManager::stopTool(); emit finished(); + emit recordingChanged(d->m_fetchDataFromStart); } void QmlProfilerEngine::setFetchingData(bool b) @@ -269,6 +270,7 @@ void QmlProfilerEngine::finishProcess() if (d->m_runner) d->m_runner->stop(); emit finished(); + emit recordingChanged(d->m_fetchDataFromStart); } } @@ -299,6 +301,7 @@ void QmlProfilerEngine::wrongSetupMessageBox(const QString &errorMessage) d->m_runningTimer.stop(); AnalyzerManager::stopTool(); emit finished(); + emit recordingChanged(d->m_fetchDataFromStart); } void QmlProfilerEngine::wrongSetupMessageBoxFinished(int button) diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.h b/src/plugins/qmlprofiler/qmlprofilerengine.h index 68c6e1279b3..017ffd050ba 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.h +++ b/src/plugins/qmlprofiler/qmlprofilerengine.h @@ -54,6 +54,7 @@ signals: void processRunning(int port); void stopRecording(); void timeUpdate(); + void recordingChanged(bool recording); public slots: bool start(); diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.cpp b/src/plugins/qmlprofiler/qmlprofilereventview.cpp index 869f0572def..b59fdc4c7a2 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventview.cpp @@ -123,9 +123,9 @@ QmlProfilerEventsWidget::QmlProfilerEventsWidget(QmlJsDebugClient::QmlProfilerEv groupLayout->addWidget(splitterVertical); setLayout(groupLayout); + m_eventStatistics = model; if (model) { - connect(model,SIGNAL(dataReady()),m_eventChildren,SLOT(clear())); - connect(model,SIGNAL(dataReady()),m_eventParents,SLOT(clear())); + connect(model, SIGNAL(stateChanged()), this, SLOT(eventListStateChanged())); } m_globalStatsEnabled = true; @@ -135,6 +135,16 @@ QmlProfilerEventsWidget::~QmlProfilerEventsWidget() { } +void QmlProfilerEventsWidget::eventListStateChanged() +{ + if (m_eventStatistics) { + QmlProfilerEventList::State newState = m_eventStatistics->currentState(); + if (newState == QmlProfilerEventList::Empty) { + clear(); + } + } +} + void QmlProfilerEventsWidget::switchToV8View() { setObjectName("QmlProfilerV8ProfileView"); @@ -278,16 +288,25 @@ QmlProfilerEventsMainView::~QmlProfilerEventsMainView() void QmlProfilerEventsMainView::setEventStatisticsModel( QmlProfilerEventList *model ) { if (d->m_eventStatistics) { - disconnect(d->m_eventStatistics,SIGNAL(dataReady()),this,SLOT(buildModel())); + disconnect(d->m_eventStatistics,SIGNAL(stateChanged()),this,SLOT(eventListStateChanged())); disconnect(d->m_eventStatistics,SIGNAL(detailsChanged(int,QString)),this,SLOT(changeDetailsForEvent(int,QString))); } d->m_eventStatistics = model; if (model) { - connect(d->m_eventStatistics,SIGNAL(dataReady()),this,SLOT(buildModel())); + connect(d->m_eventStatistics,SIGNAL(stateChanged()),this,SLOT(eventListStateChanged())); connect(d->m_eventStatistics,SIGNAL(detailsChanged(int,QString)),this,SLOT(changeDetailsForEvent(int,QString))); } } +void QmlProfilerEventsMainView::eventListStateChanged() +{ + if (d->m_eventStatistics) { + QmlProfilerEventList::State newState = d->m_eventStatistics->currentState(); + if (newState == QmlProfilerEventList::Done) + buildModel(); + } +} + void QmlProfilerEventsMainView::setFieldViewable(Fields field, bool show) { if (field < MaxFields) { diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.h b/src/plugins/qmlprofiler/qmlprofilereventview.h index 797dc806091..1c7c87d7f24 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.h +++ b/src/plugins/qmlprofiler/qmlprofilereventview.h @@ -84,6 +84,9 @@ public slots: void updateSelectedEvent(int eventId) const; void selectBySourceLocation(const QString &filename, int line, int column); +private slots: + void eventListStateChanged(); + protected: void contextMenuEvent(QContextMenuEvent *ev); @@ -91,6 +94,7 @@ private: QmlProfilerEventsMainView *m_eventTree; QmlProfilerEventsParentsAndChildrenView *m_eventChildren; QmlProfilerEventsParentsAndChildrenView *m_eventParents; + QmlJsDebugClient::QmlProfilerEventList *m_eventStatistics; bool m_globalStatsEnabled; }; @@ -153,6 +157,7 @@ signals: void showEventInTimeline(int eventId); public slots: + void eventListStateChanged(); void clear(); void jumpToItem(const QModelIndex &index); void selectEvent(int eventId); diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 0e10042c29d..cabfd6bc418 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -368,6 +368,7 @@ IAnalyzerEngine *QmlProfilerTool::createEngine(const AnalyzerStartParameters &sp connect(engine, SIGNAL(finished()), this, SLOT(disconnectClient())); connect(engine, SIGNAL(finished()), this, SLOT(updateTimers())); connect(engine, SIGNAL(stopRecording()), this, SLOT(stopRecording())); + connect(engine, SIGNAL(recordingChanged(bool)), this, SLOT(setRecording(bool))); connect(engine, SIGNAL(timeUpdate()), this, SLOT(updateTimers())); connect(d->m_traceWindow, SIGNAL(viewUpdated()), engine, SLOT(dataReceived())); connect(this, SIGNAL(connectionFailed()), engine, SLOT(finishProcess())); @@ -456,9 +457,9 @@ QWidget *QmlProfilerTool::createWidgets() connect(d->m_traceWindow, SIGNAL(gotoSourceLocation(QString,int,int)),this, SLOT(gotoSourceLocation(QString,int,int))); connect(d->m_traceWindow, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); connect(d->m_traceWindow->getEventList(), SIGNAL(error(QString)), this, SLOT(showErrorDialog(QString))); - connect(d->m_traceWindow->getEventList(), SIGNAL(dataReady()), this, SLOT(showSaveOption())); - connect(d->m_traceWindow->getEventList(), SIGNAL(dataReady()), this, SLOT(updateTimers())); + connect(d->m_traceWindow->getEventList(), SIGNAL(stateChanged()), this, SLOT(eventListStateChanged())); connect(d->m_traceWindow, SIGNAL(profilerStateChanged(bool,bool)), this, SLOT(profilerStateChanged(bool,bool))); + connect(d->m_traceWindow, SIGNAL(recordingChanged(bool)), this, SLOT(setRecording(bool))); d->m_eventsView = new QmlProfilerEventsWidget(d->m_traceWindow->getEventList(), mw); connect(d->m_eventsView, SIGNAL(gotoSourceLocation(QString,int,int)), this, SLOT(gotoSourceLocation(QString,int,int))); @@ -500,11 +501,11 @@ QWidget *QmlProfilerTool::createWidgets() layout->setSpacing(0); d->m_recordButton = new QToolButton(toolbarWidget); - // icon and tooltip set in setRecording(), called later d->m_recordButton->setCheckable(true); - connect(d->m_recordButton,SIGNAL(toggled(bool)), this, SLOT(setRecording(bool))); + connect(d->m_recordButton,SIGNAL(clicked(bool)), this, SLOT(recordingButtonChanged(bool))); d->m_recordButton->setChecked(true); + setRecording(d->m_recordingEnabled); layout->addWidget(d->m_recordButton); d->m_clearButton = new QToolButton(toolbarWidget); @@ -583,20 +584,25 @@ void QmlProfilerTool::stopRecording() emit cancelRun(); } -void QmlProfilerTool::setRecording(bool recording) +void QmlProfilerTool::recordingButtonChanged(bool recording) { - d->m_recordingEnabled = recording; - - // update record button - d->m_recordButton->setToolTip( d->m_recordingEnabled ? tr("Disable profiling") : tr("Enable profiling")); - d->m_recordButton->setIcon(QIcon(d->m_recordingEnabled ? QLatin1String(":/qmlprofiler/recordOn.png") : - QLatin1String(":/qmlprofiler/recordOff.png"))); - if (recording) startRecording(); else stopRecording(); + setRecording(recording); +} + +void QmlProfilerTool::setRecording(bool recording) +{ + // update record button + d->m_recordingEnabled = recording; + d->m_recordButton->setToolTip( recording ? tr("Disable profiling") : tr("Enable profiling")); + d->m_recordButton->setIcon(QIcon(recording ? QLatin1String(":/qmlprofiler/recordOn.png") : + QLatin1String(":/qmlprofiler/recordOff.png"))); + + d->m_recordButton->setChecked(recording); updateTimers(); } @@ -886,3 +892,11 @@ void QmlProfilerTool::retryMessageBoxFinished(int result) } } } + +void QmlProfilerTool::eventListStateChanged() +{ + if (d->m_traceWindow->getEventList()->currentState() == QmlProfilerEventList::Done) { + showSaveOption(); + updateTimers(); + } +} diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index 728496c6346..3b53e5d7274 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -78,6 +78,7 @@ public slots: void startRecording(); void stopRecording(); + void recordingButtonChanged(bool recording); void setRecording(bool recording); void setAppIsRunning(); @@ -106,6 +107,7 @@ private slots: void showLoadDialog(); void showErrorDialog(const QString &error); void retryMessageBoxFinished(int result); + void eventListStateChanged(); private: void connectToClient(); diff --git a/src/plugins/qmlprofiler/tracewindow.cpp b/src/plugins/qmlprofiler/tracewindow.cpp index 22e481e60fd..0e4953180c6 100644 --- a/src/plugins/qmlprofiler/tracewindow.cpp +++ b/src/plugins/qmlprofiler/tracewindow.cpp @@ -138,7 +138,7 @@ TraceWindow::TraceWindow(QWidget *parent) connect(this, SIGNAL(traceFinished(qint64)), m_eventList, SLOT(setTraceEndTime(qint64))); connect(this, SIGNAL(traceStarted(qint64)), m_eventList, SLOT(setTraceStartTime(qint64))); connect(this, SIGNAL(frameEvent(qint64,int,int)), m_eventList, SLOT(addFrameEvent(qint64,int,int))); - connect(this,SIGNAL(viewUpdated()), m_eventList, SLOT(complete())); + connect(m_eventList, SIGNAL(stateChanged()), this, SLOT(eventListStateChanged())); m_mainView->rootContext()->setContextProperty("qmlEventList", m_eventList); m_overview->rootContext()->setContextProperty("qmlEventList", m_eventList); @@ -319,10 +319,11 @@ void TraceWindow::connectClientSignals() connect(m_plugin.data(), SIGNAL(range(int,qint64,qint64,QStringList,QmlJsDebugClient::QmlEventLocation)), this, SIGNAL(range(int,qint64,qint64,QStringList,QmlJsDebugClient::QmlEventLocation))); connect(m_plugin.data(), SIGNAL(traceFinished(qint64)), this, SIGNAL(traceFinished(qint64))); - connect(m_plugin.data(), SIGNAL(traceStarted(qint64)), this, SIGNAL(traceStarted(qint64))); + connect(m_plugin.data(), SIGNAL(traceStarted(qint64)), this, SLOT(manageTraceStart(qint64))); connect(m_plugin.data(), SIGNAL(frame(qint64,int,int)), this, SIGNAL(frameEvent(qint64,int,int))); connect(m_plugin.data(), SIGNAL(enabledChanged()), this, SLOT(updateProfilerState())); connect(m_plugin.data(), SIGNAL(enabledChanged()), m_plugin.data(), SLOT(sendRecordingStatus())); + connect(m_plugin.data(), SIGNAL(recordingChanged(bool)), this, SIGNAL(recordingChanged(bool))); } if (m_v8plugin) { connect(m_v8plugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); @@ -339,9 +340,10 @@ void TraceWindow::disconnectClientSignals() disconnect(m_plugin.data(), SIGNAL(range(int,qint64,qint64,QStringList,QmlJsDebugClient::QmlEventLocation)), this, SIGNAL(range(int,qint64,qint64,QStringList,QmlJsDebugClient::QmlEventLocation))); disconnect(m_plugin.data(), SIGNAL(traceFinished(qint64)), this, SIGNAL(traceFinished(qint64))); - disconnect(m_plugin.data(), SIGNAL(traceStarted(qint64)), this, SIGNAL(traceStarted(qint64))); + disconnect(m_plugin.data(), SIGNAL(traceStarted(qint64)), this, SLOT(manageTraceStart(qint64))); disconnect(m_plugin.data(), SIGNAL(enabledChanged()), this, SLOT(updateProfilerState())); disconnect(m_plugin.data(), SIGNAL(enabledChanged()), m_plugin.data(), SLOT(sendRecordingStatus())); + disconnect(m_plugin.data(), SIGNAL(recordingChanged(bool)), this, SIGNAL(recordingChanged(bool))); } if (m_v8plugin) { disconnect(m_v8plugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); @@ -378,6 +380,15 @@ void TraceWindow::updateTimer() m_profiledTime = m_mainView->rootObject()->property("elapsedTime").toDouble(); } +void TraceWindow::correctTimer() +{ + // once the data is post-processed, use the eventlist time instead of the qml timer + m_profiledTime = (m_eventList->traceEndTime() - m_eventList->traceStartTime()) / 1.0e9; + if (m_profiledTime < 0) + m_profiledTime = 0; + emit viewUpdated(); +} + double TraceWindow::profiledTime() const { return m_profiledTime; @@ -463,11 +474,11 @@ bool TraceWindow::isRecording() const void TraceWindow::qmlComplete() { m_qmlDataReady = true; - if (!m_v8plugin || m_v8plugin.data()->status() != QDeclarativeDebugClient::Enabled || m_v8DataReady) { - emit viewUpdated(); - // once complete is sent, reset the flag + m_eventList->complete(); + // once complete is sent, reset the flags m_qmlDataReady = false; + m_v8DataReady = false; } } @@ -475,9 +486,10 @@ void TraceWindow::v8Complete() { m_v8DataReady = true; if (!m_plugin || m_plugin.data()->status() != QDeclarativeDebugClient::Enabled || m_qmlDataReady) { - emit viewUpdated(); - // once complete is sent, reset the flag + m_eventList->complete(); + // once complete is sent, reset the flags m_v8DataReady = false; + m_qmlDataReady = false; } } @@ -591,5 +603,41 @@ void TraceWindow::updateVerticalScroll(int newPosition) m_mainView->verticalScrollBar()->setValue(newPosition); } +void TraceWindow::eventListStateChanged() +{ + switch (m_eventList->currentState()) { + case QmlProfilerEventList::Empty : + clearDisplay(); + break; + case QmlProfilerEventList::AcquiringData : + firstDataReceived(); + break; + case QmlProfilerEventList::ProcessingData : + // nothing to be done + break; + case QmlProfilerEventList::Done : + correctTimer(); + break; + default: + break; + } +} + +void TraceWindow::manageTraceStart(qint64 traceStart) +{ + // new trace started + clearDisplay(); + + emit traceStarted(traceStart); +} + +void TraceWindow::firstDataReceived() +{ + if (m_plugin && m_plugin.data()->isRecording()) { + // serverside recording disabled + m_plugin.data()->setRecordingFromServer(false); + } +} + } // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/tracewindow.h b/src/plugins/qmlprofiler/tracewindow.h index b357d1e6038..80134c7c66d 100644 --- a/src/plugins/qmlprofiler/tracewindow.h +++ b/src/plugins/qmlprofiler/tracewindow.h @@ -110,9 +110,12 @@ public: double profiledTime() const; public slots: + void clearDisplay(); + void selectNextEvent(int eventId); + +private slots: void updateCursorPosition(); void updateTimer(); - void clearDisplay(); void updateToolbar(); void toggleRangeMode(bool); void toggleLockMode(bool); @@ -124,10 +127,13 @@ public slots: void qmlComplete(); void v8Complete(); - void selectNextEvent(int eventId); void updateProfilerState(); void updateToolTip(const QString &text); void updateVerticalScroll(int newPosition); + void eventListStateChanged(); + void manageTraceStart(qint64 traceStart); + void firstDataReceived(); + void correctTimer(); signals: void viewUpdated(); @@ -139,6 +145,7 @@ signals: void traceFinished(qint64); void traceStarted(qint64); void frameEvent(qint64, int, int); + void recordingChanged(bool); void internalClearDisplay(); void jumpToPrev(); -- GitLab