Commit 4bfa5d62 authored by Ulf Hermann's avatar Ulf Hermann
Browse files

QmlProfiler: Reduce code duplication between timeline models



Change-Id: Ic898ad06437209040c029304ee156f5aef5929da
Reviewed-by: default avatarKai Koehne <kai.koehne@digia.com>
parent 9cbee153
......@@ -28,21 +28,33 @@
****************************************************************************/
#include "abstracttimelinemodel.h"
#include "abstracttimelinemodel_p.h"
namespace QmlProfiler {
AbstractTimelineModel::AbstractTimelineModel(const QString &name, QObject *parent) :
QObject(parent), m_name(name), m_modelManager(0)
{}
AbstractTimelineModel::AbstractTimelineModel(AbstractTimelineModelPrivate *dd, const QString &name,
QObject *parent) :
QObject(parent), d_ptr(dd)
{
Q_D(AbstractTimelineModel);
d->q_ptr = this;
d->name = name;
d->modelId = 0;
d->modelManager = 0;
}
AbstractTimelineModel::~AbstractTimelineModel()
{}
{
Q_D(AbstractTimelineModel);
delete d;
}
void AbstractTimelineModel::setModelManager(QmlProfilerModelManager *modelManager)
{
m_modelManager = modelManager;
connect(modelManager->simpleModel(),SIGNAL(changed()),this,SLOT(dataChanged()));
m_modelId = modelManager->registerModelProxy();
Q_D(AbstractTimelineModel);
d->modelManager = modelManager;
connect(d->modelManager->simpleModel(),SIGNAL(changed()),this,SLOT(dataChanged()));
d->modelId = d->modelManager->registerModelProxy();
}
QStringList AbstractTimelineModel::categoryTitles() const
......@@ -55,7 +67,56 @@ QStringList AbstractTimelineModel::categoryTitles() const
QString AbstractTimelineModel::name() const
{
return m_name;
Q_D(const AbstractTimelineModel);
return d->name;
}
int AbstractTimelineModel::count() const
{
Q_D(const AbstractTimelineModel);
return d->count();
}
qint64 AbstractTimelineModel::lastTimeMark() const
{
Q_D(const AbstractTimelineModel);
return d->lastEndTime();
}
int AbstractTimelineModel::findFirstIndex(qint64 startTime) const
{
Q_D(const AbstractTimelineModel);
return d->findFirstIndex(startTime);
}
int AbstractTimelineModel::findFirstIndexNoParents(qint64 startTime) const
{
Q_D(const AbstractTimelineModel);
return d->findFirstIndexNoParents(startTime);
}
int AbstractTimelineModel::findLastIndex(qint64 endTime) const
{
Q_D(const AbstractTimelineModel);
return d->findLastIndex(endTime);
}
qint64 AbstractTimelineModel::getDuration(int index) const
{
Q_D(const AbstractTimelineModel);
return d->duration(index);
}
qint64 AbstractTimelineModel::getStartTime(int index) const
{
Q_D(const AbstractTimelineModel);
return d->startTime(index);
}
qint64 AbstractTimelineModel::getEndTime(int index) const
{
Q_D(const AbstractTimelineModel);
return d->startTime(index) + d->duration(index);
}
bool AbstractTimelineModel::isEmpty() const
......@@ -65,22 +126,47 @@ bool AbstractTimelineModel::isEmpty() const
qint64 AbstractTimelineModel::traceStartTime() const
{
return m_modelManager->traceTime()->startTime();
Q_D(const AbstractTimelineModel);
return d->modelManager->traceTime()->startTime();
}
qint64 AbstractTimelineModel::traceEndTime() const
{
return m_modelManager->traceTime()->endTime();
Q_D(const AbstractTimelineModel);
return d->modelManager->traceTime()->endTime();
}
qint64 AbstractTimelineModel::traceDuration() const
{
return m_modelManager->traceTime()->duration();
Q_D(const AbstractTimelineModel);
return d->modelManager->traceTime()->duration();
}
int AbstractTimelineModel::getState() const
{
return (int)m_modelManager->state();
Q_D(const AbstractTimelineModel);
return (int)d->modelManager->state();
}
const QVariantMap AbstractTimelineModel::getEventLocation(int index) const
{
Q_UNUSED(index);
QVariantMap map;
return map;
}
int AbstractTimelineModel::getEventIdForHash(const QString &eventHash) const
{
Q_UNUSED(eventHash);
return -1;
}
int AbstractTimelineModel::getEventIdForLocation(const QString &filename, int line, int column) const
{
Q_UNUSED(filename);
Q_UNUSED(line);
Q_UNUSED(column);
return -1;
}
int AbstractTimelineModel::rowCount() const
......@@ -97,9 +183,16 @@ int AbstractTimelineModel::getBindingLoopDest(int index) const
return -1;
}
float AbstractTimelineModel::getHeight(int index) const
{
Q_UNUSED(index);
return 1.0f;
}
void AbstractTimelineModel::dataChanged()
{
switch (m_modelManager->state()) {
Q_D(AbstractTimelineModel);
switch (d->modelManager->state()) {
case QmlProfilerDataState::ProcessingData:
loadData();
break;
......
......@@ -45,59 +45,54 @@ class QMLPROFILER_EXPORT AbstractTimelineModel : public QObject
Q_OBJECT
public:
explicit AbstractTimelineModel(const QString &name, QObject *parent = 0);
class AbstractTimelineModelPrivate;
~AbstractTimelineModel();
// Trivial methods implemented by the abstract model itself
void setModelManager(QmlProfilerModelManager *modelManager);
QStringList categoryTitles() const;
QString name() const;
virtual int count() const = 0;
bool isEmpty() const;
virtual bool eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const = 0;
Q_INVOKABLE virtual qint64 lastTimeMark() const = 0;
// Methods are directly passed on to the private model and relying on its virtual methods.
Q_INVOKABLE qint64 lastTimeMark() const;
Q_INVOKABLE qint64 traceStartTime() const;
Q_INVOKABLE qint64 traceEndTime() const;
Q_INVOKABLE qint64 traceDuration() const;
Q_INVOKABLE int getState() const;
Q_INVOKABLE int rowCount() const;
Q_INVOKABLE qint64 getDuration(int index) const;
Q_INVOKABLE qint64 getStartTime(int index) const;
Q_INVOKABLE qint64 getEndTime(int index) const;
int findFirstIndex(qint64 startTime) const;
int findFirstIndexNoParents(qint64 startTime) const;
int findLastIndex(qint64 endTime) const;
int count() const;
// Methods that have to be implemented by child models
Q_INVOKABLE virtual bool expanded(int category) const = 0;
Q_INVOKABLE virtual void setExpanded(int category, bool expanded) = 0;
Q_INVOKABLE virtual int categoryDepth(int categoryIndex) const = 0;
Q_INVOKABLE virtual int categoryCount() const = 0;
Q_INVOKABLE virtual int rowCount() const;
Q_INVOKABLE virtual const QString categoryLabel(int categoryIndex) const = 0;
virtual int findFirstIndex(qint64 startTime) const = 0;
virtual int findFirstIndexNoParents(qint64 startTime) const = 0;
virtual int findLastIndex(qint64 endTime) const = 0;
Q_INVOKABLE virtual int getEventId(int index) const = 0;
Q_INVOKABLE virtual QColor getColor(int index) const = 0;
Q_INVOKABLE virtual const QVariantList getLabelsForCategory(int category) const = 0;
Q_INVOKABLE virtual const QVariantList getEventDetails(int index) const = 0;
virtual bool eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const = 0;
virtual int getEventType(int index) const = 0;
virtual int getEventCategory(int index) const = 0;
virtual int getEventRow(int index) const = 0;
virtual void loadData() = 0;
virtual void clear() = 0;
Q_INVOKABLE virtual qint64 getDuration(int index) const = 0;
Q_INVOKABLE virtual qint64 getStartTime(int index) const = 0;
Q_INVOKABLE virtual qint64 getEndTime(int index) const = 0;
Q_INVOKABLE virtual int getEventId(int index) const = 0;
Q_INVOKABLE virtual int getBindingLoopDest(int index) const;
Q_INVOKABLE virtual QColor getColor(int index) const = 0;
Q_INVOKABLE virtual float getHeight(int index) const = 0;
Q_INVOKABLE virtual const QVariantList getLabelsForCategory(int category) const = 0;
Q_INVOKABLE virtual const QVariantList getEventDetails(int index) const = 0;
// Methods which can optionally be implemented by child models.
// returned map should contain "file", "line", "column" properties, or be empty
Q_INVOKABLE virtual const QVariantMap getEventLocation(int index) const = 0;
Q_INVOKABLE virtual int getEventIdForHash(const QString &eventHash) const = 0;
Q_INVOKABLE virtual int getEventIdForLocation(const QString &filename, int line, int column) const = 0;
Q_INVOKABLE virtual const QVariantMap getEventLocation(int index) const;
Q_INVOKABLE virtual int getEventIdForHash(const QString &eventHash) const;
Q_INVOKABLE virtual int getEventIdForLocation(const QString &filename, int line, int column) const;
Q_INVOKABLE virtual int getBindingLoopDest(int index) const;
Q_INVOKABLE virtual float getHeight(int index) const;
signals:
void dataAvailable();
......@@ -106,12 +101,15 @@ signals:
void expandedChanged();
protected:
QString m_name;
QmlProfilerModelManager *m_modelManager;
int m_modelId;
explicit AbstractTimelineModel(AbstractTimelineModelPrivate *dd, const QString &name,
QObject *parent = 0);
AbstractTimelineModelPrivate *d_ptr;
protected slots:
void dataChanged();
private:
Q_DECLARE_PRIVATE(AbstractTimelineModel)
};
}
......
/****************************************************************************
**
** 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 ABSTRACTTIMELINEMODEL_P_H
#define ABSTRACTTIMELINEMODEL_P_H
#include "abstracttimelinemodel.h"
namespace QmlProfiler {
class QMLPROFILER_EXPORT AbstractTimelineModel::AbstractTimelineModelPrivate {
public:
virtual ~AbstractTimelineModelPrivate() {}
virtual int count() const = 0;
virtual qint64 duration(int index) const = 0;
virtual qint64 startTime(int index) const = 0;
virtual qint64 lastEndTime() const = 0;
virtual qint64 firstStartTime() const = 0;
virtual int findFirstIndex(qint64 startTime) const = 0;
virtual int findFirstIndexNoParents(qint64 startTime) const = 0;
virtual int findLastIndex(qint64 endTime) const = 0;
QString name;
QmlProfilerModelManager *modelManager;
int modelId;
protected:
AbstractTimelineModel *q_ptr;
private:
Q_DECLARE_PUBLIC(AbstractTimelineModel)
};
}
#endif // ABSTRACTTIMELINEMODEL_P_H
......@@ -32,7 +32,8 @@ SOURCES += \
timelinemodelaggregator.cpp \
qmlprofilerpainteventsmodelproxy.cpp \
sortedtimelinemodel.cpp \
qmlprofilerbasemodel.cpp
qmlprofilerbasemodel.cpp \
singlecategorytimelinemodel.cpp
HEADERS += \
qmlprofilerconstants.h \
......@@ -65,7 +66,10 @@ HEADERS += \
timelinemodelaggregator.h \
qmlprofilerpainteventsmodelproxy.h \
sortedtimelinemodel.h \
qmlprofilerbasemodel.h
qmlprofilerbasemodel.h \
abstracttimelinemodel_p.h \
singlecategorytimelinemodel.h \
singlecategorytimelinemodel_p.h
RESOURCES += \
qml/qmlprofiler.qrc
......
......@@ -24,7 +24,7 @@ QtcPlugin {
name: "General"
files: [
"abstractqmlprofilerrunner.h",
"abstracttimelinemodel.h", "abstracttimelinemodel.cpp",
"abstracttimelinemodel.h", "abstracttimelinemodel_p.h", "abstracttimelinemodel.cpp",
"localqmlprofilerrunner.cpp", "localqmlprofilerrunner.h",
"qmlprofiler_global.h",
"qmlprofilerattachdialog.cpp", "qmlprofilerattachdialog.h",
......@@ -51,6 +51,8 @@ QtcPlugin {
"qmlprofilerviewmanager.cpp", "qmlprofilerviewmanager.h",
"qv8profilerdatamodel.cpp", "qv8profilerdatamodel.h",
"qv8profilereventview.h", "qv8profilereventview.cpp",
"singlecategorytimelinemodel.h", "singlecategorytimelinemodel_p.h",
"singlecategorytimelinemodel.cpp",
"sortedtimelinemodel.h", "sortedtimelinemodel.cpp",
"timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
"timelinerenderer.cpp", "timelinerenderer.h",
......
......@@ -31,6 +31,7 @@
#include "qmlprofilermodelmanager.h"
#include "qmlprofilersimplemodel.h"
#include "sortedtimelinemodel.h"
#include "singlecategorytimelinemodel_p.h"
#include <QCoreApplication>
#include <QVector>
......@@ -50,52 +51,51 @@ struct CategorySpan {
int contractedRows;
};
class PaintEventsModelProxy::PaintEventsModelProxyPrivate : public SortedTimelineModel<QmlPaintEventData>
class PaintEventsModelProxy::PaintEventsModelProxyPrivate :
public SortedTimelineModel<QmlPaintEventData,
SingleCategoryTimelineModel::SingleCategoryTimelineModelPrivate>
{
public:
PaintEventsModelProxyPrivate(PaintEventsModelProxy *qq) : q(qq) {}
~PaintEventsModelProxyPrivate() {}
void computeAnimationCountLimit();
int minAnimationCount;
int maxAnimationCount;
bool expanded;
bool seenForeignPaintEvent;
PaintEventsModelProxy *q;
private:
Q_DECLARE_PUBLIC(PaintEventsModelProxy)
};
PaintEventsModelProxy::PaintEventsModelProxy(QObject *parent)
: AbstractTimelineModel(QLatin1String("PaintEventsModelProxy"), parent),
d(new PaintEventsModelProxyPrivate(this))
: SingleCategoryTimelineModel(new PaintEventsModelProxyPrivate,
QLatin1String("PaintEventsModelProxy"), tr("Painting"),
QmlDebug::Painting, parent)
{
}
PaintEventsModelProxy::~PaintEventsModelProxy()
{
delete d;
}
void PaintEventsModelProxy::clear()
{
Q_D(PaintEventsModelProxy);
d->SortedTimelineModel::clear();
d->minAnimationCount = 1;
d->maxAnimationCount = 1;
d->expanded = false;
d->seenForeignPaintEvent = false;
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
}
bool PaintEventsModelProxy::eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const
{
return (event.eventType == QmlDebug::Painting && event.bindingType == QmlDebug::AnimationFrame);
return SingleCategoryTimelineModel::eventAccepted(event) &&
event.bindingType == QmlDebug::AnimationFrame;
}
void PaintEventsModelProxy::loadData()
{
Q_D(PaintEventsModelProxy);
clear();
QmlProfilerSimpleModel *simpleModel = m_modelManager->simpleModel();
QmlProfilerSimpleModel *simpleModel = d->modelManager->simpleModel();
if (simpleModel->isEmpty())
return;
......@@ -133,41 +133,20 @@ void PaintEventsModelProxy::loadData()
minNextStartTime = event.startTime + 1;
m_modelManager->modelProxyCountUpdated(m_modelId, d->count(), referenceList.count());
d->modelManager->modelProxyCountUpdated(d->modelId, d->count(), referenceList.count());
}
d->computeAnimationCountLimit();
d->computeNesting();
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
}
/////////////////// QML interface
int PaintEventsModelProxy::count() const
{
return d->count();
}
qint64 PaintEventsModelProxy::lastTimeMark() const
{
return d->lastEndTime();
}
bool PaintEventsModelProxy::expanded(int ) const
{
return d->expanded;
}
void PaintEventsModelProxy::setExpanded(int category, bool expanded)
{
Q_UNUSED(category);
d->expanded = expanded;
emit expandedChanged();
}
int PaintEventsModelProxy::categoryDepth(int categoryIndex) const
{
Q_D(const PaintEventsModelProxy);
Q_UNUSED(categoryIndex);
if (isEmpty())
return d->seenForeignPaintEvent ? 0 : 1;
......@@ -175,67 +154,12 @@ int PaintEventsModelProxy::categoryDepth(int categoryIndex) const
return 2;
}
int PaintEventsModelProxy::categoryCount() const
{
return 1;
}
const QString PaintEventsModelProxy::categoryLabel(int categoryIndex) const
{
Q_UNUSED(categoryIndex);
return tr("Painting");
}
int PaintEventsModelProxy::findFirstIndex(qint64 startTime) const
{
return d->findFirstIndex(startTime);
}
int PaintEventsModelProxy::findFirstIndexNoParents(qint64 startTime) const
{
return d->findFirstIndexNoParents(startTime);
}
int PaintEventsModelProxy::findLastIndex(qint64 endTime) const
{
return d->findLastIndex(endTime);
}
int PaintEventsModelProxy::getEventType(int index) const
{
Q_UNUSED(index);
return (int)QmlDebug::Painting;
}
int PaintEventsModelProxy::getEventCategory(int index) const
{
Q_UNUSED(index);
// there is only one category, all events belong to it
return 0;
}
int PaintEventsModelProxy::getEventRow(int index) const
{
Q_UNUSED(index);
return 1;
}
qint64 PaintEventsModelProxy::getDuration(int index) const
{
return d->range(index).duration;
}
qint64 PaintEventsModelProxy::getStartTime(int index) const
{
return d->range(index).start;
}
qint64 PaintEventsModelProxy::getEndTime(int index) const
{
return d->range(index).start + d->range(index).duration;
}
int PaintEventsModelProxy::getEventId(int index) const
{
// there is only one event Id for all painting events
......@@ -245,6 +169,7 @@ int PaintEventsModelProxy::getEventId(int index) const
QColor PaintEventsModelProxy::getColor(int index) const
{
Q_D(const PaintEventsModelProxy);
double fpsFraction = d->range(index).framerate / 60.0;
if (fpsFraction > 1.0)
fpsFraction = 1.0;
......@@ -255,6 +180,7 @@ QColor PaintEventsModelProxy::getColor(int index) const
float PaintEventsModelProxy::getHeight(int index) const
{
Q_D(const PaintEventsModelProxy);
float scale = d->maxAnimationCount - d->minAnimationCount;
float fraction = 1.0f;
if (scale > 1)
......@@ -297,6 +223,7 @@ void PaintEventsModelProxy::PaintEventsModelProxyPrivate::computeAnimationCountL
const QVariantList PaintEventsModelProxy::getEventDetails(int index) const
{
Q_D(const PaintEventsModelProxy);
QVariantList result;
// int eventId = getEventId(index);
......@@ -332,24 +259,5 @@ const QVariantList PaintEventsModelProxy::getEventDetails(int index) const
return result;
}
const QVariantMap PaintEventsModelProxy::getEventLocation(int /*index*/) const
{
QVariantMap map;
return map;
}
int PaintEventsModelProxy::getEventIdForHash(const QString &/*eventHash*/) const
{