Commit 461e677b authored by Ulf Hermann's avatar Ulf Hermann

QmlProfiler: Consistently apply the d-pointer pattern to all models

Change-Id: I338291ee94f0301039c2b2e04b6c37fff66a2995
Reviewed-by: default avatarKai Koehne <kai.koehne@digia.com>
parent fdb5624f
......@@ -67,7 +67,8 @@ HEADERS += \
abstracttimelinemodel_p.h \
singlecategorytimelinemodel.h \
singlecategorytimelinemodel_p.h \
qmlprofilerdatamodel.h
qmlprofilerdatamodel.h \
qmlprofilerbasemodel_p.h
RESOURCES += \
qml/qmlprofiler.qrc
......
......@@ -29,32 +29,52 @@
#include "qmlprofilerbasemodel.h"
#include "qmlprofilermodelmanager.h"
#include "qmlprofilerbasemodel_p.h"
namespace QmlProfiler {
QmlProfilerBaseModel::QmlProfilerBaseModel(Utils::FileInProjectFinder *fileFinder,
QmlProfilerModelManager *manager) :
m_modelManager(manager), m_processingDone(false), m_detailsRewriter(this, fileFinder)
QmlProfilerModelManager *manager,
QmlProfilerBaseModelPrivate *dd) : d_ptr(dd)
{
Q_ASSERT(m_modelManager);
m_modelId = m_modelManager->registerModelProxy();
connect(&m_detailsRewriter, SIGNAL(rewriteDetailsString(int,QString)),
Q_D(QmlProfilerBaseModel);
d->modelManager = manager;
d->processingDone = false;
d->detailsRewriter = new QmlProfilerDetailsRewriter(this, fileFinder);
Q_ASSERT(d->modelManager);
d->modelId = d->modelManager->registerModelProxy();
connect(d->detailsRewriter, SIGNAL(rewriteDetailsString(int,QString)),
this, SLOT(detailsChanged(int,QString)));
connect(&m_detailsRewriter, SIGNAL(eventDetailsChanged()),
connect(d->detailsRewriter, SIGNAL(eventDetailsChanged()),
this, SLOT(detailsDone()));
}
QmlProfilerBaseModel::~QmlProfilerBaseModel()
{
Q_D(QmlProfilerBaseModel);
delete d->detailsRewriter;
delete d;
}
void QmlProfilerBaseModel::clear()
{
m_detailsRewriter.clearRequests();
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
m_processingDone = false;
Q_D(QmlProfilerBaseModel);
d->detailsRewriter->clearRequests();
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
d->processingDone = false;
emit changed();
}
bool QmlProfilerBaseModel::processingDone() const
{
Q_D(const QmlProfilerBaseModel);
return d->processingDone;
}
void QmlProfilerBaseModel::complete()
{
m_detailsRewriter.reloadDocuments();
Q_D(QmlProfilerBaseModel);
d->detailsRewriter->reloadDocuments();
}
QString QmlProfilerBaseModel::formatTime(qint64 timestamp)
......@@ -69,10 +89,11 @@ QString QmlProfilerBaseModel::formatTime(qint64 timestamp)
void QmlProfilerBaseModel::detailsDone()
{
Q_D(QmlProfilerBaseModel);
emit changed();
m_processingDone = true;
m_modelManager->modelProxyCountUpdated(m_modelId, isEmpty() ? 0 : 1, 1);
m_modelManager->modelProcessingDone();
d->processingDone = true;
d->modelManager->modelProxyCountUpdated(d->modelId, isEmpty() ? 0 : 1, 1);
d->modelManager->modelProcessingDone();
}
}
......@@ -41,28 +41,31 @@ class QmlProfilerModelManager;
class QMLPROFILER_EXPORT QmlProfilerBaseModel : public QObject {
Q_OBJECT
public:
QmlProfilerBaseModel(Utils::FileInProjectFinder *fileFinder, QmlProfilerModelManager *manager);
virtual ~QmlProfilerBaseModel() {}
virtual ~QmlProfilerBaseModel();
virtual void complete();
virtual void clear();
virtual bool isEmpty() const = 0;
bool processingDone() const { return m_processingDone; }
bool processingDone() const;
static QString formatTime(qint64 timestamp);
protected:
QmlProfilerModelManager *m_modelManager;
int m_modelId;
bool m_processingDone;
Internal::QmlProfilerDetailsRewriter m_detailsRewriter;
protected slots:
virtual void detailsChanged(int requestId, const QString &newString) = 0;
virtual void detailsDone();
signals:
void changed();
protected:
class QmlProfilerBaseModelPrivate;
QmlProfilerBaseModelPrivate *d_ptr;
QmlProfilerBaseModel(Utils::FileInProjectFinder *fileFinder, QmlProfilerModelManager *manager,
QmlProfilerBaseModelPrivate *dd);
private:
Q_DECLARE_PRIVATE(QmlProfilerBaseModel)
};
}
......
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QMLPROFILERBASEMODEL_P_H
#define QMLPROFILERBASEMODEL_P_H
#include "qmlprofilerbasemodel.h"
namespace QmlProfiler {
class QmlProfilerBaseModel::QmlProfilerBaseModelPrivate {
public:
QmlProfilerBaseModelPrivate(QmlProfilerBaseModel *qq) : q_ptr(qq) {}
virtual ~QmlProfilerBaseModelPrivate() {}
QmlProfilerModelManager *modelManager;
int modelId;
bool processingDone;
Internal::QmlProfilerDetailsRewriter *detailsRewriter;
protected:
QmlProfilerBaseModel *q_ptr;
private:
Q_DECLARE_PUBLIC(QmlProfilerBaseModel)
};
}
#endif // QMLPROFILERBASEMODEL_P_H
......@@ -28,6 +28,7 @@
****************************************************************************/
#include "qmlprofilerdatamodel.h"
#include "qmlprofilerbasemodel_p.h"
#include "qmlprofilermodelmanager.h"
#include <qmldebug/qmlprofilereventtypes.h>
#include <utils/qtcassert.h>
......@@ -36,6 +37,16 @@
namespace QmlProfiler {
class QmlProfilerDataModel::QmlProfilerDataModelPrivate :
public QmlProfilerBaseModel::QmlProfilerBaseModelPrivate
{
public:
QmlProfilerDataModelPrivate(QmlProfilerDataModel *qq) : QmlProfilerBaseModelPrivate(qq) {}
QVector<QmlEventData> eventList;
private:
Q_DECLARE_PUBLIC(QmlProfilerDataModel)
};
QmlDebug::QmlEventLocation getLocation(const QmlProfilerDataModel::QmlEventData &event);
QString getDisplayName(const QmlProfilerDataModel::QmlEventData &event);
QString getInitialDetails(const QmlProfilerDataModel::QmlEventData &event);
......@@ -102,45 +113,51 @@ bool compareStartTimes(const QmlProfilerDataModel::QmlEventData &t1, const QmlPr
QmlProfilerDataModel::QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinder,
QmlProfilerModelManager *parent)
: QmlProfilerBaseModel(fileFinder, parent)
: QmlProfilerBaseModel(fileFinder, parent, new QmlProfilerDataModelPrivate(this))
{
Q_D(QmlProfilerDataModel);
// The document loading is very expensive.
m_modelManager->setProxyCountWeight(m_modelId, 4);
d->modelManager->setProxyCountWeight(d->modelId, 4);
}
const QVector<QmlProfilerDataModel::QmlEventData> &QmlProfilerDataModel::getEvents() const
{
return m_eventList;
Q_D(const QmlProfilerDataModel);
return d->eventList;
}
int QmlProfilerDataModel::count() const
{
return m_eventList.count();
Q_D(const QmlProfilerDataModel);
return d->eventList.count();
}
void QmlProfilerDataModel::clear()
{
m_eventList.clear();
Q_D(QmlProfilerDataModel);
d->eventList.clear();
// This call emits changed(). Don't emit it again here.
QmlProfilerBaseModel::clear();
}
bool QmlProfilerDataModel::isEmpty() const
{
return m_eventList.isEmpty();
Q_D(const QmlProfilerDataModel);
return d->eventList.isEmpty();
}
void QmlProfilerDataModel::complete()
{
Q_D(QmlProfilerDataModel);
// post-processing
// sort events by start time
qSort(m_eventList.begin(), m_eventList.end(), compareStartTimes);
qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes);
// rewrite strings
int n = m_eventList.count();
int n = d->eventList.count();
for (int i = 0; i < n; i++) {
QmlEventData *event = &m_eventList[i];
QmlEventData *event = &d->eventList[i];
event->location = getLocation(*event);
event->displayName = getDisplayName(*event);
event->data = QStringList() << getInitialDetails(*event);
......@@ -160,8 +177,8 @@ void QmlProfilerDataModel::complete()
if (event->location.column == -1)
continue;
m_detailsRewriter.requestDetailsForLocation(i, event->location);
m_modelManager->modelProxyCountUpdated(m_modelId, i + n, n * 2);
d->detailsRewriter->requestDetailsForLocation(i, event->location);
d->modelManager->modelProxyCountUpdated(d->modelId, i + n, n * 2);
}
// Allow changed() event only after documents have been reloaded to avoid
......@@ -175,6 +192,7 @@ void QmlProfilerDataModel::addQmlEvent(int type, int bindingType, qint64 startTi
qint64 ndata1, qint64 ndata2, qint64 ndata3,
qint64 ndata4, qint64 ndata5)
{
Q_D(QmlProfilerDataModel);
QString displayName;
if (type == QmlDebug::Painting && bindingType == QmlDebug::AnimationFrame) {
displayName = tr("Animations");
......@@ -186,10 +204,10 @@ void QmlProfilerDataModel::addQmlEvent(int type, int bindingType, qint64 startTi
QmlEventData eventData = {displayName, type, bindingType, startTime, duration, data, location,
ndata1, ndata2, ndata3, ndata4, ndata5};
m_eventList.append(eventData);
d->eventList.append(eventData);
m_modelManager->modelProxyCountUpdated(m_modelId, startTime,
m_modelManager->estimatedProfilingTime() * 2);
d->modelManager->modelProxyCountUpdated(d->modelId, startTime,
d->modelManager->estimatedProfilingTime() * 2);
}
QString QmlProfilerDataModel::getHashString(const QmlProfilerDataModel::QmlEventData &event)
......@@ -204,17 +222,19 @@ QString QmlProfilerDataModel::getHashString(const QmlProfilerDataModel::QmlEvent
qint64 QmlProfilerDataModel::lastTimeMark() const
{
if (m_eventList.isEmpty())
Q_D(const QmlProfilerDataModel);
if (d->eventList.isEmpty())
return 0;
return m_eventList.last().startTime + m_eventList.last().duration;
return d->eventList.last().startTime + d->eventList.last().duration;
}
void QmlProfilerDataModel::detailsChanged(int requestId, const QString &newString)
{
QTC_ASSERT(requestId < m_eventList.count(), return);
Q_D(QmlProfilerDataModel);
QTC_ASSERT(requestId < d->eventList.count(), return);
QmlEventData *event = &m_eventList[requestId];
QmlEventData *event = &d->eventList[requestId];
event->data = QStringList(newString);
}
......
......@@ -70,7 +70,8 @@ protected slots:
void detailsChanged(int requestId, const QString &newString);
private:
QVector<QmlEventData> m_eventList;
class QmlProfilerDataModelPrivate;
Q_DECLARE_PRIVATE(QmlProfilerDataModel)
};
}
......
......@@ -30,6 +30,7 @@
#include "qv8profilerdatamodel.h"
#include "qmlprofilermodelmanager.h"
#include "qmlprofilerdetailsrewriter.h"
#include "qmlprofilerbasemodel_p.h"
#include <utils/qtcassert.h>
#include <QStringList>
......@@ -95,33 +96,35 @@ QV8ProfilerDataModel::QV8EventData::~QV8EventData()
childrenHash.clear();
}
class QV8ProfilerDataModel::QV8ProfilerDataModelPrivate
class QV8ProfilerDataModel::QV8ProfilerDataModelPrivate :
public QmlProfilerBaseModel::QmlProfilerBaseModelPrivate
{
public:
QV8ProfilerDataModelPrivate(QV8ProfilerDataModel *qq) {Q_UNUSED(qq);}
QV8ProfilerDataModelPrivate(QV8ProfilerDataModel *qq) :
QmlProfilerBaseModel::QmlProfilerBaseModelPrivate(qq) {}
QHash<QString, QV8EventData *> v8EventHash;
QList<QV8EventData *> pendingRewrites;
QHash<int, QV8EventData *> v8parents;
QV8EventData v8RootEvent;
qint64 v8MeasuredTime;
private:
Q_DECLARE_PUBLIC(QV8ProfilerDataModel)
};
QV8ProfilerDataModel::QV8ProfilerDataModel(Utils::FileInProjectFinder *fileFinder,
QmlProfilerModelManager *parent)
: QmlProfilerBaseModel(fileFinder, parent), d(new QV8ProfilerDataModelPrivate(this))
: QmlProfilerBaseModel(fileFinder, parent, new QV8ProfilerDataModelPrivate(this))
{
Q_D(QV8ProfilerDataModel);
d->v8MeasuredTime = 0;
clearV8RootEvent();
}
QV8ProfilerDataModel::~QV8ProfilerDataModel()
{
delete d;
}
void QV8ProfilerDataModel::clear()
{
Q_D(QV8ProfilerDataModel);
qDeleteAll(d->v8EventHash.values());
d->v8EventHash.clear();
d->v8parents.clear();
......@@ -134,11 +137,13 @@ void QV8ProfilerDataModel::clear()
bool QV8ProfilerDataModel::isEmpty() const
{
Q_D(const QV8ProfilerDataModel);
return d->v8EventHash.isEmpty();
}
QV8ProfilerDataModel::QV8EventData *QV8ProfilerDataModel::v8EventDescription(int eventId) const
{
Q_D(const QV8ProfilerDataModel);
foreach (QV8EventData *event, d->v8EventHash) {
if (event->eventId == eventId)
return event;
......@@ -148,11 +153,13 @@ QV8ProfilerDataModel::QV8EventData *QV8ProfilerDataModel::v8EventDescription(int
qint64 QV8ProfilerDataModel::v8MeasuredTime() const
{
Q_D(const QV8ProfilerDataModel);
return d->v8MeasuredTime;
}
QList<QV8ProfilerDataModel::QV8EventData *> QV8ProfilerDataModel::getV8Events() const
{
Q_D(const QV8ProfilerDataModel);
return d->v8EventHash.values();
}
......@@ -168,6 +175,7 @@ void QV8ProfilerDataModel::addV8Event(int depth,
double totalTime,
double selfTime)
{
Q_D(QV8ProfilerDataModel);
QString displayName = filename.mid(filename.lastIndexOf(QLatin1Char('/')) + 1) +
QLatin1Char(':') + QString::number(lineNumber);
QString hashStr = getHashStringForV8Event(displayName, function);
......@@ -228,18 +236,21 @@ void QV8ProfilerDataModel::addV8Event(int depth,
void QV8ProfilerDataModel::detailsChanged(int requestId, const QString &newString)
{
Q_D(QV8ProfilerDataModel);
QTC_ASSERT(requestId < d->pendingRewrites.count(), return);
d->pendingRewrites[requestId]->filename = newString;
}
void QV8ProfilerDataModel::detailsDone()
{
Q_D(QV8ProfilerDataModel);
d->pendingRewrites.clear();
QmlProfilerBaseModel::detailsDone();
}
void QV8ProfilerDataModel::complete()
{
Q_D(QV8ProfilerDataModel);
if (!d->v8EventHash.isEmpty()) {
double totalTimes = d->v8MeasuredTime;
double selfTimes = 0;
......@@ -278,7 +289,7 @@ void QV8ProfilerDataModel::complete()
foreach (QV8EventData *v8event, d->v8EventHash.values()) {
v8event->eventId = index++;
d->pendingRewrites << v8event;
m_detailsRewriter.requestDetailsForLocation(index,
d->detailsRewriter->requestDetailsForLocation(index,
QmlDebug::QmlEventLocation(v8event->filename, v8event->line, 1));
}
......@@ -293,6 +304,7 @@ void QV8ProfilerDataModel::complete()
void QV8ProfilerDataModel::clearV8RootEvent()
{
Q_D(QV8ProfilerDataModel);
d->v8RootEvent.displayName = tr("<program>");
d->v8RootEvent.eventHashStr = tr("<program>");
d->v8RootEvent.functionName = tr("Main Program");
......@@ -312,6 +324,7 @@ void QV8ProfilerDataModel::clearV8RootEvent()
void QV8ProfilerDataModel::save(QXmlStreamWriter &stream)
{
Q_D(QV8ProfilerDataModel);
stream.writeStartElement(QLatin1String("v8profile")); // v8 profiler output
stream.writeAttribute(QLatin1String("totalTime"), QString::number(d->v8MeasuredTime));
foreach (const QV8EventData *v8event, d->v8EventHash) {
......@@ -351,6 +364,7 @@ void QV8ProfilerDataModel::save(QXmlStreamWriter &stream)
void QV8ProfilerDataModel::load(QXmlStreamReader &stream)
{
Q_D(QV8ProfilerDataModel);
QHash <int, QV8EventData *> v8eventBuffer;
QHash <int, QString> childrenIndexes;
QHash <int, QString> childrenTimes;
......
......@@ -77,7 +77,6 @@ public:
};
QV8ProfilerDataModel(Utils::FileInProjectFinder *fileFinder, QmlProfilerModelManager *parent = 0);
~QV8ProfilerDataModel();
void clear();
bool isEmpty() const;
......@@ -103,8 +102,9 @@ public slots:
private:
class QV8ProfilerDataModelPrivate;
QV8ProfilerDataModelPrivate *d;
void clearV8RootEvent();
Q_DECLARE_PRIVATE(QV8ProfilerDataModel)
};
} // namespace QmlProfiler
......
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