diff options
author | Kai Koehne <kai.koehne@digia.com> | 2013-06-05 16:55:32 +0200 |
---|---|---|
committer | Kai Koehne <kai.koehne@digia.com> | 2013-06-06 16:01:42 +0200 |
commit | e96414023748a03f63a88886b163177a7a862946 (patch) | |
tree | 26c453cf3d48dc0345023376de1b45f67ca909d1 /plugins/qmlprofiler/qmlprofilermodelmanager.cpp | |
download | qt-creator-e96414023748a03f63a88886b163177a7a862946.tar.gz |
Initial commit of qmlprofiler plugin (commercial version)
Change-Id: I08e838110c17a4a2085e0c3232424787186f9c31
Diffstat (limited to 'plugins/qmlprofiler/qmlprofilermodelmanager.cpp')
-rw-r--r-- | plugins/qmlprofiler/qmlprofilermodelmanager.cpp | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/plugins/qmlprofiler/qmlprofilermodelmanager.cpp new file mode 100644 index 0000000000..c8343c4dd4 --- /dev/null +++ b/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmlprofilermodelmanager.h" +#include "qmlprofilersimplemodel.h" +#include "qmlprofilerprocessedmodel.h" +#include "qv8profilerdatamodel.h" +#include "qmlprofilertracefile.h" + +#include <utils/qtcassert.h> + +#include <QDebug> +#include <QFile> + +namespace QmlProfiler { +namespace Internal { + + +///////////////////////////////////////////////////////////////////// +QmlProfilerDataState::QmlProfilerDataState(QmlProfilerModelManager *modelManager, QObject *parent) + : QObject(parent), m_state(Empty), m_modelManager(modelManager) +{ + connect(this, SIGNAL(error(QString)), m_modelManager, SIGNAL(error(QString))); + connect(this, SIGNAL(stateChanged()), m_modelManager, SIGNAL(stateChanged())); +} + +void QmlProfilerDataState::setState(QmlProfilerDataState::State state) +{ + // It's not an error, we are continuously calling "AcquiringData" for example + if (m_state == state) + return; + + switch (state) { + case Empty: + // if it's not empty, complain but go on + QTC_ASSERT(m_modelManager->isEmpty(), /**/); + break; + case AcquiringData: + // we're not supposed to receive new data while processing older data + QTC_ASSERT(m_state != ProcessingData, return); + break; + case ProcessingData: + QTC_ASSERT(m_state == AcquiringData, return); + break; + case Done: + QTC_ASSERT(m_state == ProcessingData || m_state == Empty, return); + break; + default: + emit error(tr("Trying to set unknown state in events list")); + break; + } + + m_state = state; + emit stateChanged(); + + return; +} + + +///////////////////////////////////////////////////////////////////// +QmlProfilerTraceTime::QmlProfilerTraceTime(QObject *parent) : QObject(parent) +{ + clear(); +} + +QmlProfilerTraceTime::~QmlProfilerTraceTime() +{ +} + +qint64 QmlProfilerTraceTime::startTime() const +{ + return m_startTime; +} + +qint64 QmlProfilerTraceTime::endTime() const +{ + return m_endTime; +} + +qint64 QmlProfilerTraceTime::duration() const +{ + return endTime() - startTime(); +} + +void QmlProfilerTraceTime::clear() +{ + m_startTime = -1; + m_endTime = 0; +} + +void QmlProfilerTraceTime::setStartTime(qint64 time) +{ + m_startTime = time; +} + +void QmlProfilerTraceTime::setEndTime(qint64 time) +{ + m_endTime = time; +} + + +///////////////////////////////////////////////////////////////////// + +class QmlProfilerModelManager::QmlProfilerModelManagerPrivate +{ +public: + QmlProfilerModelManagerPrivate(QmlProfilerModelManager *qq) : q(qq) {} + ~QmlProfilerModelManagerPrivate() {} + QmlProfilerModelManager *q; + + QmlProfilerSimpleModel *model; + QV8ProfilerDataModel *v8Model; + QmlProfilerDataState *dataState; + QmlProfilerTraceTime *traceTime; + + // file to load + QString fileName; +}; + + +QmlProfilerModelManager::QmlProfilerModelManager(Utils::FileInProjectFinder *finder, QObject *parent) : + QObject(parent), d(new QmlProfilerModelManagerPrivate(this)) +{ + d->model = new QmlProfilerProcessedModel(finder, this); + d->v8Model = new QV8ProfilerDataModel(this); +// d->model = new QmlProfilerSimpleModel(this); + d->dataState = new QmlProfilerDataState(this, this); + d->traceTime = new QmlProfilerTraceTime(this); +} + +QmlProfilerModelManager::~QmlProfilerModelManager() +{ + delete d; +} + +QmlProfilerTraceTime *QmlProfilerModelManager::traceTime() const +{ + return d->traceTime; +} + +// TODO: rename to just "model" or something like that +QmlProfilerSimpleModel *QmlProfilerModelManager::simpleModel() const +{ + return d->model; +} + +QV8ProfilerDataModel *QmlProfilerModelManager::v8Model() const +{ + return d->v8Model; +} + +bool QmlProfilerModelManager::isEmpty() const +{ + return d->model->isEmpty() && d->v8Model->isEmpty(); +} + +int QmlProfilerModelManager::count() const +{ + return d->model->count(); +} + +void QmlProfilerModelManager::addRangedEvent(int type, int bindingType, qint64 startTime, qint64 length, const QStringList &data, const QmlDebug::QmlEventLocation &location) +{ + // If trace start time was not explicitly set, use the first event + if (d->traceTime->startTime() == -1) + d->traceTime->setStartTime(startTime); + + QTC_ASSERT(state() == QmlProfilerDataState::AcquiringData, /**/); + d->model->addRangedEvent(type, bindingType, startTime, length, data, location); + emit countChanged(); +} + +void QmlProfilerModelManager::addV8Event(int depth, const QString &function, const QString &filename, + int lineNumber, double totalTime, double selfTime) +{ + d->v8Model->addV8Event(depth, function, filename, lineNumber,totalTime, selfTime); +} + +void QmlProfilerModelManager::complete() +{ + if (state() == QmlProfilerDataState::AcquiringData) { + // If trace end time was not explicitly set, use the last event + if (d->traceTime->endTime() == 0) + d->traceTime->setEndTime(d->model->lastTimeMark()); + setState(QmlProfilerDataState::ProcessingData); + d->model->complete(); + d->v8Model->complete(); + setState(QmlProfilerDataState::Done); + } else + if (state() == QmlProfilerDataState::Empty) { + setState(QmlProfilerDataState::Done); + } else + if (state() == QmlProfilerDataState::Done) { + // repeated Done states are ignored + } else { + emit error(tr("Unexpected complete signal in data model")); + } +} + +void QmlProfilerModelManager::save(const QString &filename) +{ + QFile file(filename); + if (!file.open(QIODevice::WriteOnly)) { + emit error(tr("Could not open %1 for writing.").arg(filename)); + return; + } + + QmlProfilerFileWriter writer; + + writer.setTraceTime(traceTime()->startTime(), traceTime()->endTime(), traceTime()->duration()); + writer.setV8DataModel(d->v8Model); + writer.setQmlEvents(d->model->getEvents()); + writer.save(&file); +} + +void QmlProfilerModelManager::load(const QString &filename) +{ + d->fileName = filename; + load(); +} + +void QmlProfilerModelManager::setFilename(const QString &filename) +{ + d->fileName = filename; +} + +void QmlProfilerModelManager::load() +{ + QString filename = d->fileName; + + QFile file(filename); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + emit error(tr("Could not open %1 for reading.").arg(filename)); + return; + } + + // erase current + clear(); + + setState(QmlProfilerDataState::AcquiringData); + + QmlProfilerFileReader reader; + connect(&reader, SIGNAL(error(QString)), this, SIGNAL(error(QString))); + connect(&reader, SIGNAL(rangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)), this, + SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); + connect(&reader, SIGNAL(traceStartTime(qint64)), traceTime(), SLOT(setStartTime(qint64))); + connect(&reader, SIGNAL(traceEndTime(qint64)), traceTime(), SLOT(setEndTime(qint64))); + + reader.setV8DataModel(d->v8Model); + reader.load(&file); + + complete(); +} + +void QmlProfilerModelManager::setState(QmlProfilerDataState::State state) +{ + d->dataState->setState(state); +} + +QmlProfilerDataState::State QmlProfilerModelManager::state() const +{ + return d->dataState->state(); +} + +void QmlProfilerModelManager::clear() +{ + d->model->clear(); + d->v8Model->clear(); + d->traceTime->clear(); + + emit countChanged(); + setState(QmlProfilerDataState::Empty); +} + +void QmlProfilerModelManager::prepareForWriting() +{ + setState(QmlProfilerDataState::AcquiringData); +} + + +} +} |