diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2018-04-05 09:47:33 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-04-19 08:09:07 +0000 |
commit | 1c2e0f387f552d3fbe98050f8629c11829ec95f7 (patch) | |
tree | 1a03f9f0e5c68f384d5940f19a59017f648a820a /src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp | |
parent | 7099f215865d90b69906dc92da77857fa0e66165 (diff) |
QmlProfiler: Move parts of model manager and trace file to Timeline
This way we can use the trace file loading and saving mechanism for
other profilers.
Change-Id: I98ec1cdde6f7abcea152cabf72e64d4e696dfa59
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp')
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp | 651 |
1 files changed, 168 insertions, 483 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index 2f5afbd8ac..f60e843b40 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -30,9 +30,9 @@ #include "qmlprofilerdetailsrewriter.h" #include <coreplugin/progressmanager/progressmanager.h> +#include <timeline/tracestashfile.h> #include <utils/runextensions.h> #include <utils/qtcassert.h> -#include <utils/temporaryfile.h> #include <QDebug> #include <QFile> @@ -43,7 +43,6 @@ #include <functional> namespace QmlProfiler { -namespace Internal { static const char *ProfileFeatureNames[] = { QT_TRANSLATE_NOOP("MainView", "JavaScript"), @@ -62,65 +61,44 @@ static const char *ProfileFeatureNames[] = { Q_STATIC_ASSERT(sizeof(ProfileFeatureNames) == sizeof(char *) * MaximumProfileFeature); -} // namespace Internal - -using namespace Internal; - class QmlProfilerModelManager::QmlProfilerModelManagerPrivate { public: QmlProfilerModelManagerPrivate() : file("qmlprofiler-data") {} - QmlProfilerNotesModel *notesModel = nullptr; - QmlProfilerTextMarkModel *textMarkModel = nullptr; - - QmlProfilerModelManager::State state = Empty; - - int numFinishedFinalizers = 0; - - int numLoadedEvents = 0; - quint64 availableFeatures = 0; - quint64 visibleFeatures = 0; - quint64 recordedFeatures = 0; - bool aggregateTraces = false; - - QHash<ProfileFeature, QVector<EventLoader> > eventLoaders; - QVector<Finalizer> finalizers; + Internal::QmlProfilerTextMarkModel *textMarkModel = nullptr; QVector<QmlEventType> eventTypes; - QmlProfilerDetailsRewriter *detailsRewriter = nullptr; + Internal::QmlProfilerDetailsRewriter *detailsRewriter = nullptr; - Utils::TemporaryFile file; - QDataStream eventStream; + Timeline::TraceStashFile<QmlEvent> file; - qint64 traceStart = -1; - qint64 traceEnd = -1; - qint64 restrictedTraceStart = -1; - qint64 restrictedTraceEnd = -1; + void writeToStream(const QmlEvent &event); + void addEventType(const QmlEventType &eventType); + void handleError(const QString &message); - void dispatch(const QmlEvent &event, const QmlEventType &type); void rewriteType(int typeIndex); int resolveStackTop(); - void updateTraceTime(qint64 time); - void restrictTraceTimeToRange(qint64 start, qint64 end); }; QmlProfilerModelManager::QmlProfilerModelManager(QObject *parent) : - QObject(parent), d(new QmlProfilerModelManagerPrivate) + Timeline::TimelineTraceManager(parent), d(new QmlProfilerModelManagerPrivate) { - d->notesModel = new QmlProfilerNotesModel(this); - d->textMarkModel = new QmlProfilerTextMarkModel(this); + setNotesModel(new QmlProfilerNotesModel(this)); + d->textMarkModel = new Internal::QmlProfilerTextMarkModel(this); - d->detailsRewriter = new QmlProfilerDetailsRewriter(this); - connect(d->detailsRewriter, &QmlProfilerDetailsRewriter::rewriteDetailsString, - this, &QmlProfilerModelManager::detailsChanged); - connect(d->detailsRewriter, &QmlProfilerDetailsRewriter::eventDetailsChanged, + d->detailsRewriter = new Internal::QmlProfilerDetailsRewriter(this); + connect(d->detailsRewriter, &Internal::QmlProfilerDetailsRewriter::rewriteDetailsString, + this, &QmlProfilerModelManager::typeDetailsChanged); + connect(d->detailsRewriter, &Internal::QmlProfilerDetailsRewriter::eventDetailsChanged, this, &QmlProfilerModelManager::typeDetailsFinished); - if (d->file.open()) - d->eventStream.setDevice(&d->file); - else + if (!d->file.open()) emit error(tr("Cannot open temporary trace file to store events.")); + + quint64 allFeatures = 0; + for (quint8 i = 0; i <= MaximumProfileFeature; ++i) + allFeatures |= (1ull << i); } QmlProfilerModelManager::~QmlProfilerModelManager() @@ -128,129 +106,51 @@ QmlProfilerModelManager::~QmlProfilerModelManager() delete d; } -qint64 QmlProfilerModelManager::traceStart() const -{ - return d->restrictedTraceStart != -1 ? d->restrictedTraceStart : d->traceStart; -} - -qint64 QmlProfilerModelManager::traceEnd() const -{ - return d->restrictedTraceEnd != -1 ? d->restrictedTraceEnd : d->traceEnd; -} - -qint64 QmlProfilerModelManager::traceDuration() const -{ - return traceEnd() - traceStart(); -} - -void QmlProfilerModelManager::decreaseTraceStart(qint64 start) -{ - QTC_ASSERT(start >= 0, return); - if (d->traceStart > start || d->traceStart == -1) { - d->traceStart = start; - if (d->traceEnd == -1) - d->traceEnd = d->traceStart; - else - QTC_ASSERT(d->traceEnd >= d->traceStart, d->traceEnd = d->traceStart); - } -} - -void QmlProfilerModelManager::increaseTraceEnd(qint64 end) -{ - QTC_ASSERT(end >= 0, return); - if (d->traceEnd < end || d->traceEnd == -1) { - d->traceEnd = end; - if (d->traceStart == -1) - d->traceStart = d->traceEnd; - else - QTC_ASSERT(d->traceEnd >= d->traceStart, d->traceStart = d->traceEnd); - } -} - -QmlProfilerNotesModel *QmlProfilerModelManager::notesModel() const -{ - return d->notesModel; -} - -QmlProfilerTextMarkModel *QmlProfilerModelManager::textMarkModel() const +Internal::QmlProfilerTextMarkModel *QmlProfilerModelManager::textMarkModel() const { return d->textMarkModel; } -bool QmlProfilerModelManager::isEmpty() const +void QmlProfilerModelManager::registerFeatures(quint64 features, QmlEventLoader eventLoader, + Initializer initializer, Finalizer finalizer, + Clearer clearer) { - return d->file.pos() == 0; -} + 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)); + } : TraceEventLoader(); -int QmlProfilerModelManager::numEvents() const -{ - return d->numLoadedEvents; -} - -int QmlProfilerModelManager::numEventTypes() const -{ - return d->eventTypes.count(); -} - -int QmlProfilerModelManager::numFinishedFinalizers() const -{ - return d->numFinishedFinalizers; -} - -int QmlProfilerModelManager::numRegisteredFinalizers() const -{ - return d->finalizers.count(); + Timeline::TimelineTraceManager::registerFeatures(features, traceEventLoader, initializer, + finalizer, clearer); } void QmlProfilerModelManager::addEvents(const QVector<QmlEvent> &events) { - for (const QmlEvent &event : events) { - d->eventStream << event; - d->updateTraceTime(event.timestamp()); - d->dispatch(event, d->eventTypes[event.typeIndex()]); - } -} - -void QmlProfilerModelManager::addEvent(const QmlEvent &event) -{ - d->eventStream << event; - d->updateTraceTime(event.timestamp()); - QTC_ASSERT(event.typeIndex() < d->eventTypes.size(), - d->eventTypes.resize(event.typeIndex() + 1)); - d->dispatch(event, d->eventTypes.at(event.typeIndex())); + for (const QmlEvent &event : events) + addEvent(event); } void QmlProfilerModelManager::addEventTypes(const QVector<QmlEventType> &types) { - const int firstTypeId = d->eventTypes.length();; - d->eventTypes.append(types); - for (int typeId = firstTypeId, end = d->eventTypes.length(); typeId < end; ++typeId) { - d->rewriteType(typeId); - const QmlEventLocation &location = d->eventTypes[typeId].location(); - if (location.isValid()) { - d->textMarkModel->addTextMarkId(typeId, QmlEventLocation( - findLocalFile(location.filename()), location.line(), - location.column())); - } + for (const QmlEventType &type : types) { + d->addEventType(type); + TimelineTraceManager::addEventType(type); } } -void QmlProfilerModelManager::addEventType(const QmlEventType &type) +const QmlEventType &QmlProfilerModelManager::eventType(int typeId) const { - const int typeId = d->eventTypes.count(); - d->eventTypes.append(type); - d->rewriteType(typeId); - const QmlEventLocation &location = type.location(); - if (location.isValid()) { - d->textMarkModel->addTextMarkId( - typeId, QmlEventLocation(findLocalFile(location.filename()), - location.line(), location.column())); - } + return d->eventTypes.at(typeId); } -const QmlEventType &QmlProfilerModelManager::eventType(int typeId) const +void QmlProfilerModelManager::replayEvents(qint64 rangeStart, qint64 rangeEnd, + TraceEventLoader loader, Initializer initializer, + Finalizer finalizer, ErrorHandler errorHandler, + QFutureInterface<void> &future) const { - return d->eventTypes.at(typeId); + replayEvents(rangeStart, rangeEnd, static_cast<QmlEventLoader>(loader), initializer, finalizer, + errorHandler, future); } static bool isStateful(const QmlEventType &type) @@ -262,82 +162,102 @@ static bool isStateful(const QmlEventType &type) return message == PixmapCacheEvent || message == MemoryAllocation; } -bool QmlProfilerModelManager::replayEvents(qint64 rangeStart, qint64 rangeEnd, - EventLoader loader) const +void QmlProfilerModelManager::replayEvents(qint64 rangeStart, qint64 rangeEnd, + QmlEventLoader loader, Initializer initializer, + Finalizer finalizer, ErrorHandler errorHandler, + QFutureInterface<void> &future) const { - QStack<QmlEvent> stack; - QmlEvent event; - QFile file(d->file.fileName()); - if (!file.open(QIODevice::ReadOnly)) - return false; + if (initializer) + initializer(); - QDataStream stream(&file); + QStack<QmlEvent> stack; bool crossedRangeStart = false; - while (!stream.atEnd()) { - stream >> event; - if (stream.status() == QDataStream::ReadPastEnd) - break; + + const auto result = d->file.replay([&](const QmlEvent &event) { + if (future.isCanceled()) + return false; const QmlEventType &type = d->eventTypes[event.typeIndex()]; - if (rangeStart != -1 && rangeEnd != -1) { - // Double-check if rangeStart has been crossed. Some versions of Qt send dirty data. - if (event.timestamp() < rangeStart && !crossedRangeStart) { - if (type.rangeType() != MaximumRangeType) { - if (event.rangeStage() == RangeStart) - stack.push(event); - else if (event.rangeStage() == RangeEnd) - stack.pop(); - continue; - } else if (isStateful(type)) { - event.setTimestamp(rangeStart); - } else { - continue; - } + + // No restrictions: load all events + if (rangeStart == -1 || rangeEnd == -1) { + loader(event, type); + return true; + } + + // Double-check if rangeStart has been crossed. Some versions of Qt send dirty data. + qint64 adjustedTimestamp = event.timestamp(); + if (event.timestamp() < rangeStart && !crossedRangeStart) { + if (type.rangeType() != MaximumRangeType) { + if (event.rangeStage() == RangeStart) + stack.push(event); + else if (event.rangeStage() == RangeEnd) + stack.pop(); + return true; + } else if (isStateful(type)) { + adjustedTimestamp = rangeStart; } else { - if (!crossedRangeStart) { - foreach (QmlEvent stashed, stack) { - stashed.setTimestamp(rangeStart); - loader(stashed, d->eventTypes[stashed.typeIndex()]); - } - stack.clear(); - crossedRangeStart = true; + return true; + } + } else { + if (!crossedRangeStart) { + for (QmlEvent stashed : stack) { + stashed.setTimestamp(rangeStart); + loader(stashed, d->eventTypes[stashed.typeIndex()]); } - if (event.timestamp() > rangeEnd) { - if (type.rangeType() != MaximumRangeType) { - if (event.rangeStage() == RangeEnd) { - if (stack.isEmpty()) { - QmlEvent endEvent(event); - endEvent.setTimestamp(rangeEnd); - loader(endEvent, d->eventTypes[event.typeIndex()]); - } else { - stack.pop(); - } - } else if (event.rangeStage() == RangeStart) { - stack.push(event); + stack.clear(); + crossedRangeStart = true; + } + if (event.timestamp() > rangeEnd) { + if (type.rangeType() != MaximumRangeType) { + if (event.rangeStage() == RangeEnd) { + if (stack.isEmpty()) { + QmlEvent endEvent(event); + endEvent.setTimestamp(rangeEnd); + loader(endEvent, d->eventTypes[event.typeIndex()]); + } else { + stack.pop(); } - continue; - } else if (isStateful(type)) { - event.setTimestamp(rangeEnd); - } else { - continue; + } else if (event.rangeStage() == RangeStart) { + stack.push(event); } + return true; + } else if (isStateful(type)) { + adjustedTimestamp = rangeEnd; + } else { + return true; } } } - loader(event, type); - } - return true; -} + if (adjustedTimestamp != event.timestamp()) { + QmlEvent adjusted(event); + adjusted.setTimestamp(adjustedTimestamp); + loader(adjusted, type); + } else { + loader(event, type); + } + return true; + }); -void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::dispatch(const QmlEvent &event, - const QmlEventType &type) -{ - for (const EventLoader &loader : eventLoaders.value( - static_cast<ProfileFeature>(type.feature()))) { - loader(event, type); + switch (result) { + case Timeline::TraceStashFile<QmlEvent>::ReplaySuccess: + if (finalizer) + finalizer(); + break; + case Timeline::TraceStashFile<QmlEvent>::ReplayOpenFailed: + if (errorHandler) + errorHandler(tr("Could not re-open temporary trace file")); + break; + case Timeline::TraceStashFile<QmlEvent>::ReplayLoadFailed: + if (errorHandler) + errorHandler(tr("Could not load events from temporary trace file")); + break; + case Timeline::TraceStashFile<QmlEvent>::ReplayReadPastEnd: + if (errorHandler) + errorHandler(tr("Read past end in temporary trace file")); + break; } - ++numLoadedEvents; } static QString getDisplayName(const QmlEventType &event) @@ -374,6 +294,30 @@ static QString getInitialDetails(const QmlEventType &event) return details; } +void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::writeToStream(const QmlEvent &event) +{ + file.append(event); +} + +void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::addEventType(const QmlEventType &type) +{ + const int typeId = eventTypes.count(); + eventTypes.append(type); + rewriteType(typeId); + const QmlEventLocation &location = type.location(); + if (location.isValid()) { + textMarkModel->addTextMarkId(typeId, QmlEventLocation( + detailsRewriter->getLocalFile(location.filename()), + location.line(), location.column())); + } +} + +void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::handleError(const QString &message) +{ + // What to do here? + qWarning() << message; +} + void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::rewriteType(int typeIndex) { QmlEventType &type = eventTypes[typeIndex]; @@ -390,85 +334,6 @@ void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::rewriteType(int ty detailsRewriter->requestDetailsForLocation(typeIndex, location); } -void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::updateTraceTime(qint64 time) -{ - QTC_ASSERT(time >= 0, return); - if (traceStart > time || traceStart == -1) - traceStart = time; - if (traceEnd < time || traceEnd == -1) - traceEnd = time; - QTC_ASSERT(traceEnd >= traceStart, traceStart = traceEnd); -} - -void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::restrictTraceTimeToRange(qint64 start, qint64 end) -{ - QTC_ASSERT(end == -1 || start <= end, end = start); - restrictedTraceStart = start; - restrictedTraceEnd = end; -} - -void QmlProfilerModelManager::announceFeatures(quint64 features, EventLoader eventLoader, - Finalizer finalizer) -{ - if ((features & d->availableFeatures) != features) { - d->availableFeatures |= features; - emit availableFeaturesChanged(d->availableFeatures); - } - if ((features & d->visibleFeatures) != features) { - d->visibleFeatures |= features; - emit visibleFeaturesChanged(d->visibleFeatures); - } - - for (int feature = 0; feature != MaximumProfileFeature; ++feature) { - if (features & (1ULL << feature)) - d->eventLoaders[static_cast<ProfileFeature>(feature)].append(eventLoader); - } - - d->finalizers.append(finalizer); -} - -quint64 QmlProfilerModelManager::availableFeatures() const -{ - return d->availableFeatures; -} - -quint64 QmlProfilerModelManager::visibleFeatures() const -{ - return d->visibleFeatures; -} - -void QmlProfilerModelManager::setVisibleFeatures(quint64 features) -{ - if (d->visibleFeatures != features) { - d->visibleFeatures = features; - emit visibleFeaturesChanged(d->visibleFeatures); - } -} - -quint64 QmlProfilerModelManager::recordedFeatures() const -{ - return d->recordedFeatures; -} - -void QmlProfilerModelManager::setRecordedFeatures(quint64 features) -{ - if (d->recordedFeatures != features) { - d->recordedFeatures = features; - emit recordedFeaturesChanged(d->recordedFeatures); - } -} - -bool QmlProfilerModelManager::aggregateTraces() const -{ - return d->aggregateTraces; -} - -void QmlProfilerModelManager::setAggregateTraces(bool aggregateTraces) -{ - d->aggregateTraces = aggregateTraces; -} - - const char *QmlProfilerModelManager::featureName(ProfileFeature feature) { return ProfileFeatureNames[feature]; @@ -477,18 +342,14 @@ const char *QmlProfilerModelManager::featureName(ProfileFeature feature) void QmlProfilerModelManager::finalize() { QTC_ASSERT(state() == AcquiringData, /**/); - d->file.flush(); + if (!d->file.flush()) + emit error(tr("Failed to flush temporary trace file")); d->detailsRewriter->reloadDocuments(); // Load notes after the timeline models have been initialized ... // which happens on stateChanged(Done). - foreach (const Finalizer &finalizer, d->finalizers) { - finalizer(); - ++d->numFinishedFinalizers; - } - - setState(Done); + TimelineTraceManager::finalize(); } void QmlProfilerModelManager::populateFileFinder(const ProjectExplorer::Target *target) @@ -501,146 +362,6 @@ QString QmlProfilerModelManager::findLocalFile(const QString &remoteFile) return d->detailsRewriter->getLocalFile(remoteFile); } -void QmlProfilerModelManager::save(const QString &filename) -{ - QFile *file = new QFile(filename); - if (!file->open(QIODevice::WriteOnly)) { - emit error(tr("Could not open %1 for writing.").arg(filename)); - delete file; - emit saveFinished(); - return; - } - - d->notesModel->stash(); - - QmlProfilerFileWriter *writer = new QmlProfilerFileWriter(this); - writer->setTraceTime(traceStart(), traceEnd(), traceDuration()); - writer->setData(this); - writer->setNotes(d->notesModel->notes()); - - connect(writer, &QObject::destroyed, this, &QmlProfilerModelManager::saveFinished, - Qt::QueuedConnection); - - connect(writer, &QmlProfilerFileWriter::error, this, [this, file](const QString &message) { - file->close(); - file->remove(); - delete file; - emit error(message); - }, Qt::QueuedConnection); - - connect(writer, &QmlProfilerFileWriter::success, this, [file]() { - file->close(); - delete file; - }, Qt::QueuedConnection); - - connect(writer, &QmlProfilerFileWriter::canceled, this, [file]() { - file->close(); - file->remove(); - delete file; - }, Qt::QueuedConnection); - - QFuture<void> result = Utils::runAsync([file, writer] (QFutureInterface<void> &future) { - writer->setFuture(&future); - if (file->fileName().endsWith(QLatin1String(Constants::QtdFileExtension))) - writer->saveQtd(file); - else - writer->saveQzt(file); - writer->deleteLater(); - }); - - Core::ProgressManager::addTask(result, tr("Saving Trace Data"), Constants::TASK_SAVE, - Core::ProgressManager::ShowInApplicationIcon); -} - -void QmlProfilerModelManager::load(const QString &filename) -{ - bool isQtd = filename.endsWith(QLatin1String(Constants::QtdFileExtension)); - QFile *file = new QFile(filename, this); - if (!file->open(isQtd ? (QIODevice::ReadOnly | QIODevice::Text) : QIODevice::ReadOnly)) { - emit error(tr("Could not open %1 for reading.").arg(filename)); - delete file; - emit loadFinished(); - return; - } - - clear(); - setState(AcquiringData); - QmlProfilerFileReader *reader = new QmlProfilerFileReader(this); - - connect(reader, &QObject::destroyed, this, &QmlProfilerModelManager::loadFinished, - Qt::QueuedConnection); - - connect(reader, &QmlProfilerFileReader::typesLoaded, - this, &QmlProfilerModelManager::addEventTypes); - - connect(reader, &QmlProfilerFileReader::notesLoaded, - d->notesModel, &QmlProfilerNotesModel::setNotes); - - connect(reader, &QmlProfilerFileReader::qmlEventsLoaded, - this, &QmlProfilerModelManager::addEvents); - - connect(reader, &QmlProfilerFileReader::success, this, [this, reader]() { - if (reader->traceStart() >= 0) - decreaseTraceStart(reader->traceStart()); - if (reader->traceEnd() >= 0) - increaseTraceEnd(reader->traceEnd()); - setRecordedFeatures(reader->loadedFeatures()); - delete reader; - finalize(); - }, Qt::QueuedConnection); - - connect(reader, &QmlProfilerFileReader::error, this, [this, reader](const QString &message) { - clear(); - delete reader; - emit error(message); - }, Qt::QueuedConnection); - - connect(reader, &QmlProfilerFileReader::canceled, this, [this, reader]() { - clear(); - delete reader; - }, Qt::QueuedConnection); - - QFuture<void> result = Utils::runAsync([isQtd, file, reader] (QFutureInterface<void> &future) { - reader->setFuture(&future); - if (isQtd) - reader->loadQtd(file); - else - reader->loadQzt(file); - file->close(); - file->deleteLater(); - }); - - Core::ProgressManager::addTask(result, tr("Loading Trace Data"), Constants::TASK_LOAD); -} - -void QmlProfilerModelManager::setState(QmlProfilerModelManager::State state) -{ - // It's not an error, we are continuously calling "AcquiringData" for example - if (d->state == state) - return; - - switch (state) { - case ClearingData: - QTC_ASSERT(d->state == Done || d->state == Empty || d->state == AcquiringData, /**/); - break; - case Empty: - // if it's not empty, complain but go on - QTC_ASSERT(isEmpty(), /**/); - break; - case AcquiringData: - break; - case Done: - QTC_ASSERT(d->state == AcquiringData || d->state == Empty, return); - break; - default: - emit error(tr("Trying to set unknown state in events list.")); - break; - } - - d->state = state; - emit stateChanged(); -} - void QmlProfilerModelManager::detailsChanged(int typeId, const QString &newString) { QTC_ASSERT(typeId < d->eventTypes.count(), return); @@ -648,76 +369,40 @@ void QmlProfilerModelManager::detailsChanged(int typeId, const QString &newStrin emit typeDetailsChanged(typeId); } -QmlProfilerModelManager::State QmlProfilerModelManager::state() const -{ - return d->state; -} - -void QmlProfilerModelManager::doClearEvents() +const Timeline::TraceEventType &QmlProfilerModelManager::lookupType(int typeIndex) const { - d->numLoadedEvents = 0; - d->numFinishedFinalizers = 0; - d->file.remove(); - d->eventStream.unsetDevice(); - if (d->file.open()) - d->eventStream.setDevice(&d->file); - else - emit error(tr("Cannot open temporary trace file to store events.")); - d->restrictTraceTimeToRange(-1, -1); - d->traceStart = -1; - d->traceEnd = -1; - d->notesModel->clear(); - setVisibleFeatures(0); - setRecordedFeatures(0); + return eventType(typeIndex); } -void QmlProfilerModelManager::clearEvents() +void QmlProfilerModelManager::clearEventStorage() { - setState(ClearingData); - doClearEvents(); - setState(Empty); + TimelineTraceManager::clearEventStorage(); + d->file.clear(); + if (!d->file.open()) + emit error(tr("Failed to reset temporary trace file")); } -void QmlProfilerModelManager::clear() +void QmlProfilerModelManager::clearTypeStorage() { - setState(ClearingData); - doClearEvents(); + TimelineTraceManager::clearTypeStorage(); d->eventTypes.clear(); - d->detailsRewriter->clear(); - setState(Empty); } -void QmlProfilerModelManager::restrictToRange(qint64 startTime, qint64 endTime) +void QmlProfilerModelManager::addEventType(const QmlEventType &type) { - d->notesModel->stash(); - const QVector<QmlNote> notes = d->notesModel->notes(); - d->notesModel->clear(); - - setState(ClearingData); - setVisibleFeatures(0); - - startAcquiring(); - if (!replayEvents(startTime, endTime, - std::bind(&QmlProfilerModelManagerPrivate::dispatch, d, std::placeholders::_1, - std::placeholders::_2))) { - emit error(tr("Could not re-read events from temporary trace file. " - "The trace data is lost.")); - clear(); - } else { - d->notesModel->setNotes(notes); - d->restrictTraceTimeToRange(startTime, endTime); - finalize(); - } + d->addEventType(type); + TimelineTraceManager::addEventType(type); } -bool QmlProfilerModelManager::isRestrictedToRange() const +void QmlProfilerModelManager::addEvent(const QmlEvent &event) { - return d->restrictedTraceStart != -1 || d->restrictedTraceEnd != -1; + d->writeToStream(event); + TimelineTraceManager::addEvent(event); } -void QmlProfilerModelManager::startAcquiring() +Timeline::TimelineTraceFile *QmlProfilerModelManager::createTraceFile() { - setState(AcquiringData); + return new Internal::QmlProfilerTraceFile(this); } } // namespace QmlProfiler |