forked from qt-creator/qt-creator
Move flame graph view from QmlProfiler to separate library
We want to use it for other profilers, too. Change-Id: Ice4bd7fdfce6e0153d62a7c9a83dc7de6d5cba30 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -25,8 +25,7 @@
|
|||||||
|
|
||||||
#include "flamegraph.h"
|
#include "flamegraph.h"
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace FlameGraph {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
FlameGraph::FlameGraph(QQuickItem *parent) :
|
FlameGraph::FlameGraph(QQuickItem *parent) :
|
||||||
QQuickItem(parent)
|
QQuickItem(parent)
|
||||||
@@ -180,10 +179,4 @@ void FlameGraph::rebuild()
|
|||||||
emit depthChanged(m_depth);
|
emit depthChanged(m_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant FlameGraphAttached::data(int role) const
|
} // namespace FlameGraph
|
||||||
{
|
|
||||||
return m_data.isValid() ? m_data.data(role) : QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace QmlProfiler
|
|
@@ -25,82 +25,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "flamegraph_global.h"
|
||||||
|
#include "flamegraphattached.h"
|
||||||
|
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace FlameGraph {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class FlameGraphAttached : public QObject
|
class FLAMEGRAPH_EXPORT FlameGraph : public QQuickItem
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(qreal relativeSize READ relativeSize WRITE setRelativeSize
|
|
||||||
NOTIFY relativeSizeChanged)
|
|
||||||
Q_PROPERTY(qreal relativePosition READ relativePosition WRITE setRelativePosition
|
|
||||||
NOTIFY relativePositionChanged)
|
|
||||||
Q_PROPERTY(bool dataValid READ isDataValid NOTIFY dataValidChanged)
|
|
||||||
|
|
||||||
public:
|
|
||||||
FlameGraphAttached(QObject *parent = 0) :
|
|
||||||
QObject(parent), m_relativeSize(0), m_relativePosition(0) {}
|
|
||||||
|
|
||||||
Q_INVOKABLE QVariant data(int role) const;
|
|
||||||
|
|
||||||
bool isDataValid() const
|
|
||||||
{
|
|
||||||
return m_data.isValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal relativeSize() const
|
|
||||||
{
|
|
||||||
return m_relativeSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRelativeSize(qreal relativeSize)
|
|
||||||
{
|
|
||||||
if (relativeSize != m_relativeSize) {
|
|
||||||
m_relativeSize = relativeSize;
|
|
||||||
emit relativeSizeChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal relativePosition() const
|
|
||||||
{
|
|
||||||
return m_relativePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRelativePosition(qreal relativePosition)
|
|
||||||
{
|
|
||||||
if (relativePosition != m_relativePosition) {
|
|
||||||
m_relativePosition = relativePosition;
|
|
||||||
emit relativePositionChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setModelIndex(const QModelIndex &data)
|
|
||||||
{
|
|
||||||
if (data != m_data) {
|
|
||||||
bool validChanged = (data.isValid() != m_data.isValid());
|
|
||||||
m_data = data;
|
|
||||||
if (validChanged)
|
|
||||||
emit dataValidChanged();
|
|
||||||
emit dataChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void dataChanged();
|
|
||||||
void dataValidChanged();
|
|
||||||
void relativeSizeChanged();
|
|
||||||
void relativePositionChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QPersistentModelIndex m_data;
|
|
||||||
qreal m_relativeSize;
|
|
||||||
qreal m_relativePosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FlameGraph : public QQuickItem
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
|
Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
|
||||||
@@ -169,7 +102,6 @@ private:
|
|||||||
const QModelIndex &childIndex, qreal position, qreal size);
|
const QModelIndex &childIndex, qreal position, qreal size);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace FlameGraph
|
||||||
} // namespace QmlProfiler
|
|
||||||
|
|
||||||
QML_DECLARE_TYPEINFO(QmlProfiler::Internal::FlameGraph, QML_HAS_ATTACHED_PROPERTIES)
|
QML_DECLARE_TYPEINFO(FlameGraph::FlameGraph, QML_HAS_ATTACHED_PROPERTIES)
|
16
src/libs/flamegraph/flamegraph.pro
Normal file
16
src/libs/flamegraph/flamegraph.pro
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
QT += qml quick
|
||||||
|
DEFINES += FLAMEGRAPH_LIBRARY
|
||||||
|
|
||||||
|
include(../../qtcreatorlibrary.pri)
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/flamegraph.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/flamegraph.h \
|
||||||
|
$$PWD/flamegraph_global.h \
|
||||||
|
$$PWD/flamegraphattached.h
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
$$PWD/qml/flamegraph.qrc
|
||||||
|
|
30
src/libs/flamegraph/flamegraph.qbs
Normal file
30
src/libs/flamegraph/flamegraph.qbs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import qbs 1.0
|
||||||
|
|
||||||
|
import QtcLibrary
|
||||||
|
|
||||||
|
Project {
|
||||||
|
name: "FlameGraph"
|
||||||
|
|
||||||
|
QtcDevHeaders { }
|
||||||
|
|
||||||
|
QtcLibrary {
|
||||||
|
Depends { name: "Qt"; submodules: ["qml", "quick", "gui"] }
|
||||||
|
|
||||||
|
Group {
|
||||||
|
name: "General"
|
||||||
|
files: [
|
||||||
|
"flamegraph.cpp", "flamegraph.h",
|
||||||
|
"flamegraph_global.h",
|
||||||
|
"flamegraphattached.h",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Group {
|
||||||
|
name: "QML"
|
||||||
|
prefix: "qml/"
|
||||||
|
files: ["flamegraph.qrc"]
|
||||||
|
}
|
||||||
|
|
||||||
|
cpp.defines: base.concat("FLAMEGRAPH_LIBRARY")
|
||||||
|
}
|
||||||
|
}
|
2
src/libs/flamegraph/flamegraph_dependencies.pri
Normal file
2
src/libs/flamegraph/flamegraph_dependencies.pri
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
QTC_LIB_NAME = FlameGraph
|
||||||
|
|
@@ -25,45 +25,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <qmlprofiler/flamegraph.h>
|
#include <QtGlobal>
|
||||||
#include <QObject>
|
|
||||||
#include <QStandardItemModel>
|
|
||||||
#include <QQmlComponent>
|
|
||||||
#include <QQuickItem>
|
|
||||||
|
|
||||||
namespace QmlProfiler {
|
#if defined(FLAMEGRAPH_LIBRARY)
|
||||||
namespace Internal {
|
# define FLAMEGRAPH_EXPORT Q_DECL_EXPORT
|
||||||
|
#else
|
||||||
class DelegateObject : public QQuickItem
|
# define FLAMEGRAPH_EXPORT Q_DECL_IMPORT
|
||||||
{
|
#endif
|
||||||
Q_OBJECT
|
|
||||||
};
|
|
||||||
|
|
||||||
class DelegateComponent : public QQmlComponent
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
QObject *create(QQmlContext *context) override;
|
|
||||||
QObject *beginCreate(QQmlContext *) override;
|
|
||||||
void completeCreate() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FlameGraphTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private slots:
|
|
||||||
void initTestCase();
|
|
||||||
void testRebuild();
|
|
||||||
void cleanupTestCase();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const int sizeRole = Qt::UserRole + 1;
|
|
||||||
static const int dataRole = Qt::UserRole + 2;
|
|
||||||
FlameGraph flameGraph;
|
|
||||||
QStandardItemModel model;
|
|
||||||
DelegateComponent delegate;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace QmlProfiler
|
|
107
src/libs/flamegraph/flamegraphattached.h
Normal file
107
src/libs/flamegraph/flamegraphattached.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** 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 The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "flamegraph_global.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
namespace FlameGraph {
|
||||||
|
|
||||||
|
class FLAMEGRAPH_EXPORT FlameGraphAttached : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(qreal relativeSize READ relativeSize WRITE setRelativeSize
|
||||||
|
NOTIFY relativeSizeChanged)
|
||||||
|
Q_PROPERTY(qreal relativePosition READ relativePosition WRITE setRelativePosition
|
||||||
|
NOTIFY relativePositionChanged)
|
||||||
|
Q_PROPERTY(bool dataValid READ isDataValid NOTIFY dataValidChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
FlameGraphAttached(QObject *parent = 0) :
|
||||||
|
QObject(parent), m_relativeSize(0), m_relativePosition(0) {}
|
||||||
|
|
||||||
|
Q_INVOKABLE QVariant data(int role) const
|
||||||
|
{
|
||||||
|
return m_data.isValid() ? m_data.data(role) : QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDataValid() const
|
||||||
|
{
|
||||||
|
return m_data.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal relativeSize() const
|
||||||
|
{
|
||||||
|
return m_relativeSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRelativeSize(qreal relativeSize)
|
||||||
|
{
|
||||||
|
if (relativeSize != m_relativeSize) {
|
||||||
|
m_relativeSize = relativeSize;
|
||||||
|
emit relativeSizeChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal relativePosition() const
|
||||||
|
{
|
||||||
|
return m_relativePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRelativePosition(qreal relativePosition)
|
||||||
|
{
|
||||||
|
if (relativePosition != m_relativePosition) {
|
||||||
|
m_relativePosition = relativePosition;
|
||||||
|
emit relativePositionChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setModelIndex(const QModelIndex &data)
|
||||||
|
{
|
||||||
|
if (data != m_data) {
|
||||||
|
bool validChanged = (data.isValid() != m_data.isValid());
|
||||||
|
m_data = data;
|
||||||
|
if (validChanged)
|
||||||
|
emit dataValidChanged();
|
||||||
|
emit dataChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dataChanged();
|
||||||
|
void dataValidChanged();
|
||||||
|
void relativeSizeChanged();
|
||||||
|
void relativePositionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPersistentModelIndex m_data;
|
||||||
|
qreal m_relativeSize;
|
||||||
|
qreal m_relativePosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FlameGraph
|
82
src/libs/flamegraph/qml/FlameGraphDelegate.qml
Normal file
82
src/libs/flamegraph/qml/FlameGraphDelegate.qml
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** 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 The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import FlameGraph 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: flamegraphItem
|
||||||
|
property color borderColor
|
||||||
|
property real borderWidth
|
||||||
|
property real itemHeight
|
||||||
|
property bool isSelected
|
||||||
|
property string text;
|
||||||
|
|
||||||
|
signal mouseEntered
|
||||||
|
signal mouseExited
|
||||||
|
signal clicked
|
||||||
|
|
||||||
|
property bool textVisible: width > 20 || isSelected
|
||||||
|
property int level: (parent.level !== undefined ? parent.level + 1 : -1)
|
||||||
|
+ (itemHeight > 0 ? 1 : 0)
|
||||||
|
|
||||||
|
height: parent === null ? 0 : parent.height - (level > 0 ? itemHeight : 0);
|
||||||
|
width: parent === null ? 0 : parent.width * FlameGraph.relativeSize
|
||||||
|
x: parent === null ? 0 : parent.width * FlameGraph.relativePosition
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
border.color: borderColor
|
||||||
|
border.width: borderWidth
|
||||||
|
color: Qt.hsla((level % 12) / 72, 0.9 + Math.random() / 10,
|
||||||
|
0.45 + Math.random() / 10, 0.9 + Math.random() / 10);
|
||||||
|
height: itemHeight;
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
FlameGraphText {
|
||||||
|
id: text
|
||||||
|
visible: textVisible
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 5
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: flamegraphItem.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
|
font.bold: isSelected
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onEntered: flamegraphItem.mouseEntered()
|
||||||
|
onExited: flamegraphItem.mouseExited()
|
||||||
|
onClicked: flamegraphItem.clicked()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/libs/flamegraph/qml/flamegraph.qrc
Normal file
7
src/libs/flamegraph/qml/flamegraph.qrc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/flamegraph">
|
||||||
|
<file>FlameGraphText.qml</file>
|
||||||
|
<file>FlameGraphDetails.qml</file>
|
||||||
|
<file>FlameGraphDelegate.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@@ -16,7 +16,8 @@ SUBDIRS = \
|
|||||||
ssh \
|
ssh \
|
||||||
timeline \
|
timeline \
|
||||||
sqlite \
|
sqlite \
|
||||||
clangbackendipc
|
clangbackendipc \
|
||||||
|
flamegraph
|
||||||
|
|
||||||
for(l, SUBDIRS) {
|
for(l, SUBDIRS) {
|
||||||
QTC_LIB_DEPENDS =
|
QTC_LIB_DEPENDS =
|
||||||
|
@@ -7,6 +7,7 @@ Project {
|
|||||||
"clangbackendipc/clangbackendipc.qbs",
|
"clangbackendipc/clangbackendipc.qbs",
|
||||||
"cplusplus/cplusplus.qbs",
|
"cplusplus/cplusplus.qbs",
|
||||||
"extensionsystem/extensionsystem.qbs",
|
"extensionsystem/extensionsystem.qbs",
|
||||||
|
"flamegraph/flamegraph.qbs",
|
||||||
"glsl/glsl.qbs",
|
"glsl/glsl.qbs",
|
||||||
"languageutils/languageutils.qbs",
|
"languageutils/languageutils.qbs",
|
||||||
"modelinglib/modelinglib.qbs",
|
"modelinglib/modelinglib.qbs",
|
||||||
|
@@ -24,10 +24,12 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "flamegraphview.h"
|
#include "flamegraphview.h"
|
||||||
#include "flamegraph.h"
|
|
||||||
#include "qmlprofilerconstants.h"
|
#include "qmlprofilerconstants.h"
|
||||||
#include "qmlprofilertool.h"
|
#include "qmlprofilertool.h"
|
||||||
|
|
||||||
|
#include <flamegraph/flamegraph.h>
|
||||||
|
|
||||||
|
#include <QQmlEngine>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
@@ -44,14 +46,15 @@ FlameGraphView::FlameGraphView(QmlProfilerModelManager *manager, QWidget *parent
|
|||||||
// We cannot change this without breaking the settings.
|
// We cannot change this without breaking the settings.
|
||||||
setObjectName(QStringLiteral("QmlProfilerFlamegraph"));
|
setObjectName(QStringLiteral("QmlProfilerFlamegraph"));
|
||||||
|
|
||||||
qmlRegisterType<FlameGraph>("FlameGraph", 1, 0, "FlameGraph");
|
qmlRegisterType<FlameGraph::FlameGraph>("FlameGraph", 1, 0, "FlameGraph");
|
||||||
qmlRegisterUncreatableType<FlameGraphModel>("FlameGraphModel", 1, 0, "FlameGraphModel",
|
qmlRegisterUncreatableType<FlameGraphModel>("QmlProfilerFlameGraphModel", 1, 0,
|
||||||
|
"QmlProfilerFlameGraphModel",
|
||||||
QLatin1String("use the context property"));
|
QLatin1String("use the context property"));
|
||||||
qmlRegisterUncreatableType<QAbstractItemModel>("AbstractItemModel", 1, 0, "AbstractItemModel",
|
qmlRegisterUncreatableType<QAbstractItemModel>("AbstractItemModel", 1, 0, "AbstractItemModel",
|
||||||
QLatin1String("only for Qt 5.4"));
|
QLatin1String("only for Qt 5.4"));
|
||||||
|
|
||||||
m_content->rootContext()->setContextProperty(QStringLiteral("flameGraphModel"), m_model);
|
m_content->rootContext()->setContextProperty(QStringLiteral("flameGraphModel"), m_model);
|
||||||
m_content->setSource(QUrl(QStringLiteral("qrc:/qmlprofiler/FlameGraphView.qml")));
|
m_content->setSource(QUrl(QStringLiteral("qrc:/qmlprofiler/QmlProfilerFlameGraphView.qml")));
|
||||||
m_content->setClearColor(QColor(0xdc, 0xdc, 0xdc));
|
m_content->setClearColor(QColor(0xdc, 0xdc, 0xdc));
|
||||||
|
|
||||||
m_content->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_content->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
@@ -26,7 +26,8 @@
|
|||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtQuick.Controls 1.3
|
import QtQuick.Controls 1.3
|
||||||
import FlameGraph 1.0
|
import FlameGraph 1.0
|
||||||
import FlameGraphModel 1.0
|
import QmlProfilerFlameGraphModel 1.0
|
||||||
|
import "../flamegraph/"
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
id: root
|
id: root
|
||||||
@@ -45,7 +46,6 @@ ScrollView {
|
|||||||
|
|
||||||
FlameGraph {
|
FlameGraph {
|
||||||
property int itemHeight: Math.max(30, flickable.height / depth)
|
property int itemHeight: Math.max(30, flickable.height / depth)
|
||||||
property int level: -1
|
|
||||||
property color blue: "blue"
|
property color blue: "blue"
|
||||||
property color blue1: Qt.lighter(blue)
|
property color blue1: Qt.lighter(blue)
|
||||||
property color blue2: Qt.rgba(0.375, 0, 1, 1)
|
property color blue2: Qt.rgba(0.375, 0, 1, 1)
|
||||||
@@ -59,21 +59,42 @@ ScrollView {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: depth * itemHeight
|
height: depth * itemHeight
|
||||||
model: flameGraphModel
|
model: flameGraphModel
|
||||||
sizeRole: FlameGraphModel.DurationRole
|
sizeRole: QmlProfilerFlameGraphModel.DurationRole
|
||||||
sizeThreshold: 0.002
|
sizeThreshold: 0.002
|
||||||
maximumDepth: 25
|
maximumDepth: 25
|
||||||
y: flickable.height > height ? flickable.height - height : 0
|
y: flickable.height > height ? flickable.height - height : 0
|
||||||
|
|
||||||
delegate: Item {
|
delegate: FlameGraphDelegate {
|
||||||
id: flamegraphItem
|
id: flamegraphItem
|
||||||
|
|
||||||
property int typeId: FlameGraph.data(FlameGraphModel.TypeIdRole) || -1
|
property int typeId: FlameGraph.data(QmlProfilerFlameGraphModel.TypeIdRole) || -1
|
||||||
property bool isBindingLoop: parent.checkBindingLoop(typeId)
|
property bool isBindingLoop: parent.checkBindingLoop(typeId)
|
||||||
property int level: parent.level + (rangeTypeVisible ? 1 : 0)
|
|
||||||
property bool isSelected: typeId !== -1 && typeId === root.selectedTypeId
|
|
||||||
&& rangeTypeVisible
|
|
||||||
property bool rangeTypeVisible:
|
property bool rangeTypeVisible:
|
||||||
root.visibleRangeTypes & (1 << FlameGraph.data(FlameGraphModel.RangeTypeRole))
|
root.visibleRangeTypes & (1 << FlameGraph.data(QmlProfilerFlameGraphModel.RangeTypeRole))
|
||||||
|
|
||||||
|
itemHeight: rangeTypeVisible ? flamegraph.itemHeight : 0
|
||||||
|
isSelected: typeId !== -1 && typeId === root.selectedTypeId && rangeTypeVisible
|
||||||
|
|
||||||
|
borderColor: {
|
||||||
|
if (isSelected)
|
||||||
|
return flamegraph.blue2;
|
||||||
|
else if (tooltip.hoveredNode === flamegraphItem)
|
||||||
|
return flamegraph.blue1;
|
||||||
|
else if (note() !== "" || isBindingLoop)
|
||||||
|
return flamegraph.orange;
|
||||||
|
else
|
||||||
|
return flamegraph.grey1;
|
||||||
|
}
|
||||||
|
borderWidth: {
|
||||||
|
if (tooltip.hoveredNode === flamegraphItem ||
|
||||||
|
tooltip.selectedNode === flamegraphItem) {
|
||||||
|
return 2;
|
||||||
|
} else if (note() !== "") {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onIsSelectedChanged: {
|
onIsSelectedChanged: {
|
||||||
if (isSelected && (tooltip.selectedNode === null ||
|
if (isSelected && (tooltip.selectedNode === null ||
|
||||||
@@ -93,10 +114,45 @@ ScrollView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildText() {
|
||||||
|
if (!FlameGraph.dataValid)
|
||||||
|
return "<others>";
|
||||||
|
|
||||||
|
return FlameGraph.data(QmlProfilerFlameGraphModel.DetailsRole) + " ("
|
||||||
|
+ FlameGraph.data(QmlProfilerFlameGraphModel.TypeRole) + ", "
|
||||||
|
+ FlameGraph.data(QmlProfilerFlameGraphModel.TimeInPercentRole) + "%)";
|
||||||
|
}
|
||||||
|
text: textVisible ? buildText() : ""
|
||||||
|
FlameGraph.onDataChanged: if (textVisible) text = buildText();
|
||||||
|
|
||||||
|
onMouseEntered: {
|
||||||
|
tooltip.hoveredNode = flamegraphItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseExited: {
|
||||||
|
if (tooltip.hoveredNode === flamegraphItem)
|
||||||
|
tooltip.hoveredNode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (flamegraphItem.FlameGraph.dataValid) {
|
||||||
|
tooltip.selectedNode = flamegraphItem;
|
||||||
|
root.typeSelected(flamegraphItem.FlameGraph.data(
|
||||||
|
QmlProfilerFlameGraphModel.TypeIdRole));
|
||||||
|
root.gotoSourceLocation(
|
||||||
|
flamegraphItem.FlameGraph.data(
|
||||||
|
QmlProfilerFlameGraphModel.FilenameRole),
|
||||||
|
flamegraphItem.FlameGraph.data(
|
||||||
|
QmlProfilerFlameGraphModel.LineRole),
|
||||||
|
flamegraphItem.FlameGraph.data(
|
||||||
|
QmlProfilerFlameGraphModel.ColumnRole));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Functions, not properties to limit the initial overhead when creating the nodes,
|
// Functions, not properties to limit the initial overhead when creating the nodes,
|
||||||
// and because FlameGraph.data(...) cannot be notified anyway.
|
// and because FlameGraph.data(...) cannot be notified anyway.
|
||||||
function title() { return FlameGraph.data(FlameGraphModel.TypeRole) || ""; }
|
function title() { return FlameGraph.data(QmlProfilerFlameGraphModel.TypeRole) || ""; }
|
||||||
function note() { return FlameGraph.data(FlameGraphModel.NoteRole) || ""; }
|
function note() { return FlameGraph.data(QmlProfilerFlameGraphModel.NoteRole) || ""; }
|
||||||
function details() {
|
function details() {
|
||||||
var model = [];
|
var model = [];
|
||||||
function addDetail(name, index, format) {
|
function addDetail(name, index, format) {
|
||||||
@@ -130,106 +186,17 @@ ScrollView {
|
|||||||
model.push(qsTr("Details"));
|
model.push(qsTr("Details"));
|
||||||
model.push(qsTr("Various Events"));
|
model.push(qsTr("Various Events"));
|
||||||
} else {
|
} else {
|
||||||
addDetail(qsTr("Details"), FlameGraphModel.DetailsRole, noop);
|
addDetail(qsTr("Details"), QmlProfilerFlameGraphModel.DetailsRole, noop);
|
||||||
addDetail(qsTr("Type"), FlameGraphModel.TypeRole, noop);
|
addDetail(qsTr("Type"), QmlProfilerFlameGraphModel.TypeRole, noop);
|
||||||
addDetail(qsTr("Calls"), FlameGraphModel.CallCountRole, noop);
|
addDetail(qsTr("Calls"), QmlProfilerFlameGraphModel.CallCountRole, noop);
|
||||||
addDetail(qsTr("Total Time"), FlameGraphModel.DurationRole, printTime);
|
addDetail(qsTr("Total Time"), QmlProfilerFlameGraphModel.DurationRole, printTime);
|
||||||
addDetail(qsTr("Mean Time"), FlameGraphModel.TimePerCallRole, printTime);
|
addDetail(qsTr("Mean Time"), QmlProfilerFlameGraphModel.TimePerCallRole, printTime);
|
||||||
addDetail(qsTr("In Percent"), FlameGraphModel.TimeInPercentRole,
|
addDetail(qsTr("In Percent"), QmlProfilerFlameGraphModel.TimeInPercentRole,
|
||||||
addPercent);
|
addPercent);
|
||||||
addDetail(qsTr("Location"), FlameGraphModel.LocationRole, noop);
|
addDetail(qsTr("Location"), QmlProfilerFlameGraphModel.LocationRole, noop);
|
||||||
}
|
}
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
border.color: {
|
|
||||||
if (flamegraphItem.isSelected)
|
|
||||||
return flamegraph.blue2;
|
|
||||||
else if (tooltip.hoveredNode === flamegraphItem)
|
|
||||||
return flamegraph.blue1;
|
|
||||||
else if (flamegraphItem.note() !== "" || flamegraphItem.isBindingLoop)
|
|
||||||
return flamegraph.orange;
|
|
||||||
else
|
|
||||||
return flamegraph.grey1;
|
|
||||||
}
|
|
||||||
border.width: {
|
|
||||||
if (tooltip.hoveredNode === flamegraphItem ||
|
|
||||||
tooltip.selectedNode === flamegraphItem) {
|
|
||||||
return 2;
|
|
||||||
} else if (flamegraphItem.note() !== "") {
|
|
||||||
return 3;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
color: Qt.hsla((level % 12) / 72, 0.9 + Math.random() / 10,
|
|
||||||
0.45 + Math.random() / 10, 0.9 + Math.random() / 10);
|
|
||||||
height: flamegraphItem.rangeTypeVisible ? flamegraph.itemHeight : 0;
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
|
|
||||||
FlameGraphText {
|
|
||||||
id: text
|
|
||||||
visible: width > 20 || flamegraphItem === tooltip.selectedNode
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: 5
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: visible ? buildText() : ""
|
|
||||||
elide: Text.ElideRight
|
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
|
||||||
font.bold: flamegraphItem === tooltip.selectedNode
|
|
||||||
|
|
||||||
function buildText() {
|
|
||||||
if (!flamegraphItem.FlameGraph.dataValid)
|
|
||||||
return "<others>";
|
|
||||||
|
|
||||||
return flamegraphItem.FlameGraph.data(FlameGraphModel.DetailsRole)
|
|
||||||
+ " ("
|
|
||||||
+ flamegraphItem.FlameGraph.data(FlameGraphModel.TypeRole)
|
|
||||||
+ ", "
|
|
||||||
+ flamegraphItem.FlameGraph.data(
|
|
||||||
FlameGraphModel.TimeInPercentRole) + "%)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
onEntered: {
|
|
||||||
tooltip.hoveredNode = flamegraphItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: {
|
|
||||||
if (tooltip.hoveredNode === flamegraphItem)
|
|
||||||
tooltip.hoveredNode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (flamegraphItem.FlameGraph.dataValid) {
|
|
||||||
tooltip.selectedNode = flamegraphItem;
|
|
||||||
root.typeSelected(flamegraphItem.FlameGraph.data(
|
|
||||||
FlameGraphModel.TypeIdRole));
|
|
||||||
root.gotoSourceLocation(
|
|
||||||
flamegraphItem.FlameGraph.data(
|
|
||||||
FlameGraphModel.FilenameRole),
|
|
||||||
flamegraphItem.FlameGraph.data(
|
|
||||||
FlameGraphModel.LineRole),
|
|
||||||
flamegraphItem.FlameGraph.data(
|
|
||||||
FlameGraphModel.ColumnRole));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FlameGraph.onDataChanged: if (text.visible) text.text = text.buildText();
|
|
||||||
|
|
||||||
height: flamegraph.height - level * flamegraph.itemHeight;
|
|
||||||
width: parent === null ? flamegraph.width : parent.width * FlameGraph.relativeSize
|
|
||||||
x: parent === null ? 0 : parent.width * FlameGraph.relativePosition
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -2,8 +2,6 @@
|
|||||||
<qresource prefix="/qmlprofiler">
|
<qresource prefix="/qmlprofiler">
|
||||||
<file>bindingloops.vert</file>
|
<file>bindingloops.vert</file>
|
||||||
<file>bindingloops.frag</file>
|
<file>bindingloops.frag</file>
|
||||||
<file>FlameGraphView.qml</file>
|
<file>QmlProfilerFlameGraphView.qml</file>
|
||||||
<file>FlameGraphText.qml</file>
|
|
||||||
<file>FlameGraphDetails.qml</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@@ -6,7 +6,6 @@ include(../../qtcreatorplugin.pri)
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
debugmessagesmodel.cpp \
|
debugmessagesmodel.cpp \
|
||||||
flamegraph.cpp \
|
|
||||||
flamegraphmodel.cpp \
|
flamegraphmodel.cpp \
|
||||||
flamegraphview.cpp \
|
flamegraphview.cpp \
|
||||||
inputeventsmodel.cpp \
|
inputeventsmodel.cpp \
|
||||||
@@ -48,7 +47,6 @@ SOURCES += \
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
debugmessagesmodel.h \
|
debugmessagesmodel.h \
|
||||||
flamegraph.h \
|
|
||||||
flamegraphmodel.h \
|
flamegraphmodel.h \
|
||||||
flamegraphview.h \
|
flamegraphview.h \
|
||||||
inputeventsmodel.h \
|
inputeventsmodel.h \
|
||||||
|
@@ -4,6 +4,8 @@ QtcPlugin {
|
|||||||
name: "QmlProfiler"
|
name: "QmlProfiler"
|
||||||
|
|
||||||
Depends { name: "Qt"; submodules: ["widgets", "network", "quick", "quickwidgets"] }
|
Depends { name: "Qt"; submodules: ["widgets", "network", "quick", "quickwidgets"] }
|
||||||
|
|
||||||
|
Depends { name: "FlameGraph" }
|
||||||
Depends { name: "QmlJS" }
|
Depends { name: "QmlJS" }
|
||||||
Depends { name: "QmlDebug" }
|
Depends { name: "QmlDebug" }
|
||||||
Depends { name: "Utils" }
|
Depends { name: "Utils" }
|
||||||
@@ -19,7 +21,6 @@ QtcPlugin {
|
|||||||
name: "General"
|
name: "General"
|
||||||
files: [
|
files: [
|
||||||
"debugmessagesmodel.cpp", "debugmessagesmodel.h",
|
"debugmessagesmodel.cpp", "debugmessagesmodel.h",
|
||||||
"flamegraph.cpp", "flamegraph.h",
|
|
||||||
"flamegraphmodel.cpp", "flamegraphmodel.h",
|
"flamegraphmodel.cpp", "flamegraphmodel.h",
|
||||||
"flamegraphview.cpp", "flamegraphview.h",
|
"flamegraphview.cpp", "flamegraphview.h",
|
||||||
"inputeventsmodel.cpp", "inputeventsmodel.h",
|
"inputeventsmodel.cpp", "inputeventsmodel.h",
|
||||||
@@ -77,7 +78,6 @@ QtcPlugin {
|
|||||||
prefix: "tests/"
|
prefix: "tests/"
|
||||||
files: [
|
files: [
|
||||||
"debugmessagesmodel_test.cpp", "debugmessagesmodel_test.h",
|
"debugmessagesmodel_test.cpp", "debugmessagesmodel_test.h",
|
||||||
"flamegraph_test.cpp", "flamegraph_test.h",
|
|
||||||
"flamegraphmodel_test.cpp", "flamegraphmodel_test.h",
|
"flamegraphmodel_test.cpp", "flamegraphmodel_test.h",
|
||||||
"flamegraphview_test.cpp", "flamegraphview_test.h",
|
"flamegraphview_test.cpp", "flamegraphview_test.h",
|
||||||
"inputeventsmodel_test.cpp", "inputeventsmodel_test.h",
|
"inputeventsmodel_test.cpp", "inputeventsmodel_test.h",
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
QTC_PLUGIN_NAME = QmlProfiler
|
QTC_PLUGIN_NAME = QmlProfiler
|
||||||
QTC_LIB_DEPENDS += \
|
QTC_LIB_DEPENDS += \
|
||||||
extensionsystem \
|
extensionsystem \
|
||||||
|
flamegraph \
|
||||||
qmldebug \
|
qmldebug \
|
||||||
qmljs \
|
qmljs \
|
||||||
timeline \
|
timeline \
|
||||||
|
@@ -32,7 +32,6 @@
|
|||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
|
|
||||||
#include "tests/debugmessagesmodel_test.h"
|
#include "tests/debugmessagesmodel_test.h"
|
||||||
#include "tests/flamegraph_test.h"
|
|
||||||
#include "tests/flamegraphmodel_test.h"
|
#include "tests/flamegraphmodel_test.h"
|
||||||
#include "tests/flamegraphview_test.h"
|
#include "tests/flamegraphview_test.h"
|
||||||
#include "tests/inputeventsmodel_test.h"
|
#include "tests/inputeventsmodel_test.h"
|
||||||
@@ -102,7 +101,6 @@ QList<QObject *> QmlProfiler::Internal::QmlProfilerPlugin::createTestObjects() c
|
|||||||
QList<QObject *> tests;
|
QList<QObject *> tests;
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
tests << new DebugMessagesModelTest;
|
tests << new DebugMessagesModelTest;
|
||||||
tests << new FlameGraphTest;
|
|
||||||
tests << new FlameGraphModelTest;
|
tests << new FlameGraphModelTest;
|
||||||
tests << new FlameGraphViewTest;
|
tests << new FlameGraphViewTest;
|
||||||
tests << new InputEventsModelTest;
|
tests << new InputEventsModelTest;
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/debugmessagesmodel_test.cpp \
|
$$PWD/debugmessagesmodel_test.cpp \
|
||||||
$$PWD/flamegraph_test.cpp \
|
|
||||||
$$PWD/flamegraphmodel_test.cpp \
|
$$PWD/flamegraphmodel_test.cpp \
|
||||||
$$PWD/flamegraphview_test.cpp \
|
$$PWD/flamegraphview_test.cpp \
|
||||||
$$PWD/inputeventsmodel_test.cpp \
|
$$PWD/inputeventsmodel_test.cpp \
|
||||||
@@ -18,7 +17,6 @@ SOURCES += \
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/debugmessagesmodel_test.h \
|
$$PWD/debugmessagesmodel_test.h \
|
||||||
$$PWD/flamegraph_test.h \
|
|
||||||
$$PWD/flamegraphmodel_test.h \
|
$$PWD/flamegraphmodel_test.h \
|
||||||
$$PWD/flamegraphview_test.h \
|
$$PWD/flamegraphview_test.h \
|
||||||
$$PWD/inputeventsmodel_test.h \
|
$$PWD/inputeventsmodel_test.h \
|
||||||
|
@@ -24,4 +24,4 @@ SUBDIRS += \
|
|||||||
valgrind
|
valgrind
|
||||||
|
|
||||||
qtHaveModule(qml): SUBDIRS += qml
|
qtHaveModule(qml): SUBDIRS += qml
|
||||||
qtHaveModule(quick): SUBDIRS += timeline
|
qtHaveModule(quick): SUBDIRS += flamegraph timeline
|
||||||
|
@@ -14,6 +14,7 @@ Project {
|
|||||||
"extensionsystem/extensionsystem.qbs",
|
"extensionsystem/extensionsystem.qbs",
|
||||||
"externaltool/externaltool.qbs",
|
"externaltool/externaltool.qbs",
|
||||||
"filesearch/filesearch.qbs",
|
"filesearch/filesearch.qbs",
|
||||||
|
"flamegraph/flamegraph.qbs",
|
||||||
"generichighlighter/generichighlighter.qbs",
|
"generichighlighter/generichighlighter.qbs",
|
||||||
"json/json.qbs",
|
"json/json.qbs",
|
||||||
"profilewriter/profilewriter.qbs",
|
"profilewriter/profilewriter.qbs",
|
||||||
|
5
tests/auto/flamegraph/flamegraph.pro
Normal file
5
tests/auto/flamegraph/flamegraph.pro
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
QTC_LIB_DEPENDS += flamegraph
|
||||||
|
include(../qttest.pri)
|
||||||
|
|
||||||
|
QT += quick
|
||||||
|
SOURCES += tst_flamegraph.cpp
|
9
tests/auto/flamegraph/flamegraph.qbs
Normal file
9
tests/auto/flamegraph/flamegraph.qbs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import qbs
|
||||||
|
|
||||||
|
QtcAutotest {
|
||||||
|
name: "FlameGraph autotest"
|
||||||
|
Depends { name: "FlameGraph" }
|
||||||
|
Depends { name: "Qt.quick" }
|
||||||
|
Depends { name: "Qt.gui" }
|
||||||
|
files: "tst_flamegraph.cpp"
|
||||||
|
}
|
@@ -23,14 +23,46 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "flamegraph_test.h"
|
#include <flamegraph/flamegraph.h>
|
||||||
|
#include <flamegraph/flamegraphattached.h>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
#include <QQuickItem>
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
|
|
||||||
namespace QmlProfiler {
|
class DelegateObject : public QQuickItem
|
||||||
namespace Internal {
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
};
|
||||||
|
|
||||||
void FlameGraphTest::initTestCase()
|
class DelegateComponent : public QQmlComponent
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QObject *create(QQmlContext *context) override;
|
||||||
|
QObject *beginCreate(QQmlContext *) override;
|
||||||
|
void completeCreate() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class tst_FlameGraph : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void testRebuild();
|
||||||
|
void cleanupTestCase();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int sizeRole = Qt::UserRole + 1;
|
||||||
|
static const int dataRole = Qt::UserRole + 2;
|
||||||
|
FlameGraph::FlameGraph flameGraph;
|
||||||
|
QStandardItemModel model;
|
||||||
|
DelegateComponent delegate;
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_FlameGraph::initTestCase()
|
||||||
{
|
{
|
||||||
flameGraph.setDelegate(&delegate);
|
flameGraph.setDelegate(&delegate);
|
||||||
flameGraph.setModel(&model);
|
flameGraph.setModel(&model);
|
||||||
@@ -45,7 +77,7 @@ void FlameGraphTest::initTestCase()
|
|||||||
QCOMPARE(flameGraph.sizeThreshold(), 0.01);
|
QCOMPARE(flameGraph.sizeThreshold(), 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlameGraphTest::testRebuild()
|
void tst_FlameGraph::testRebuild()
|
||||||
{
|
{
|
||||||
flameGraph.setModel(nullptr);
|
flameGraph.setModel(nullptr);
|
||||||
qreal sum = 0;
|
qreal sum = 0;
|
||||||
@@ -75,7 +107,9 @@ void FlameGraphTest::testRebuild()
|
|||||||
qreal i = 0;
|
qreal i = 0;
|
||||||
qreal position = 0;
|
qreal position = 0;
|
||||||
foreach (QQuickItem *child, flameGraph.childItems()) {
|
foreach (QQuickItem *child, flameGraph.childItems()) {
|
||||||
FlameGraphAttached *attached = FlameGraph::qmlAttachedProperties(child);
|
FlameGraph::FlameGraphAttached *attached =
|
||||||
|
FlameGraph::FlameGraph::qmlAttachedProperties(child);
|
||||||
|
QVERIFY(attached);
|
||||||
QCOMPARE(attached->relativeSize(), (++i) / sum);
|
QCOMPARE(attached->relativeSize(), (++i) / sum);
|
||||||
QCOMPARE(attached->relativePosition(), position / sum);
|
QCOMPARE(attached->relativePosition(), position / sum);
|
||||||
QCOMPARE(attached->data(dataRole).toInt(), 100 / static_cast<int>(i));
|
QCOMPARE(attached->data(dataRole).toInt(), 100 / static_cast<int>(i));
|
||||||
@@ -83,12 +117,15 @@ void FlameGraphTest::testRebuild()
|
|||||||
|
|
||||||
qreal j = 0;
|
qreal j = 0;
|
||||||
foreach (QQuickItem *grandchild, child->childItems()) {
|
foreach (QQuickItem *grandchild, child->childItems()) {
|
||||||
FlameGraphAttached *attached2 = FlameGraph::qmlAttachedProperties(grandchild);
|
FlameGraph::FlameGraphAttached *attached2 =
|
||||||
|
FlameGraph::FlameGraph::qmlAttachedProperties(grandchild);
|
||||||
|
QVERIFY(attached2);
|
||||||
QCOMPARE(attached2->relativeSize(), 1.0 / i);
|
QCOMPARE(attached2->relativeSize(), 1.0 / i);
|
||||||
QCOMPARE(attached2->relativePosition(), (j++) / i);
|
QCOMPARE(attached2->relativePosition(), (j++) / i);
|
||||||
QCOMPARE(grandchild->childItems().count(), 1);
|
QCOMPARE(grandchild->childItems().count(), 1);
|
||||||
FlameGraphAttached *skipped =
|
FlameGraph::FlameGraphAttached *skipped =
|
||||||
FlameGraph::qmlAttachedProperties(grandchild->childItems()[0]);
|
FlameGraph::FlameGraph::qmlAttachedProperties(grandchild->childItems()[0]);
|
||||||
|
QVERIFY(skipped);
|
||||||
QCOMPARE(skipped->relativePosition(), 0.0);
|
QCOMPARE(skipped->relativePosition(), 0.0);
|
||||||
QCOMPARE(skipped->relativeSize(), 0.001 * 10);
|
QCOMPARE(skipped->relativeSize(), 0.001 * 10);
|
||||||
}
|
}
|
||||||
@@ -98,7 +135,7 @@ void FlameGraphTest::testRebuild()
|
|||||||
QCOMPARE(i, 9.0);
|
QCOMPARE(i, 9.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlameGraphTest::cleanupTestCase()
|
void tst_FlameGraph::cleanupTestCase()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -119,5 +156,6 @@ void DelegateComponent::completeCreate()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
QTEST_MAIN(tst_FlameGraph)
|
||||||
} // namespace QmlProfiler
|
|
||||||
|
#include "tst_flamegraph.moc"
|
Reference in New Issue
Block a user