From 3176ebeffe825a5f998b13755c09cfa312b0e8d3 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 6 Sep 2011 21:11:36 -0400 Subject: [PATCH] First working on demand loading! searching, editing and state lookups don't work quite yet, but the frames are being loaded on demand. --- gui/apitrace.cpp | 17 +++++++-------- gui/apitrace.h | 6 ++--- gui/apitracecall.cpp | 17 ++++++++++----- gui/apitracecall.h | 1 + gui/apitracemodel.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++ gui/apitracemodel.h | 6 +++++ gui/traceloader.cpp | 34 +++++++++++++++++++++++------ gui/traceloader.h | 6 ++--- 8 files changed, 109 insertions(+), 29 deletions(-) diff --git a/gui/apitrace.cpp b/gui/apitrace.cpp index d6a9e41..2eb6ab5 100644 --- a/gui/apitrace.cpp +++ b/gui/apitrace.cpp @@ -3,6 +3,7 @@ #include "traceloader.h" #include "saverthread.h" +#include #include #include @@ -13,10 +14,12 @@ ApiTrace::ApiTrace() 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)), this, SLOT(addFrames(const QList))); - connect(m_loader, SIGNAL(frameLoaded(int,QVector,quint64)), - this, SLOT(fillFrame(int,QVector,quint64))); + connect(m_loader, SIGNAL(frameLoaded(ApiTraceFrame*)), + this, SIGNAL(frameLoaded(ApiTraceFrame*))); connect(m_loader, SIGNAL(startedParsing()), this, SIGNAL(startedLoadingTrace())); @@ -94,11 +97,6 @@ QVector 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(); @@ -302,9 +300,10 @@ bool ApiTrace::hasErrors() const return !m_errors.isEmpty(); } -void ApiTrace::fillFrame(int frameIdx, const QVector &calls, - quint64 binaryDataSize) +void ApiTrace::loadFrame(ApiTraceFrame *frame) { + Q_ASSERT(!frame->loaded()); + emit requestFrame(frame); } #include "apitrace.moc" diff --git a/gui/apitrace.h b/gui/apitrace.h index 3b737e0..8da0320 100644 --- a/gui/apitrace.h +++ b/gui/apitrace.h @@ -35,7 +35,6 @@ public: ApiTraceState defaultState() const; QVector calls() const; - ApiTraceCall *callAt(int idx) const; ApiTraceCall *callWithIndex(int idx) const; int numCalls() const; @@ -59,9 +58,11 @@ public slots: void setFileName(const QString &name); void setFrameMarker(FrameMarker marker); void save(); + void loadFrame(ApiTraceFrame *frame); signals: void loadTrace(const QString &name); + void requestFrame(ApiTraceFrame *frame); void startedLoadingTrace(); void loaded(int percent); void finishedLoadingTrace(); @@ -70,6 +71,7 @@ signals: void changed(ApiTraceCall *call); void startedSaving(); void saved(); + void frameLoaded(ApiTraceFrame *frame); void beginAddingFrames(int oldCount, int numAdded); void endAddingFrames(); @@ -77,8 +79,6 @@ signals: private slots: void addFrames(const QList &frames); - void fillFrame(int frameIdx, const QVector &calls, - quint64 binaryDataSize); void slotSaved(); private: void detectFrames(); diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index d1de5a8..5925045 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -965,11 +965,7 @@ QStaticText ApiTraceFrame::staticText() const int ApiTraceFrame::numChildren() const { - if (m_loaded) { - return m_calls.count(); - } else { - return m_callsToLoad; - } + return m_calls.count(); } ApiTrace * ApiTraceFrame::parentTrace() const @@ -1004,7 +1000,11 @@ int ApiTraceFrame::callIndex(ApiTraceCall *call) const bool ApiTraceFrame::isEmpty() const { - return m_calls.isEmpty(); + if (m_loaded) { + return m_calls.isEmpty(); + } else { + return m_callsToLoad == 0; + } } int ApiTraceFrame::binaryDataSize() const @@ -1039,3 +1039,8 @@ void ApiTraceFrame::setParentTrace(ApiTrace *parent) { m_parentTrace = parent; } + +int ApiTraceFrame::numChildrenToLoad() const +{ + return m_callsToLoad; +} diff --git a/gui/apitracecall.h b/gui/apitracecall.h index 865f60c..ca4c354 100644 --- a/gui/apitracecall.h +++ b/gui/apitracecall.h @@ -296,6 +296,7 @@ public: void setNumChildren(int num); int numChildren() const; + int numChildrenToLoad() const; QStaticText staticText() const; int callIndex(ApiTraceCall *call) const; diff --git a/gui/apitracemodel.cpp b/gui/apitracemodel.cpp index 800b5c7..a510c43 100644 --- a/gui/apitracemodel.cpp +++ b/gui/apitracemodel.cpp @@ -218,6 +218,8 @@ void ApiTraceModel::setApiTrace(ApiTrace *trace) this, SLOT(endAddingFrames())); connect(m_trace, SIGNAL(changed(ApiTraceCall*)), this, SLOT(callChanged(ApiTraceCall*))); + connect(m_trace, SIGNAL(frameLoaded(ApiTraceFrame*)), + this, SLOT(frameChanged(ApiTraceFrame*))); } const ApiTrace * ApiTraceModel::apiTrace() const @@ -313,4 +315,53 @@ void ApiTraceModel::endAddingFrames() endInsertRows(); } +bool ApiTraceModel::canFetchMore(const QModelIndex &parent) const +{ + if (parent.isValid()) { + ApiTraceEvent *event = item(parent); + if (event && event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); + return !frame->loaded() && !m_loadingFrames.contains(frame); + } else + return false; + } else { + return false; + } +} + +void ApiTraceModel::fetchMore(const QModelIndex &parent) +{ + if (parent.isValid()) { + ApiTraceEvent *event = item(parent); + if (event && event->type() == ApiTraceEvent::Frame) { + ApiTraceFrame *frame = static_cast(event); + QModelIndex index = createIndex(frame->number, 0, frame); + + Q_ASSERT(!frame->loaded()); + m_loadingFrames.insert(frame); + beginInsertRows(index, 0, + frame->numChildrenToLoad() - 1); + + m_trace->loadFrame(frame); + } + } +} + +void ApiTraceModel::frameChanged(ApiTraceFrame *frame) +{ + QModelIndex index = createIndex(frame->number, 0, frame); +#if 0 + qDebug()<<"Frame loaded = "<loaded(); + qDebug()<<"\tframe idx = "<number; + qDebug()<<"\tis empty = "<isEmpty(); + qDebug()<<"\tnum children = "<numChildren(); + qDebug()<<"\tindex is "< #include +#include #include class ApiTrace; class ApiTraceCall; class ApiTraceEvent; +class ApiTraceFrame; class ApiTraceModel : public QAbstractItemModel { @@ -45,6 +47,8 @@ public: const QModelIndex &parent = QModelIndex()); bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + virtual bool canFetchMore(const QModelIndex & parent) const; + virtual void fetchMore(const QModelIndex &parent); /* } QAbstractItemModel; */ private slots: @@ -52,12 +56,14 @@ private slots: void beginAddingFrames(int oldCount, int numAdded); void endAddingFrames(); void callChanged(ApiTraceCall *call); + void frameChanged(ApiTraceFrame *frame); private: ApiTraceEvent *item(const QModelIndex &index) const; private: ApiTrace *m_trace; + QSet m_loadingFrames; }; #endif diff --git a/gui/traceloader.cpp b/gui/traceloader.cpp index b6eba6a..77e8750 100644 --- a/gui/traceloader.cpp +++ b/gui/traceloader.cpp @@ -1,5 +1,6 @@ #include "traceloader.h" +#include "apitrace.h" #include #include @@ -53,30 +54,50 @@ void TraceLoader::loadTrace(const QString &filename) emit finishedParsing(); } -void TraceLoader::loadFrame(int frameIdx) +void TraceLoader::loadFrame(ApiTraceFrame *currentFrame) { if (m_parser.supportsOffsets()) { + unsigned frameIdx = currentFrame->number; int numOfCalls = numberOfCallsInFrame(frameIdx); + if (numOfCalls) { + quint64 binaryDataSize = 0; + QVector calls(numOfCalls); const FrameOffset &frameOffset = m_frameOffsets[frameIdx]; - std::vector calls(numOfCalls); + m_parser.setCurrentOffset(frameOffset.start); m_parser.setCurrentCallNumber(frameOffset.callNumber); Trace::Call *call; int parsedCalls = 0; while ((call = m_parser.parse_call())) { + ApiTraceCall *apiCall = + apiCallFromTraceCall(call, m_helpHash, + currentFrame, this); + calls[parsedCalls] = apiCall; + Q_ASSERT(calls[parsedCalls]); + if (apiCall->hasBinaryData()) { + QByteArray data = + apiCall->arguments()[ + apiCall->binaryDataIndex()].toByteArray(); + binaryDataSize += data.size(); + } - calls[parsedCalls] = call; ++parsedCalls; - if (isCallAFrameMarker(call)) { + delete call; + + if (ApiTrace::isCallAFrameMarker(apiCall, m_frameMarker)) { break; } } assert(parsedCalls == numOfCalls); - // emit parsedFrame(); + Q_ASSERT(parsedCalls == calls.size()); + Q_ASSERT(parsedCalls == currentFrame->numChildrenToLoad()); + calls.squeeze(); + currentFrame->setCalls(calls, binaryDataSize); + emit frameLoaded(currentFrame); } } } @@ -183,12 +204,11 @@ void TraceLoader::scanTrace() callNum = m_parser.currentCallNumber(); numOfCalls = 0; } - //call->dump(std::cout, color); delete call; } if (numOfCalls) { - // Trace::File::Offset endOffset = m_parser.currentOffset(); + //Trace::File::Offset endOffset = m_parser.currentOffset(); FrameOffset frameOffset(startOffset); frameOffset.numberOfCalls = numOfCalls; frameOffset.callNumber = callNum; diff --git a/gui/traceloader.h b/gui/traceloader.h index 32c7f16..791a19c 100644 --- a/gui/traceloader.h +++ b/gui/traceloader.h @@ -26,7 +26,7 @@ public: public slots: void loadTrace(const QString &filename); - void loadFrame(int frameIdx); + void loadFrame(ApiTraceFrame *frame); void setFrameMarker(ApiTrace::FrameMarker marker); signals: @@ -35,9 +35,7 @@ signals: void finishedParsing(); void framesLoaded(const QList &frames); - void frameLoaded(int frameIdx, - const QVector &calls, - quint64 binaryDataSize); + void frameLoaded(ApiTraceFrame *frame); private: struct FrameOffset { -- 2.43.0