From 10fd477dcd2a7a8a7710712f353137986660e370 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 14 Sep 2011 01:45:12 -0400 Subject: [PATCH] Properly handle and propagate retrace errors. --- gui/apitrace.cpp | 62 +++++++++++++++++++++++++++++++++++--------- gui/apitrace.h | 2 ++ gui/apitracecall.cpp | 3 --- gui/apitracecall.h | 8 ++++++ gui/mainwindow.cpp | 29 ++++++++------------- gui/mainwindow.h | 4 +-- gui/retracer.cpp | 12 ++++----- gui/retracer.h | 12 +++------ 8 files changed, 83 insertions(+), 49 deletions(-) diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index 2500489..1087cca 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -252,18 +252,6 @@ bool ApiTrace::isSaving() const return m_saver->isRunning(); } -void ApiTrace::callError(ApiTraceCall *call) -{ - Q_ASSERT(call); - - if (call->hasError()) - m_errors.insert(call); - else - m_errors.remove(call); - - emit changed(call); -} - bool ApiTrace::hasErrors() const { return !m_errors.isEmpty(); @@ -291,6 +279,31 @@ void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame, emit beginLoadingFrame(frame, calls.size()); frame->setCalls(calls, binaryDataSize); emit endLoadingFrame(frame); + + if (!m_queuedErrors.isEmpty()) { + QList< QPair >::iterator itr; + for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end(); + ++itr) { + const ApiTraceError &error = (*itr).second; + if ((*itr).first == frame) { + ApiTraceCall *call = frame->callWithIndex(error.callIndex); + + if (!call) { + continue; + } + + call->setError(error.message); + m_queuedErrors.erase(itr); + + if (call->hasError()) { + m_errors.insert(call); + } else { + m_errors.remove(call); + } + emit changed(call); + } + } + } } void ApiTrace::findNext(ApiTraceFrame *frame, @@ -433,4 +446,29 @@ int ApiTrace::callInFrame(int callIdx) const return -1; } +void ApiTrace::setCallError(const ApiTraceError &error) +{ + int frameIdx = callInFrame(error.callIndex); + ApiTraceFrame *frame = 0; + + if (frameIdx < 0) { + return; + } + frame = m_frames[frameIdx]; + + if (frame->loaded()) { + ApiTraceCall *call = frame->callWithIndex(error.callIndex); + call->setError(error.message); + if (call->hasError()) { + m_errors.insert(call); + } else { + m_errors.remove(call); + } + emit changed(call); + } else { + emit requestFrame(frame); + m_queuedErrors.append(qMakePair(frame, error)); + } +} + #include "apitrace.moc" diff --git a/gui/apitrace.h b/gui/apitrace.h index 5cd3fe7..c5a2975 100644 --- a/gui/apitrace.h +++ b/gui/apitrace.h @@ -73,6 +73,7 @@ public slots: void findFrameStart(ApiTraceFrame *frame); void findFrameEnd(ApiTraceFrame *frame); void findCallIndex(int index); + void setCallError(const ApiTraceError &error); signals: @@ -138,6 +139,7 @@ private: bool m_needsSaving; QSet m_errors; + QList< QPair > m_queuedErrors; }; #endif diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index 8d95f16..43ec636 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -657,11 +657,8 @@ QString ApiTraceCall::error() const void ApiTraceCall::setError(const QString &msg) { if (m_error != msg) { - ApiTrace *trace = parentTrace(); m_error = msg; m_richText = QString(); - if (trace) - trace->callError(this); } } diff --git a/gui/apitracecall.h b/gui/apitracecall.h index 01dd003..d30bf1d 100644 --- a/gui/apitracecall.h +++ b/gui/apitracecall.h @@ -42,6 +42,14 @@ private: QVariant m_variant; }; + +struct ApiTraceError +{ + int callIndex; + QString type; + QString message; +}; + class ApiTraceEnumSignature { public: diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 7644e00..9e7fbad 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -707,8 +707,8 @@ void MainWindow::initConnections() this, SLOT(replayError(const QString&))); connect(m_retracer, SIGNAL(foundState(ApiTraceState*)), this, SLOT(replayStateFound(ApiTraceState*))); - connect(m_retracer, SIGNAL(retraceErrors(const QList&)), - this, SLOT(slotRetraceErrors(const QList&))); + connect(m_retracer, SIGNAL(retraceErrors(const QList&)), + this, SLOT(slotRetraceErrors(const QList&))); connect(m_ui.vertexInterpretButton, SIGNAL(clicked()), m_vdataInterpreter, SLOT(interpretData())); @@ -977,20 +977,17 @@ void MainWindow::slotTraceChanged(ApiTraceCall *call) } } -void MainWindow::slotRetraceErrors(const QList &errors) +void MainWindow::slotRetraceErrors(const QList &errors) { m_ui.errorsTreeWidget->clear(); - foreach(RetraceError error, errors) { - ApiTraceCall *call = m_trace->callWithIndex(error.callIndex); - if (!call) - continue; - call->setError(error.message); + foreach(ApiTraceError error, errors) { + m_trace->setCallError(error); QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.errorsTreeWidget); item->setData(0, Qt::DisplayRole, error.callIndex); - item->setData(0, Qt::UserRole, QVariant::fromValue(call)); + item->setData(0, Qt::UserRole, error.callIndex); QString type = error.type; type[0] = type[0].toUpper(); item->setData(1, Qt::DisplayRole, type); @@ -1001,15 +998,9 @@ void MainWindow::slotRetraceErrors(const QList &errors) void MainWindow::slotErrorSelected(QTreeWidgetItem *current) { if (current) { - ApiTraceCall *call = - current->data(0, Qt::UserRole).value(); - Q_ASSERT(call); - QModelIndex index = m_proxyModel->indexForCall(call); - if (index.isValid()) { - m_ui.callView->setCurrentIndex(index); - } else { - statusBar()->showMessage(tr("Call has been filtered out.")); - } + int callIndex = + current->data(0, Qt::UserRole).toInt(); + m_trace->findCallIndex(callIndex); } } @@ -1201,6 +1192,8 @@ void MainWindow::slotJumpToResult(ApiTraceCall *call) QModelIndex index = m_proxyModel->indexForCall(call); if (index.isValid()) { m_ui.callView->setCurrentIndex(index); + } else { + statusBar()->showMessage(tr("Call has been filtered out.")); } } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 0e1b3a2..0ae8ab7 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -21,7 +21,7 @@ class QModelIndex; class QProgressBar; class QTreeWidgetItem; class QUrl; -struct RetraceError; +struct ApiTraceError; class Retracer; class SearchWidget; class ShadersSourceWidget; @@ -71,7 +71,7 @@ private slots: void slotGoFrameStart(); void slotGoFrameEnd(); void slotTraceChanged(ApiTraceCall *call); - void slotRetraceErrors(const QList &errors); + void slotRetraceErrors(const QList &errors); void slotErrorSelected(QTreeWidgetItem *current); void slotSearchResult(ApiTrace::SearchResult result, ApiTraceCall *call); diff --git a/gui/retracer.cpp b/gui/retracer.cpp index 500d859..251028c 100644 --- a/gui/retracer.cpp +++ b/gui/retracer.cpp @@ -100,8 +100,8 @@ void Retracer::run() this, SIGNAL(error(const QString&))); connect(retrace, SIGNAL(foundState(ApiTraceState*)), this, SIGNAL(foundState(ApiTraceState*))); - connect(retrace, SIGNAL(retraceErrors(const QList&)), - this, SIGNAL(retraceErrors(const QList&))); + connect(retrace, SIGNAL(retraceErrors(const QList&)), + this, SIGNAL(retraceErrors(const QList&))); retrace->start(); @@ -163,11 +163,11 @@ void RetraceProcess::replayFinished() } QStringList errorLines = errStr.split('\n'); - QList errors; + QList errors; QRegExp regexp("(^\\d+): +(\\b\\w+\\b): (.+$)"); foreach(QString line, errorLines) { if (regexp.indexIn(line) != -1) { - RetraceError error; + ApiTraceError error; error.callIndex = regexp.cap(1).toInt(); error.type = regexp.cap(2); error.message = regexp.cap(3); @@ -190,14 +190,14 @@ void RetraceProcess::replayError(QProcess::ProcessError err) tr("Couldn't execute the replay file '%1'").arg(m_fileName)); } -Q_DECLARE_METATYPE(QList); +Q_DECLARE_METATYPE(QList); RetraceProcess::RetraceProcess(QObject *parent) : QObject(parent) { m_process = new QProcess(this); m_jsonParser = new QJson::Parser(); - qRegisterMetaType >(); + qRegisterMetaType >(); connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(replayFinished())); diff --git a/gui/retracer.h b/gui/retracer.h index 70170f5..4a43c26 100644 --- a/gui/retracer.h +++ b/gui/retracer.h @@ -1,6 +1,8 @@ #ifndef RETRACER_H #define RETRACER_H +#include "apitracecall.h" + #include #include @@ -9,12 +11,6 @@ namespace QJson { class Parser; } -struct RetraceError { - int callIndex; - QString type; - QString message; -}; - /* internal class used by the retracer to run * in the thread */ class RetraceProcess : public QObject @@ -49,7 +45,7 @@ signals: void finished(const QString &output); void error(const QString &msg); void foundState(ApiTraceState *state); - void retraceErrors(const QList &errors); + void retraceErrors(const QList &errors); private slots: void replayFinished(); @@ -91,7 +87,7 @@ signals: void finished(const QString &output); void foundState(ApiTraceState *state); void error(const QString &msg); - void retraceErrors(const QList &errors); + void retraceErrors(const QList &errors); protected: virtual void run(); -- 2.43.0