]> git.notmuchmail.org Git - apitrace/commitdiff
Properly handle and propagate retrace errors.
authorZack Rusin <zack@kde.org>
Wed, 14 Sep 2011 05:45:12 +0000 (01:45 -0400)
committerZack Rusin <zack@kde.org>
Wed, 14 Sep 2011 05:45:12 +0000 (01:45 -0400)
gui/apitrace.cpp
gui/apitrace.h
gui/apitracecall.cpp
gui/apitracecall.h
gui/mainwindow.cpp
gui/mainwindow.h
gui/retracer.cpp
gui/retracer.h

index 25004890c895094ac7ac8c50bf507c869ced15a8..1087ccab1e698d8207a372deff0ac6a8b5fbe74a 100644 (file)
@@ -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<ApiTraceFrame*, ApiTraceError> >::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"
index 5cd3fe736f990e053946e97a5e3caf8ef1244a86..c5a2975f5ebf207f30cd1ed32f9a4b1dc529a1c4 100644 (file)
@@ -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<ApiTraceCall*> m_errors;
+    QList< QPair<ApiTraceFrame*, ApiTraceError> > m_queuedErrors;
 };
 
 #endif
index 8d95f167fd44607f7d21157316ecb367c59fd0c0..43ec6363ab8a05e20803afdcac46d9496fff8513 100644 (file)
@@ -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);
     }
 }
 
index 01dd0038a3baec4273021464862d79bb9b7253e9..d30bf1db22bf30843689a7241d935f9118ee292b 100644 (file)
@@ -42,6 +42,14 @@ private:
     QVariant m_variant;
 };
 
+
+struct ApiTraceError
+{
+    int callIndex;
+    QString type;
+    QString message;
+};
+
 class ApiTraceEnumSignature
 {
 public:
index 7644e0017f3abaf7ef438cae75d1ebd82006f589..9e7fbad9994e0934a81d5e0d5f58214c43e1dec4 100644 (file)
@@ -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<RetraceError>&)),
-            this, SLOT(slotRetraceErrors(const QList<RetraceError>&)));
+    connect(m_retracer, SIGNAL(retraceErrors(const QList<ApiTraceError>&)),
+            this, SLOT(slotRetraceErrors(const QList<ApiTraceError>&)));
 
     connect(m_ui.vertexInterpretButton, SIGNAL(clicked()),
             m_vdataInterpreter, SLOT(interpretData()));
@@ -977,20 +977,17 @@ void MainWindow::slotTraceChanged(ApiTraceCall *call)
     }
 }
 
-void MainWindow::slotRetraceErrors(const QList<RetraceError> &errors)
+void MainWindow::slotRetraceErrors(const QList<ApiTraceError> &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<RetraceError> &errors)
 void MainWindow::slotErrorSelected(QTreeWidgetItem *current)
 {
     if (current) {
-        ApiTraceCall *call =
-            current->data(0, Qt::UserRole).value<ApiTraceCall*>();
-        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."));
     }
 }
 
index 0e1b3a2038774c29eed725de72eee16866504264..0ae8ab78e9315c619aa99d843b32f27c873e0ea5 100644 (file)
@@ -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<RetraceError> &errors);
+    void slotRetraceErrors(const QList<ApiTraceError> &errors);
     void slotErrorSelected(QTreeWidgetItem *current);
     void slotSearchResult(ApiTrace::SearchResult result,
                           ApiTraceCall *call);
index 500d859aa3f6d73011acc0bbaabd38a58ed19287..251028ce5ab316066dcfd8baac94a6376a91eb5b 100644 (file)
@@ -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<RetraceError>&)),
-            this, SIGNAL(retraceErrors(const QList<RetraceError>&)));
+    connect(retrace, SIGNAL(retraceErrors(const QList<ApiTraceError>&)),
+            this, SIGNAL(retraceErrors(const QList<ApiTraceError>&)));
 
     retrace->start();
 
@@ -163,11 +163,11 @@ void RetraceProcess::replayFinished()
     }
 
     QStringList errorLines = errStr.split('\n');
-    QList<RetraceError> errors;
+    QList<ApiTraceError> 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<RetraceError>);
+Q_DECLARE_METATYPE(QList<ApiTraceError>);
 RetraceProcess::RetraceProcess(QObject *parent)
     : QObject(parent)
 {
     m_process = new QProcess(this);
     m_jsonParser = new QJson::Parser();
 
-    qRegisterMetaType<QList<RetraceError> >();
+    qRegisterMetaType<QList<ApiTraceError> >();
 
     connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
             this, SLOT(replayFinished()));
index 70170f5ce4605949789083d555ab76307976df7e..4a43c261d7ec10ad1442b909e7414aa63866dd2b 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef RETRACER_H
 #define RETRACER_H
 
+#include "apitracecall.h"
+
 #include <QThread>
 #include <QProcess>
 
@@ -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<RetraceError> &errors);
+    void retraceErrors(const QList<ApiTraceError> &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<RetraceError> &errors);
+    void retraceErrors(const QList<ApiTraceError> &errors);
 
 protected:
     virtual void run();