#include "traceloader.h"
#include "saverthread.h"
+#include <QDebug>
#include <QDir>
#include <QThread>
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(frameLoaded(int,QVector<ApiTraceCall*>,quint64)),
- this, SLOT(fillFrame(int,QVector<ApiTraceCall*>,quint64)));
+ connect(m_loader, SIGNAL(frameLoaded(ApiTraceFrame*)),
+ this, SIGNAL(frameLoaded(ApiTraceFrame*)));
connect(m_loader, SIGNAL(startedParsing()),
this, SIGNAL(startedLoadingTrace()));
return m_calls;
}
-ApiTraceCall * ApiTrace::callAt(int idx) const
-{
- return m_calls.value(idx);
-}
-
int ApiTrace::numCalls() const
{
return m_calls.count();
return !m_errors.isEmpty();
}
-void ApiTrace::fillFrame(int frameIdx, const QVector<ApiTraceCall *> &calls,
- quint64 binaryDataSize)
+void ApiTrace::loadFrame(ApiTraceFrame *frame)
{
+ Q_ASSERT(!frame->loaded());
+ emit requestFrame(frame);
}
#include "apitrace.moc"
ApiTraceState defaultState() const;
QVector<ApiTraceCall*> calls() const;
- ApiTraceCall *callAt(int idx) const;
ApiTraceCall *callWithIndex(int idx) const;
int numCalls() const;
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();
void changed(ApiTraceCall *call);
void startedSaving();
void saved();
+ void frameLoaded(ApiTraceFrame *frame);
void beginAddingFrames(int oldCount, int numAdded);
void endAddingFrames();
private slots:
void addFrames(const QList<ApiTraceFrame*> &frames);
- void fillFrame(int frameIdx, const QVector<ApiTraceCall*> &calls,
- quint64 binaryDataSize);
void slotSaved();
private:
void detectFrames();
int ApiTraceFrame::numChildren() const
{
- if (m_loaded) {
- return m_calls.count();
- } else {
- return m_callsToLoad;
- }
+ return m_calls.count();
}
ApiTrace * ApiTraceFrame::parentTrace() 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
{
m_parentTrace = parent;
}
+
+int ApiTraceFrame::numChildrenToLoad() const
+{
+ return m_callsToLoad;
+}
void setNumChildren(int num);
int numChildren() const;
+ int numChildrenToLoad() const;
QStaticText staticText() const;
int callIndex(ApiTraceCall *call) const;
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
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<ApiTraceFrame*>(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<ApiTraceFrame*>(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 = "<<frame->loaded();
+ qDebug()<<"\tframe idx = "<<frame->number;
+ qDebug()<<"\tis empty = "<<frame->isEmpty();
+ qDebug()<<"\tnum children = "<<frame->numChildren();
+ qDebug()<<"\tindex is "<<index;
+#endif
+
+
+ endInsertRows();
+
+ emit dataChanged(index, index);
+}
+
#include "apitracemodel.moc"
#include <QAbstractItemModel>
#include <QModelIndex>
+#include <QSet>
#include <QVariant>
class ApiTrace;
class ApiTraceCall;
class ApiTraceEvent;
+class ApiTraceFrame;
class ApiTraceModel : public QAbstractItemModel
{
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:
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<ApiTraceFrame*> m_loadingFrames;
};
#endif
#include "traceloader.h"
+#include "apitrace.h"
#include <QDebug>
#include <QFile>
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<ApiTraceCall*> calls(numOfCalls);
const FrameOffset &frameOffset = m_frameOffsets[frameIdx];
- std::vector<Trace::Call*> 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);
}
}
}
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;
public slots:
void loadTrace(const QString &filename);
- void loadFrame(int frameIdx);
+ void loadFrame(ApiTraceFrame *frame);
void setFrameMarker(ApiTrace::FrameMarker marker);
signals:
void finishedParsing();
void framesLoaded(const QList<ApiTraceFrame*> &frames);
- void frameLoaded(int frameIdx,
- const QVector<ApiTraceCall*> &calls,
- quint64 binaryDataSize);
+ void frameLoaded(ApiTraceFrame *frame);
private:
struct FrameOffset {