diff options
-rw-r--r-- | src/libs/tracing/safecastable.h | 62 | ||||
-rw-r--r-- | src/libs/tracing/traceevent.h | 10 | ||||
-rw-r--r-- | src/libs/tracing/traceeventtype.h | 10 | ||||
-rw-r--r-- | src/libs/tracing/tracing.pro | 1 | ||||
-rw-r--r-- | src/libs/tracing/tracing.qbs | 1 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlevent.h | 10 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmleventtype.cpp | 2 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmleventtype.h | 2 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp | 26 |
9 files changed, 106 insertions, 18 deletions
diff --git a/src/libs/tracing/safecastable.h b/src/libs/tracing/safecastable.h new file mode 100644 index 0000000000..7c1fae2e7a --- /dev/null +++ b/src/libs/tracing/safecastable.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 + +namespace Timeline { + +template<class Base> +class SafeCastable +{ +public: + template<class Derived> + bool is() const + { + return static_cast<const Base *>(this)->classId() == Derived::staticClassId; + } + + template<class Derived> + Derived &asRef() + { + Q_ASSERT(is<Derived>()); + return static_cast<Derived &>(*this); + } + + template<class Derived> + const Derived &asConstRef() const + { + Q_ASSERT(is<Derived>()); + return static_cast<const Derived &>(*this); + } + + template<class Derived> + Derived &&asRvalueRef() + { + Q_ASSERT(is<Derived>()); + return static_cast<Derived &&>(*this); + } +}; + +} // namespace Timeline diff --git a/src/libs/tracing/traceevent.h b/src/libs/tracing/traceevent.h index 780ebf7ad9..7f097315eb 100644 --- a/src/libs/tracing/traceevent.h +++ b/src/libs/tracing/traceevent.h @@ -26,13 +26,14 @@ #pragma once #include "tracing_global.h" +#include "safecastable.h" #include <QHash> #include <QMetaType> namespace Timeline { -class TraceEvent +class TraceEvent : public SafeCastable<TraceEvent> { public: qint64 timestamp() const { return m_timestamp; } @@ -43,9 +44,11 @@ public: bool isValid() const { return m_typeIndex != -1; } + qint32 classId() const { return m_classId; } + protected: - TraceEvent(qint64 timestamp = -1, qint32 typeIndex = -1) - : m_timestamp(timestamp), m_typeIndex(typeIndex) + TraceEvent(qint32 classId, qint64 timestamp = -1, qint32 typeIndex = -1) + : m_timestamp(timestamp), m_typeIndex(typeIndex), m_classId(classId) {} TraceEvent(const TraceEvent &) = default; @@ -56,6 +59,7 @@ protected: private: qint64 m_timestamp; qint32 m_typeIndex; + qint32 m_classId; }; } // namespace Timeline diff --git a/src/libs/tracing/traceeventtype.h b/src/libs/tracing/traceeventtype.h index 58a3e180cd..9a667d6fd7 100644 --- a/src/libs/tracing/traceeventtype.h +++ b/src/libs/tracing/traceeventtype.h @@ -26,6 +26,7 @@ #pragma once #include "tracing_global.h" +#include "safecastable.h" #include <QHash> #include <QMetaType> @@ -33,7 +34,7 @@ namespace Timeline { -class TraceEventType +class TraceEventType : public SafeCastable<TraceEventType> { public: const QString &displayName() const { return m_displayName; } @@ -42,9 +43,11 @@ public: quint8 feature() const { return m_feature; } void setFeature(quint8 feature) { m_feature = feature; } + qint32 classId() const { return m_classId; } + protected: - TraceEventType(quint8 feature = 255, const QString &displayName = QString()) - : m_displayName(displayName), m_feature(feature) + TraceEventType(qint32 classId, quint8 feature = 255, const QString &displayName = QString()) + : m_displayName(displayName), m_classId(classId), m_feature(feature) {} TraceEventType(const TraceEventType &) = default; @@ -54,6 +57,7 @@ protected: private: QString m_displayName; + qint32 m_classId; quint8 m_feature; }; diff --git a/src/libs/tracing/tracing.pro b/src/libs/tracing/tracing.pro index 1ef079a20b..a12f03a860 100644 --- a/src/libs/tracing/tracing.pro +++ b/src/libs/tracing/tracing.pro @@ -25,6 +25,7 @@ SOURCES += \ HEADERS += \ $$PWD/flamegraph.h \ $$PWD/flamegraphattached.h \ + $$PWD/safecastable.h \ $$PWD/tracing_global.h \ $$PWD/timelinemodel.h \ $$PWD/timelinemodel_p.h \ diff --git a/src/libs/tracing/tracing.qbs b/src/libs/tracing/tracing.qbs index d91c765db0..4705d9adc7 100644 --- a/src/libs/tracing/tracing.qbs +++ b/src/libs/tracing/tracing.qbs @@ -17,6 +17,7 @@ Project { "README", "flamegraph.cpp", "flamegraph.h", "flamegraphattached.h", + "safecastable.h", "timelineabstractrenderer.cpp", "timelineabstractrenderer.h", "timelineabstractrenderer_p.h", "timelineformattime.cpp", "timelineformattime.h", diff --git a/src/plugins/qmlprofiler/qmlevent.h b/src/plugins/qmlprofiler/qmlevent.h index 23a62cb643..3f999d419e 100644 --- a/src/plugins/qmlprofiler/qmlevent.h +++ b/src/plugins/qmlprofiler/qmlevent.h @@ -39,24 +39,26 @@ namespace QmlProfiler { struct QmlEvent : public Timeline::TraceEvent { - QmlEvent() : m_dataType(Inline8Bit), m_dataLength(0) {} + static const qint32 staticClassId = 0x716d6c65; // 'qmle'; + + QmlEvent() : TraceEvent(staticClassId), m_dataType(Inline8Bit), m_dataLength(0) {} template<typename Number> QmlEvent(qint64 timestamp, int typeIndex, std::initializer_list<Number> list) - : TraceEvent(timestamp, typeIndex) + : TraceEvent(staticClassId, timestamp, typeIndex) { assignNumbers<std::initializer_list<Number>, Number>(list); } QmlEvent(qint64 timestamp, int typeIndex, const QString &data) - : TraceEvent(timestamp, typeIndex) + : TraceEvent(staticClassId, timestamp, typeIndex) { assignNumbers<QByteArray, qint8>(data.toUtf8()); } template<typename Number> QmlEvent(qint64 timestamp, int typeIndex, const QVector<Number> &data) - : TraceEvent(timestamp, typeIndex) + : TraceEvent(staticClassId, timestamp, typeIndex) { assignNumbers<QVector<Number>, Number>(data); } diff --git a/src/plugins/qmlprofiler/qmleventtype.cpp b/src/plugins/qmlprofiler/qmleventtype.cpp index 9cb99c0081..88a3d6dd47 100644 --- a/src/plugins/qmlprofiler/qmleventtype.cpp +++ b/src/plugins/qmlprofiler/qmleventtype.cpp @@ -79,7 +79,7 @@ QDataStream &operator<<(QDataStream &stream, const QmlEventType &type) QmlEventType::QmlEventType(Message message, RangeType rangeType, int detailType, const QmlEventLocation &location, const QString &data, const QString displayName) : - TraceEventType(qmlFeatureFromType(message, rangeType, detailType)), + TraceEventType(staticClassId, qmlFeatureFromType(message, rangeType, detailType)), m_data(data), m_location(location), m_message(message), m_rangeType(rangeType), m_detailType(detailType) { diff --git a/src/plugins/qmlprofiler/qmleventtype.h b/src/plugins/qmlprofiler/qmleventtype.h index 6c3fc53e06..1e038e634e 100644 --- a/src/plugins/qmlprofiler/qmleventtype.h +++ b/src/plugins/qmlprofiler/qmleventtype.h @@ -37,6 +37,8 @@ namespace QmlProfiler { class QmlEventType : public Timeline::TraceEventType { public: + static const qint32 staticClassId = 0x716d6c74; // 'qmlt'; + QmlEventType(Message message = MaximumMessage, RangeType rangeType = MaximumRangeType, int detailType = -1, const QmlEventLocation &location = QmlEventLocation(), const QString &data = QString(), const QString displayName = QString()); diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index c54c7f0981..2d02c10afd 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -148,8 +148,9 @@ void QmlProfilerModelManager::registerFeatures(quint64 features, QmlEventLoader { const TraceEventLoader traceEventLoader = eventLoader ? [eventLoader]( const Timeline::TraceEvent &event, const Timeline::TraceEventType &type) { - return eventLoader(static_cast<const QmlEvent &>(event), - static_cast<const QmlEventType &>(type)); + QTC_ASSERT(event.is<QmlEvent>(), return); + QTC_ASSERT(type.is<QmlEventType>(), return); + eventLoader(event.asConstRef<QmlEvent>(), type.asConstRef<QmlEventType>()); } : TraceEventLoader(); Timeline::TimelineTraceManager::registerFeatures(features, traceEventLoader, initializer, @@ -158,7 +159,10 @@ void QmlProfilerModelManager::registerFeatures(quint64 features, QmlEventLoader const QmlEventType &QmlProfilerModelManager::eventType(int typeId) const { - return static_cast<const QmlEventType &>(TimelineTraceManager::eventType(typeId)); + static const QmlEventType invalid; + const Timeline::TraceEventType &type = TimelineTraceManager::eventType(typeId); + QTC_ASSERT(type.is<QmlEventType>(), return invalid); + return type.asConstRef<QmlEventType>(); } void QmlProfilerModelManager::replayEvents(TraceEventLoader loader, Initializer initializer, @@ -190,7 +194,8 @@ void QmlProfilerModelManager::replayQmlEvents(QmlEventLoader loader, if (future.isCanceled()) return false; - loader(static_cast<QmlEvent &&>(event), eventType(event.typeIndex())); + QTC_ASSERT(event.is<QmlEvent>(), return false); + loader(event.asRvalueRef<QmlEvent>(), eventType(event.typeIndex())); return true; }); @@ -462,13 +467,19 @@ void QmlProfilerEventTypeStorage::set(int typeId, Timeline::TraceEventType &&typ const size_t index = static_cast<size_t>(typeId); if (m_types.size() <= index) m_types.resize(index + 1); - m_types[index] = std::move(static_cast<QmlEventType &&>(type)); + QTC_ASSERT(type.is<QmlEventType>(), return); + m_types[index] = std::move(type.asRvalueRef<QmlEventType>()); } int QmlProfilerEventTypeStorage::append(Timeline::TraceEventType &&type) { const size_t index = m_types.size(); - m_types.push_back(std::move(static_cast<QmlEventType &&>(type))); + if (type.is<QmlEventType>()) { + m_types.push_back(std::move(type.asRvalueRef<QmlEventType>())); + } else { + QTC_CHECK(false); + m_types.push_back(QmlEventType()); + } QTC_ASSERT(index <= std::numeric_limits<int>::max(), return std::numeric_limits<int>::max()); return static_cast<int>(index); } @@ -495,7 +506,8 @@ QmlProfilerEventStorage::QmlProfilerEventStorage( int QmlProfilerEventStorage::append(Timeline::TraceEvent &&event) { - m_file.append(std::move(static_cast<QmlEvent &&>(event))); + QTC_ASSERT(event.is<QmlEvent>(), return m_size); + m_file.append(std::move(event.asRvalueRef<QmlEvent>())); return m_size++; } |