Commit 10d942e2 authored by Ulf Hermann's avatar Ulf Hermann Committed by Ulf Hermann
Browse files

QmlProfiler: Split AbstractTimelineModel in two classes



We need a general purpose TimelineModel and a specialized
QmlProfilerTimelineModel.

Change-Id: I2da02d65efa11e160cab5fa9f8a21075beb0e2bf
Reviewed-by: default avatarKai Koehne <kai.koehne@theqtcompany.com>
parent af84726c
......@@ -5,7 +5,6 @@ QT += network qml quick
include(../../qtcreatorplugin.pri)
SOURCES += \
abstracttimelinemodel.cpp \
localqmlprofilerrunner.cpp \
qmlprofileranimationsmodel.cpp \
qmlprofilerattachdialog.cpp \
......@@ -23,6 +22,7 @@ SOURCES += \
qmlprofilerruncontrolfactory.cpp \
qmlprofilerstatemanager.cpp \
qmlprofilerstatewidget.cpp \
qmlprofilertimelinemodel.cpp \
qmlprofilertimelinemodelfactory.cpp \
qmlprofilertool.cpp \
qmlprofilertracefile.cpp \
......@@ -31,14 +31,13 @@ SOURCES += \
qmlprofilerviewmanager.cpp \
qv8profilerdatamodel.cpp \
qv8profilereventview.cpp \
timelinemodel.cpp \
timelinemodelaggregator.cpp \
timelinerenderer.cpp \
timelinezoomcontrol.cpp
HEADERS += \
abstractqmlprofilerrunner.h \
abstracttimelinemodel.h \
abstracttimelinemodel_p.h \
localqmlprofilerrunner.h \
qmlprofiler_global.h \
qmlprofileranimationsmodel.h \
......@@ -59,6 +58,7 @@ HEADERS += \
qmlprofilerruncontrolfactory.h \
qmlprofilerstatemanager.h \
qmlprofilerstatewidget.h \
qmlprofilertimelinemodel.h \
qmlprofilertimelinemodelfactory.h \
qmlprofilertool.h \
qmlprofilertracefile.h \
......@@ -67,6 +67,8 @@ HEADERS += \
qmlprofilerviewmanager.h \
qv8profilerdatamodel.h \
qv8profilereventview.h \
timelinemodel.h \
timelinemodel_p.h \
timelinemodelaggregator.h \
timelinerenderer.h \
timelinezoomcontrol.h
......
......@@ -21,7 +21,6 @@ QtcPlugin {
name: "General"
files: [
"abstractqmlprofilerrunner.h",
"abstracttimelinemodel.h", "abstracttimelinemodel_p.h", "abstracttimelinemodel.cpp",
"localqmlprofilerrunner.cpp", "localqmlprofilerrunner.h",
"qmlprofiler_global.h",
"qmlprofileranimationsmodel.h", "qmlprofileranimationsmodel.cpp",
......@@ -41,6 +40,7 @@ QtcPlugin {
"qmlprofilerstatemanager.cpp", "qmlprofilerstatemanager.h",
"qmlprofilerstatewidget.cpp", "qmlprofilerstatewidget.h",
"qmlprofilerrangemodel.cpp", "qmlprofilerrangemodel.h",
"qmlprofilertimelinemodel.cpp", "qmlprofilertimelinemodel.h",
"qmlprofilertimelinemodelfactory.cpp", "qmlprofilertimelinemodelfactory.h",
"qmlprofilertool.cpp", "qmlprofilertool.h",
"qmlprofilertracefile.cpp", "qmlprofilertracefile.h",
......@@ -49,6 +49,7 @@ QtcPlugin {
"qmlprofilerviewmanager.cpp", "qmlprofilerviewmanager.h",
"qv8profilerdatamodel.cpp", "qv8profilerdatamodel.h",
"qv8profilereventview.h", "qv8profilereventview.cpp",
"timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h",
"timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
"timelinerenderer.cpp", "timelinerenderer.h",
"timelinezoomcontrol.cpp", "timelinezoomcontrol.h"
......
......@@ -31,7 +31,6 @@
#include "qmlprofileranimationsmodel.h"
#include "qmlprofilermodelmanager.h"
#include "qmlprofilerdatamodel.h"
#include "abstracttimelinemodel_p.h"
#include <utils/qtcassert.h>
#include <QCoreApplication>
......@@ -47,10 +46,10 @@ namespace QmlProfiler {
namespace Internal {
QmlProfilerAnimationsModel::QmlProfilerAnimationsModel(QmlProfilerModelManager *manager,
QObject *parent)
: AbstractTimelineModel(manager,
tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileAnimations)),
QmlDebug::Event, QmlDebug::MaximumRangeType, parent)
QObject *parent) :
QmlProfilerTimelineModel(manager,
tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileAnimations)),
QmlDebug::Event, QmlDebug::MaximumRangeType, parent)
{
m_maxGuiThreadAnimations = m_maxRenderThreadAnimations = 0;
announceFeatures(1 << QmlDebug::ProfileAnimations);
......@@ -60,12 +59,12 @@ void QmlProfilerAnimationsModel::clear()
{
m_maxGuiThreadAnimations = m_maxRenderThreadAnimations = 0;
m_data.clear();
AbstractTimelineModel::clear();
QmlProfilerTimelineModel::clear();
}
bool QmlProfilerAnimationsModel::accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const
{
return AbstractTimelineModel::accepted(event) &&
return QmlProfilerTimelineModel::accepted(event) &&
event.detailType== QmlDebug::AnimationFrame;
}
......@@ -149,7 +148,7 @@ int QmlProfilerAnimationsModel::rowMaxValue(int rowNumber) const
case 2:
return m_maxRenderThreadAnimations;
default:
return AbstractTimelineModel::rowMaxValue(rowNumber);
return QmlProfilerTimelineModel::rowMaxValue(rowNumber);
}
}
......
......@@ -33,7 +33,7 @@
#define QMLPROFILERANIMATIONSMODEL_H
#include <QObject>
#include "abstracttimelinemodel.h"
#include "qmlprofilertimelinemodel.h"
#include <qmldebug/qmlprofilereventtypes.h>
#include <qmldebug/qmlprofilereventlocation.h>
//#include <QHash>
......@@ -49,7 +49,7 @@ class QmlProfilerModelManager;
namespace Internal {
class QmlProfilerAnimationsModel : public AbstractTimelineModel
class QmlProfilerAnimationsModel : public QmlProfilerTimelineModel
{
Q_OBJECT
public:
......
......@@ -47,9 +47,9 @@ void QmlProfilerNotesModel::setModelManager(QmlProfilerModelManager *modelManage
m_modelManager = modelManager;
}
void QmlProfilerNotesModel::addTimelineModel(const AbstractTimelineModel *timelineModel)
void QmlProfilerNotesModel::addTimelineModel(const QmlProfilerTimelineModel *timelineModel)
{
connect(timelineModel, &AbstractTimelineModel::destroyed,
connect(timelineModel, &QmlProfilerTimelineModel::destroyed,
this, &QmlProfilerNotesModel::removeTimelineModel);
m_timelineModels.insert(timelineModel->modelId(), timelineModel);
}
......@@ -111,7 +111,7 @@ int QmlProfilerNotesModel::get(int timelineModel, int timelineIndex) const
int QmlProfilerNotesModel::add(int timelineModel, int timelineIndex, const QString &text)
{
const AbstractTimelineModel *model = m_timelineModels[timelineModel];
const QmlProfilerTimelineModel *model = m_timelineModels[timelineModel];
int typeId = model->typeId(timelineIndex);
Note note = { text, timelineModel, timelineIndex };
m_data << note;
......@@ -162,7 +162,7 @@ int QmlProfilerNotesModel::add(int typeId, qint64 start, qint64 duration, const
int timelineIndex = -1;
const QVector<QmlProfilerDataModel::QmlEventTypeData> &types =
m_modelManager->qmlModel()->getEventTypes();
foreach (const AbstractTimelineModel *model, m_timelineModels) {
foreach (const QmlProfilerTimelineModel *model, m_timelineModels) {
if (model->accepted(types[typeId])) {
for (int i = model->firstIndex(start); i <= model->lastIndex(start + duration); ++i) {
if (i < 0)
......@@ -237,7 +237,7 @@ void QmlProfilerNotesModel::saveData()
if (it == m_timelineModels.end())
continue;
const AbstractTimelineModel *model = it.value();
const QmlProfilerTimelineModel *model = it.value();
QmlProfilerDataModel::QmlEventNoteData save = {
model->typeId(note.timelineIndex), model->startTime(note.timelineIndex),
model->duration(note.timelineIndex), note.text
......
......@@ -31,7 +31,7 @@
#ifndef NOTESMODEL_H
#define NOTESMODEL_H
#include "abstracttimelinemodel.h"
#include "qmlprofilertimelinemodel.h"
#include "qmlprofilermodelmanager.h"
#include <QList>
#include <QHash>
......@@ -54,7 +54,7 @@ public:
int count() const;
void setModelManager(QmlProfilerModelManager *modelManager);
void addTimelineModel(const AbstractTimelineModel *timelineModel);
void addTimelineModel(const QmlProfilerTimelineModel *timelineModel);
Q_INVOKABLE int typeId(int index) const;
Q_INVOKABLE QString text(int index) const;
......@@ -86,7 +86,7 @@ private slots:
protected:
QmlProfilerModelManager *m_modelManager;
QList<Note> m_data;
QHash<int, const AbstractTimelineModel *> m_timelineModels;
QHash<int, const QmlProfilerTimelineModel *> m_timelineModels;
bool m_modified;
int add(int typeId, qint64 startTime, qint64 duration, const QString &text);
......
......@@ -32,7 +32,7 @@
#include "qmlprofilerruncontrolfactory.h"
#include "qmlprofilertool.h"
#include "abstracttimelinemodel.h"
#include "qmlprofilertimelinemodel.h"
#include <analyzerbase/analyzermanager.h>
#include <extensionsystem/pluginmanager.h>
......@@ -103,7 +103,7 @@ ExtensionSystem::IPlugin::ShutdownFlag QmlProfilerPlugin::aboutToShutdown()
return SynchronousShutdown;
}
QList<AbstractTimelineModel *> QmlProfilerPlugin::getModels(QmlProfilerModelManager *manager) const
QList<QmlProfilerTimelineModel *> QmlProfilerPlugin::getModels(QmlProfilerModelManager *manager) const
{
return factory->create(manager);
}
......
......@@ -35,7 +35,7 @@
#include "qmlprofilertimelinemodelfactory.h"
#include <extensionsystem/iplugin.h>
#include "abstracttimelinemodel.h"
#include "qmlprofilertimelinemodel.h"
namespace QmlProfiler {
namespace Internal {
......@@ -55,7 +55,7 @@ public:
static bool debugOutput;
static QmlProfilerPlugin *instance;
QList<AbstractTimelineModel *> getModels(QmlProfilerModelManager *manager) const;
QList<QmlProfilerTimelineModel *> getModels(QmlProfilerModelManager *manager) const;
private:
QmlProfilerTimelineModelFactory *factory;
......
......@@ -46,8 +46,8 @@ namespace Internal {
QmlProfilerRangeModel::QmlProfilerRangeModel(QmlProfilerModelManager *manager,
QmlDebug::RangeType range, QObject *parent)
: AbstractTimelineModel(manager, categoryLabel(range), QmlDebug::MaximumMessage, range, parent)
QmlDebug::RangeType range, QObject *parent) :
QmlProfilerTimelineModel(manager, categoryLabel(range), QmlDebug::MaximumMessage, range, parent)
{
m_expandedRowTypes << -1;
announceFeatures(1ULL << QmlDebug::featureFromRangeType(rangeType()));
......@@ -58,7 +58,7 @@ void QmlProfilerRangeModel::clear()
m_expandedRowTypes.clear();
m_expandedRowTypes << -1;
m_data.clear();
AbstractTimelineModel::clear();
QmlProfilerTimelineModel::clear();
}
void QmlProfilerRangeModel::loadData()
......
......@@ -32,7 +32,7 @@
#ifndef QMLPROFILERRANGEMODEL_H
#define QMLPROFILERRANGEMODEL_H
#include "abstracttimelinemodel.h"
#include "qmlprofilertimelinemodel.h"
#include <qmldebug/qmlprofilereventtypes.h>
#include <qmldebug/qmlprofilereventlocation.h>
#include <QVariantList>
......@@ -44,7 +44,7 @@ class QmlProfilerModelManager;
namespace Internal {
class QmlProfilerRangeModel : public AbstractTimelineModel
class QmlProfilerRangeModel : public QmlProfilerTimelineModel
{
Q_OBJECT
public:
......
/****************************************************************************
**
** 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://www.qt.io/licensing. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** 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.
**
****************************************************************************/
#include "qmlprofilertimelinemodel.h"
namespace QmlProfiler {
QmlProfilerTimelineModel::QmlProfilerTimelineModel(QmlProfilerModelManager *modelManager,
const QString &displayName,
QmlDebug::Message message,
QmlDebug::RangeType rangeType, QObject *parent) :
TimelineModel(modelManager->registerModelProxy(), displayName, parent), m_message(message),
m_rangeType(rangeType), m_modelManager(modelManager)
{
connect(modelManager->qmlModel(), &QmlProfilerDataModel::changed,
this, &QmlProfilerTimelineModel::dataChanged);
}
QmlDebug::RangeType QmlProfilerTimelineModel::rangeType() const
{
return m_rangeType;
}
QmlDebug::Message QmlProfilerTimelineModel::message() const
{
return m_message;
}
bool QmlProfilerTimelineModel::accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const
{
return (event.rangeType == m_rangeType && event.message == m_message);
}
bool QmlProfilerTimelineModel::handlesTypeId(int typeIndex) const
{
if (typeIndex < 0)
return false;
return accepted(modelManager()->qmlModel()->getEventTypes().at(typeIndex));
}
void QmlProfilerTimelineModel::clear()
{
TimelineModel::clear();
updateProgress(0, 1);
}
QmlProfilerModelManager *QmlProfilerTimelineModel::modelManager() const
{
return m_modelManager;
}
void QmlProfilerTimelineModel::updateProgress(qint64 count, qint64 max) const
{
m_modelManager->modelProxyCountUpdated(modelId(), count, max);
}
void QmlProfilerTimelineModel::announceFeatures(quint64 features) const
{
m_modelManager->announceFeatures(modelId(), features);
}
void QmlProfilerTimelineModel::dataChanged()
{
switch (m_modelManager->state()) {
case QmlProfilerDataState::ProcessingData:
loadData();
emit emptyChanged();
break;
case QmlProfilerDataState::ClearingData:
clear();
break;
default:
break;
}
}
int QmlProfilerTimelineModel::bindingLoopDest(int index) const
{
Q_UNUSED(index);
return -1;
}
}
/****************************************************************************
**
** 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://www.qt.io/licensing. For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** 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 QMLPROFILERTIMELINEMODEL_H
#define QMLPROFILERTIMELINEMODEL_H
#include "timelinemodel.h"
namespace QmlProfiler {
class QMLPROFILER_EXPORT QmlProfilerTimelineModel : public TimelineModel {
Q_OBJECT
Q_PROPERTY(QmlDebug::RangeType rangeType READ rangeType CONSTANT)
Q_PROPERTY(QmlDebug::Message message READ message CONSTANT)
Q_PROPERTY(QmlProfilerModelManager *modelManager READ modelManager CONSTANT)
public:
QmlProfilerTimelineModel(QmlProfilerModelManager *modelManager, const QString &displayName,
QmlDebug::Message message, QmlDebug::RangeType rangeType,
QObject *parent);
QmlProfilerModelManager *modelManager() const;
QmlDebug::RangeType rangeType() const;
QmlDebug::Message message() const;
virtual bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const;
bool handlesTypeId(int typeId) const;
Q_INVOKABLE virtual int bindingLoopDest(int index) const;
virtual void loadData() = 0;
void clear();
private slots:
void dataChanged();
protected:
void updateProgress(qint64 count, qint64 max) const;
void announceFeatures(quint64 features) const;
private:
const QmlDebug::Message m_message;
const QmlDebug::RangeType m_rangeType;
QmlProfilerModelManager *const m_modelManager;
};
}
#endif // QMLPROFILERTIMELINEMODEL_H
......@@ -31,7 +31,7 @@
#ifndef QMLPROFILERTIMELINEMODELFACTORY_H
#define QMLPROFILERTIMELINEMODELFACTORY_H
#include "abstracttimelinemodel.h"
#include "qmlprofilertimelinemodel.h"
#include "qmlprofilermodelmanager.h"
namespace QmlProfiler {
......@@ -40,7 +40,7 @@ class QMLPROFILER_EXPORT QmlProfilerTimelineModelFactory : public QObject
{
Q_OBJECT
public:
virtual QList<AbstractTimelineModel *> create(QmlProfilerModelManager *manager) = 0;
virtual QList<QmlProfilerTimelineModel *> create(QmlProfilerModelManager *manager) = 0;
};
}
......
......@@ -28,25 +28,25 @@
**
****************************************************************************/
#include "abstracttimelinemodel.h"
#include "abstracttimelinemodel_p.h"
#include "timelinemodel.h"
#include "timelinemodel_p.h"
#include <QLinkedList>
namespace QmlProfiler {
/*!
\class QmlProfiler::AbstractTimelineModel
\brief The AbstractTimelineModel class provides a sorted model for timeline data.
\class QmlProfiler::TimelineModel
\brief The TimelineModel class provides a sorted model for timeline data.
The AbstractTimelineModel lets you keep range data sorted by both start and end times, so that
The TimelineModel lets you keep range data sorted by both start and end times, so that
visible ranges can easily be computed. The only precondition for that to work is that the ranges
must be perfectly nested. A "parent" range of a range R is defined as a range for which the
start time is smaller than R's start time and the end time is greater than R's end time. A set
start time is earlier than R's start time and the end time is later than R's end time. A set
of ranges is perfectly nested if all parent ranges of any given range have a common parent
range. Mind that you can always make that happen by defining a range that spans the whole
available time span. That, however, will make any code that uses firstStartTime() and
lastEndTime() for selecting subsets of the model always select all of it.
available time span. That, however, will make any code that uses firstIndex() and lastIndex()
for selecting subsets of the model always select all of it.
\note Indices returned from the various methods are only valid until a new range is inserted
before them. Inserting a new range before a given index moves the range pointed to by the
......@@ -54,46 +54,29 @@ namespace QmlProfiler {
*/
/*!
\fn qint64 AbstractTimelineModelPrivate::firstStartTime() const
Returns the begin of the first range in the model.
*/
/*!
\fn qint64 AbstractTimelineModelPrivate::lastEndTime() const
Returns the end of the last range in the model.
*/
/*!
\fn const AbstractTimelineModelPrivate::Range &AbstractTimelineModelPrivate::range(int index) const
Returns the range data at the specified index.
*/
/*!
\fn void AbstractTimelineModel::computeNesting()
Compute all ranges' parents.
\sa findFirstIndex
\sa firstIndex()
*/
void AbstractTimelineModel::computeNesting()
void TimelineModel::computeNesting()
{
Q_D(AbstractTimelineModel);
Q_D(TimelineModel);
QLinkedList<int> parents;
for (int range = 0; range != count(); ++range) {
AbstractTimelineModelPrivate::Range &current = d->ranges[range];
TimelineModelPrivate::Range &current = d->ranges[range];
for (QLinkedList<int>::iterator parentIt = parents.begin();;) {
if (parentIt == parents.end()) {
parents.append(range);
break;
}
AbstractTimelineModelPrivate::Range &parent = d->ranges[*parentIt];
TimelineModelPrivate::Range &parent = d->ranges[*parentIt];
qint64 parentEnd = parent.start + parent.duration;
if (parentEnd < current.start) {
if (parent.start == current.start) {
if (parent.parent == -1) {
parent.parent = range;
} else {
AbstractTimelineModelPrivate::Range &ancestor = d->ranges[parent.parent];
TimelineModelPrivate::Range &ancestor = d->ranges[parent.parent];
if (ancestor.start == current.start &&
ancestor.duration < current.duration)
parent.parent = range;
......@@ -115,130 +98,113 @@ void AbstractTimelineModel::computeNesting()
}
}
int AbstractTimelineModel::collapsedRowCount() const
int TimelineModel::collapsedRowCount() const
{
Q_D(const AbstractTimelineModel);
Q_D(const TimelineModel);
return d->collapsedRowCount;
}
void AbstractTimelineModel::setCollapsedRowCount(int rows)
void TimelineModel::setCollapsedRowCount(int rows)
{
Q_D(AbstractTimelineModel);
Q_D(TimelineModel);
d->collapsedRowCount = rows;
}
int AbstractTimelineModel::expandedRowCount() const
int TimelineModel::expandedRowCount() const
{
Q_D(const AbstractTimelineModel);
Q_D(const TimelineModel);
return d->expandedRowCount;
}
void QmlProfiler::AbstractTimelineModel::setExpandedRowCount(int rows)
void QmlProfiler::TimelineModel::setExpandedRowCount(int rows)
{
Q_D(AbstractTimelineModel);