]> git.cworth.org Git - apitrace/blobdiff - gui/apitrace.cpp
Implement find prev.
[apitrace] / gui / apitrace.cpp
index 4ce4cd423f64873c87abb4477855ec86419c0dcd..51520c5e85df38cb2305914b7e798e714355cadc 100644 (file)
@@ -1,31 +1,63 @@
 #include "apitrace.h"
 
-#include "loaderthread.h"
+#include "traceloader.h"
 #include "saverthread.h"
 
+#include <QDebug>
 #include <QDir>
+#include <QThread>
 
 ApiTrace::ApiTrace()
     : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
       m_needsSaving(false)
 {
-    m_loader = new LoaderThread(this);
-    connect(m_loader, SIGNAL(parsedFrames(const QList<ApiTraceFrame*>)),
+    m_loader = new TraceLoader();
+
+    connect(this, SIGNAL(loadTrace(QString)),
+            m_loader, SLOT(loadTrace(QString)));
+    connect(this, SIGNAL(requestFrame(ApiTraceFrame*)),
+            m_loader, SLOT(loadFrame(ApiTraceFrame*)));
+    connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
             this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
-    connect(m_loader, SIGNAL(started()),
+    connect(m_loader,
+            SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)),
+            this,
+            SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)));
+    connect(m_loader, SIGNAL(finishedParsing()),
+            this, SLOT(finishedParsing()));
+    connect(this, SIGNAL(loaderSearchNext(int,QString,Qt::CaseSensitivity)),
+            m_loader, SLOT(searchNext(int,QString,Qt::CaseSensitivity)));
+    connect(this, SIGNAL(loaderSearchPrev(int,QString,Qt::CaseSensitivity)),
+            m_loader, SLOT(searchPrev(int,QString,Qt::CaseSensitivity)));
+    connect(m_loader,
+            SIGNAL(searchResult(ApiTrace::SearchResult,ApiTraceCall*)),
+            this,
+            SLOT(loaderSearchResult(ApiTrace::SearchResult,ApiTraceCall*)));
+
+
+    connect(m_loader, SIGNAL(startedParsing()),
             this, SIGNAL(startedLoadingTrace()));
-    connect(m_loader, SIGNAL(finished()),
+    connect(m_loader, SIGNAL(parsed(int)),
+            this, SIGNAL(loaded(int)));
+    connect(m_loader, SIGNAL(finishedParsing()),
             this, SIGNAL(finishedLoadingTrace()));
 
+
     m_saver = new SaverThread(this);
     connect(m_saver, SIGNAL(traceSaved()),
             this, SLOT(slotSaved()));
     connect(m_saver, SIGNAL(traceSaved()),
             this, SIGNAL(saved()));
+
+    m_loaderThread = new QThread();
+    m_loader->moveToThread(m_loaderThread);
+    m_loaderThread->start();
 }
 
 ApiTrace::~ApiTrace()
 {
+    m_loaderThread->quit();
+    m_loaderThread->deleteLater();
     qDeleteAll(m_calls);
     qDeleteAll(m_frames);
     delete m_loader;
@@ -40,7 +72,9 @@ bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
 
     switch (marker) {
     case FrameMarker_SwapBuffers:
-        return call->name().contains(QLatin1String("SwapBuffers"));
+        return call->name().contains(QLatin1String("SwapBuffers")) ||
+               call->name() == QLatin1String("CGLFlushDrawable") ||
+               call->name() == QLatin1String("glFrameTerminatorGREMEDY");
     case FrameMarker_Flush:
         return call->name() == QLatin1String("glFlush");
     case FrameMarker_Finish:
@@ -72,16 +106,11 @@ ApiTrace::FrameMarker ApiTrace::frameMarker() const
     return m_frameMarker;
 }
 
-QList<ApiTraceCall*> ApiTrace::calls() const
+QVector<ApiTraceCall*> ApiTrace::calls() const
 {
     return m_calls;
 }
 
-ApiTraceCall * ApiTrace::callAt(int idx) const
-{
-    return m_calls.value(idx);
-}
-
 int ApiTrace::numCalls() const
 {
     return m_calls.count();
@@ -106,7 +135,7 @@ int ApiTrace::numCallsInFrame(int idx) const
 {
     const ApiTraceFrame *frame = frameAt(idx);
     if (frame)
-        return frame->calls.count();
+        return frame->numChildren();
     else
         return 0;
 }
@@ -116,15 +145,15 @@ void ApiTrace::setFileName(const QString &name)
     if (m_fileName != name) {
         m_fileName = name;
 
-        if (m_loader->isRunning()) {
-            m_loader->terminate();
-            m_loader->wait();
-        }
         m_frames.clear();
         m_calls.clear();
+        m_errors.clear();
+        m_editedCalls.clear();
+        m_needsSaving = false;
         emit invalidated();
 
-        m_loader->loadFile(m_fileName);
+//        m_loader->loadTrace(m_fileName);
+        emit loadTrace(m_fileName);
     }
 }
 
@@ -141,19 +170,25 @@ void ApiTrace::setFrameMarker(FrameMarker marker)
 
 void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
 {
+    QVector<ApiTraceCall*> calls;
     int currentFrames = m_frames.count();
     int numNewFrames = frames.count();
+
+    emit beginAddingFrames(currentFrames, numNewFrames);
+
     m_frames += frames;
 
     int currentCalls = m_calls.count();
     int numNewCalls = 0;
     foreach(ApiTraceFrame *frame, frames) {
         frame->setParentTrace(this);
-        numNewCalls += frame->calls.count();
-        m_calls += frame->calls;
+        numNewCalls += frame->numChildren();
+        calls += frame->calls();
     }
+    m_calls.reserve(m_calls.count() + calls.count() + 1);
+    m_calls += calls;
 
-    emit framesAdded(currentFrames, numNewFrames);
+    emit endAddingFrames();
     emit callsAdded(currentCalls, numNewCalls);
 }
 
@@ -162,15 +197,17 @@ void ApiTrace::detectFrames()
     if (m_calls.isEmpty())
         return;
 
+    emit beginAddingFrames(0, m_frames.count());
+
     ApiTraceFrame *currentFrame = 0;
     foreach(ApiTraceCall *apiCall, m_calls) {
         if (!currentFrame) {
-            currentFrame = new ApiTraceFrame();
-            currentFrame->setParentTrace(this);
+            currentFrame = new ApiTraceFrame(this);
             currentFrame->number = m_frames.count();
+            currentFrame->setLoaded(true);
         }
         apiCall->setParentFrame(currentFrame);
-        currentFrame->calls.append(apiCall);
+        currentFrame->addCall(apiCall);
         if (ApiTrace::isCallAFrameMarker(apiCall,
                                          m_frameMarker)) {
             m_frames.append(currentFrame);
@@ -184,7 +221,7 @@ void ApiTrace::detectFrames()
         m_frames.append(currentFrame);
         currentFrame = 0;
     }
-    emit framesAdded(0, m_frames.count());
+    emit endAddingFrames();
 }
 
 ApiTraceCall * ApiTrace::callWithIndex(int idx) const
@@ -200,10 +237,10 @@ ApiTraceCall * ApiTrace::callWithIndex(int idx) const
 ApiTraceState ApiTrace::defaultState() const
 {
     ApiTraceFrame *frame = frameAt(0);
-    if (!frame)
+    if (!frame || !frame->hasState())
         return ApiTraceState();
 
-    return frame->state();
+    return *frame->state();
 }
 
 void ApiTrace::callEdited(ApiTraceCall *call)
@@ -260,4 +297,125 @@ 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();
+}
+
+void ApiTrace::loadFrame(ApiTraceFrame *frame)
+{
+    Q_ASSERT(!frame->loaded());
+    emit requestFrame(frame);
+}
+
+void ApiTrace::finishedParsing()
+{
+    ApiTraceFrame *firstFrame = m_frames[0];
+    if (firstFrame && !firstFrame->loaded()) {
+        loadFrame(firstFrame);
+    }
+}
+
+void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
+                                 const QVector<ApiTraceCall*> &calls,
+                                 quint64 binaryDataSize)
+{
+    Q_ASSERT(frame->numChildrenToLoad() == calls.size());
+    emit beginLoadingFrame(frame, calls.size());
+    frame->setCalls(calls, binaryDataSize);
+    emit endLoadingFrame(frame);
+}
+
+void ApiTrace::findNext(ApiTraceFrame *frame,
+                        ApiTraceCall *from,
+                        const QString &str,
+                        Qt::CaseSensitivity sensitivity)
+{
+    ApiTraceCall *foundCall = 0;
+    int frameIdx = m_frames.indexOf(frame);
+
+    if (frame->loaded()) {
+        foundCall = frame->findNextCall(from, str, sensitivity);
+        if (foundCall) {
+            emit findResult(SearchFound, foundCall);
+            return;
+        }
+
+        //if the frame is loaded we already searched it above
+        // so skip it
+        frameIdx += 1;
+    }
+
+    for (int i = frameIdx; i < m_frames.count(); ++i) {
+        ApiTraceFrame *frame = m_frames[i];
+        if (!frame->loaded()) {
+            emit loaderSearchNext(i, str, sensitivity);
+            return;
+        } else {
+            ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
+            if (call) {
+                emit findResult(SearchFound, call);
+                return;
+            }
+        }
+    }
+    emit findResult(SearchWrapped, 0);
+}
+
+void ApiTrace::findPrev(ApiTraceFrame *frame,
+                        ApiTraceCall *from,
+                        const QString &str,
+                        Qt::CaseSensitivity sensitivity)
+{
+    ApiTraceCall *foundCall = 0;
+    int frameIdx = m_frames.indexOf(frame);
+
+    if (frame->loaded()) {
+        foundCall = frame->findPrevCall(from, str, sensitivity);
+        if (foundCall) {
+            emit findResult(SearchFound, foundCall);
+            return;
+        }
+
+        //if the frame is loaded we already searched it above
+        // so skip it
+        frameIdx -= 1;
+    }
+
+    for (int i = frameIdx; i >= 0; --i) {
+        ApiTraceFrame *frame = m_frames[i];
+        if (!frame->loaded()) {
+            emit loaderSearchPrev(i, str, sensitivity);
+            return;
+        } else {
+            ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
+            if (call) {
+                emit findResult(SearchFound, call);
+                return;
+            }
+        }
+    }
+    emit findResult(SearchWrapped, 0);
+}
+
+void ApiTrace::loaderSearchResult(ApiTrace::SearchResult result,
+                                  ApiTraceCall *call)
+{
+    //qDebug()<<"Search result = "<<result
+    //       <<", call is = "<<call;
+    emit findResult(result, call);
+}
+
 #include "apitrace.moc"