blob: 023a094a93f2e2867117d3861153e1f4735b90c0 [file] [log] [blame]
Zack Rusinf6667d12011-03-30 11:03:37 -04001#include "apitrace.h"
2
Zack Rusinebf971e2011-09-06 17:44:43 -04003#include "traceloader.h"
Zack Rusind809a062011-04-17 23:30:58 -04004#include "saverthread.h"
Zack Rusinf6667d12011-03-30 11:03:37 -04005
Zack Rusin3176ebe2011-09-06 21:11:36 -04006#include <QDebug>
Zack Rusin63efea82011-04-17 17:10:45 -04007#include <QDir>
Zack Rusinebf971e2011-09-06 17:44:43 -04008#include <QThread>
Zack Rusin63efea82011-04-17 17:10:45 -04009
Zack Rusinf6667d12011-03-30 11:03:37 -040010ApiTrace::ApiTrace()
Zack Rusin63efea82011-04-17 17:10:45 -040011 : m_frameMarker(ApiTrace::FrameMarker_SwapBuffers),
12 m_needsSaving(false)
Zack Rusinf6667d12011-03-30 11:03:37 -040013{
Zack Rusinebf971e2011-09-06 17:44:43 -040014 m_loader = new TraceLoader();
Zack Rusinf682e192011-09-07 01:36:41 -040015
Zack Rusinebf971e2011-09-06 17:44:43 -040016 connect(this, SIGNAL(loadTrace(QString)),
17 m_loader, SLOT(loadTrace(QString)));
Zack Rusin3176ebe2011-09-06 21:11:36 -040018 connect(this, SIGNAL(requestFrame(ApiTraceFrame*)),
19 m_loader, SLOT(loadFrame(ApiTraceFrame*)));
Zack Rusinebf971e2011-09-06 17:44:43 -040020 connect(m_loader, SIGNAL(framesLoaded(const QList<ApiTraceFrame*>)),
Zack Rusinf6667d12011-03-30 11:03:37 -040021 this, SLOT(addFrames(const QList<ApiTraceFrame*>)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040022 connect(m_loader,
23 SIGNAL(frameContentsLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)),
24 this,
25 SLOT(loaderFrameLoaded(ApiTraceFrame*,QVector<ApiTraceCall*>,quint64)));
Zack Rusinf682e192011-09-07 01:36:41 -040026 connect(m_loader, SIGNAL(finishedParsing()),
27 this, SLOT(finishedParsing()));
Zack Rusinad513b32011-09-25 14:33:41 -040028 connect(this, SIGNAL(loaderSearch(ApiTrace::SearchRequest)),
29 m_loader, SLOT(search(ApiTrace::SearchRequest)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040030 connect(m_loader,
Zack Rusinad513b32011-09-25 14:33:41 -040031 SIGNAL(searchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)),
Zack Rusin8f98c3a2011-09-11 18:21:29 -040032 this,
Zack Rusinad513b32011-09-25 14:33:41 -040033 SLOT(loaderSearchResult(ApiTrace::SearchRequest,ApiTrace::SearchResult,ApiTraceCall*)));
Zack Rusin93e4d152011-09-13 02:23:39 -040034 connect(this, SIGNAL(loaderFindFrameStart(ApiTraceFrame*)),
35 m_loader, SLOT(findFrameStart(ApiTraceFrame*)));
36 connect(this, SIGNAL(loaderFindFrameEnd(ApiTraceFrame*)),
37 m_loader, SLOT(findFrameEnd(ApiTraceFrame*)));
38 connect(m_loader, SIGNAL(foundFrameStart(ApiTraceFrame*)),
39 this, SIGNAL(foundFrameStart(ApiTraceFrame*)));
40 connect(m_loader, SIGNAL(foundFrameEnd(ApiTraceFrame*)),
41 this, SIGNAL(foundFrameEnd(ApiTraceFrame*)));
Zack Rusinda7579b2011-09-13 17:33:05 -040042 connect(this, SIGNAL(loaderFindCallIndex(int)),
43 m_loader, SLOT(findCallIndex(int)));
44 connect(m_loader, SIGNAL(foundCallIndex(ApiTraceCall*)),
45 this, SIGNAL(foundCallIndex(ApiTraceCall*)));
Zack Rusin8f98c3a2011-09-11 18:21:29 -040046
Zack Rusinebf971e2011-09-06 17:44:43 -040047
48 connect(m_loader, SIGNAL(startedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040049 this, SIGNAL(startedLoadingTrace()));
Zack Rusinebf971e2011-09-06 17:44:43 -040050 connect(m_loader, SIGNAL(parsed(int)),
51 this, SIGNAL(loaded(int)));
52 connect(m_loader, SIGNAL(finishedParsing()),
Zack Rusinde4ea412011-03-30 11:30:08 -040053 this, SIGNAL(finishedLoadingTrace()));
Zack Rusind809a062011-04-17 23:30:58 -040054
Zack Rusinebf971e2011-09-06 17:44:43 -040055
Zack Rusind809a062011-04-17 23:30:58 -040056 m_saver = new SaverThread(this);
Zack Rusin9af5bff2011-04-18 01:05:50 -040057 connect(m_saver, SIGNAL(traceSaved()),
58 this, SLOT(slotSaved()));
59 connect(m_saver, SIGNAL(traceSaved()),
60 this, SIGNAL(saved()));
Zack Rusinebf971e2011-09-06 17:44:43 -040061
62 m_loaderThread = new QThread();
63 m_loader->moveToThread(m_loaderThread);
64 m_loaderThread->start();
Zack Rusinf6667d12011-03-30 11:03:37 -040065}
66
67ApiTrace::~ApiTrace()
68{
Zack Rusinebf971e2011-09-06 17:44:43 -040069 m_loaderThread->quit();
70 m_loaderThread->deleteLater();
Zack Rusinf6667d12011-03-30 11:03:37 -040071 qDeleteAll(m_frames);
72 delete m_loader;
Zack Rusind809a062011-04-17 23:30:58 -040073 delete m_saver;
Zack Rusinf6667d12011-03-30 11:03:37 -040074}
75
76bool ApiTrace::isCallAFrameMarker(const ApiTraceCall *call,
77 ApiTrace::FrameMarker marker)
78{
Zack Rusinc5929572011-09-19 03:04:40 -040079 if (!call) {
Zack Rusinf6667d12011-03-30 11:03:37 -040080 return false;
Zack Rusinc5929572011-09-19 03:04:40 -040081 }
Zack Rusinf6667d12011-03-30 11:03:37 -040082
83 switch (marker) {
84 case FrameMarker_SwapBuffers:
José Fonseca3e9ff852011-06-06 19:37:09 +010085 return call->name().contains(QLatin1String("SwapBuffers")) ||
José Fonsecadb678122011-07-29 17:20:05 +010086 call->name() == QLatin1String("CGLFlushDrawable") ||
87 call->name() == QLatin1String("glFrameTerminatorGREMEDY");
Zack Rusinf6667d12011-03-30 11:03:37 -040088 case FrameMarker_Flush:
Zack Rusinead6aad2011-04-15 22:16:18 -040089 return call->name() == QLatin1String("glFlush");
Zack Rusinf6667d12011-03-30 11:03:37 -040090 case FrameMarker_Finish:
Zack Rusinead6aad2011-04-15 22:16:18 -040091 return call->name() == QLatin1String("glFinish");
Zack Rusinf6667d12011-03-30 11:03:37 -040092 case FrameMarker_Clear:
Zack Rusinead6aad2011-04-15 22:16:18 -040093 return call->name() == QLatin1String("glClear");
Zack Rusinf6667d12011-03-30 11:03:37 -040094 }
95
96 Q_ASSERT(!"unknown frame marker");
97
98 return false;
99}
100
101bool ApiTrace::isEmpty() const
102{
Zack Rusinc1743432011-09-13 17:58:58 -0400103 return m_frames.isEmpty();
Zack Rusinf6667d12011-03-30 11:03:37 -0400104}
105
106QString ApiTrace::fileName() const
107{
Zack Rusinc5929572011-09-19 03:04:40 -0400108 if (edited()) {
Zack Rusin63efea82011-04-17 17:10:45 -0400109 return m_tempFileName;
Zack Rusinc5929572011-09-19 03:04:40 -0400110 }
Zack Rusin63efea82011-04-17 17:10:45 -0400111
Zack Rusinf6667d12011-03-30 11:03:37 -0400112 return m_fileName;
113}
114
115ApiTrace::FrameMarker ApiTrace::frameMarker() const
116{
117 return m_frameMarker;
118}
119
Zack Rusinf6667d12011-03-30 11:03:37 -0400120QList<ApiTraceFrame*> ApiTrace::frames() const
121{
122 return m_frames;
123}
124
125ApiTraceFrame * ApiTrace::frameAt(int idx) const
126{
127 return m_frames.value(idx);
128}
129
130int ApiTrace::numFrames() const
131{
132 return m_frames.count();
133}
134
135int ApiTrace::numCallsInFrame(int idx) const
136{
137 const ApiTraceFrame *frame = frameAt(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400138 if (frame) {
Zack Rusin1d31b6c2011-04-26 22:30:25 -0400139 return frame->numChildren();
Zack Rusinc5929572011-09-19 03:04:40 -0400140 } else {
Zack Rusinf6667d12011-03-30 11:03:37 -0400141 return 0;
Zack Rusinc5929572011-09-19 03:04:40 -0400142 }
Zack Rusinf6667d12011-03-30 11:03:37 -0400143}
144
145void ApiTrace::setFileName(const QString &name)
146{
147 if (m_fileName != name) {
148 m_fileName = name;
Zack Rusindaf82af2011-09-24 13:42:53 -0400149 m_tempFileName = QString();
Zack Rusinf6667d12011-03-30 11:03:37 -0400150
Zack Rusinca164112011-04-11 02:23:09 -0400151 m_frames.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400152 m_errors.clear();
153 m_editedCalls.clear();
Zack Rusindaf82af2011-09-24 13:42:53 -0400154 m_queuedErrors.clear();
Zack Rusin30069572011-04-20 18:21:11 -0400155 m_needsSaving = false;
Zack Rusinf6667d12011-03-30 11:03:37 -0400156 emit invalidated();
157
Zack Rusinebf971e2011-09-06 17:44:43 -0400158 emit loadTrace(m_fileName);
Zack Rusinf6667d12011-03-30 11:03:37 -0400159 }
160}
161
Zack Rusinf6667d12011-03-30 11:03:37 -0400162void ApiTrace::addFrames(const QList<ApiTraceFrame*> &frames)
163{
164 int currentFrames = m_frames.count();
165 int numNewFrames = frames.count();
Zack Rusinb56e03d2011-04-20 23:58:52 -0400166
167 emit beginAddingFrames(currentFrames, numNewFrames);
168
Zack Rusinf6667d12011-03-30 11:03:37 -0400169 m_frames += frames;
170
Zack Rusinf6667d12011-03-30 11:03:37 -0400171 foreach(ApiTraceFrame *frame, frames) {
Zack Rusinebf971e2011-09-06 17:44:43 -0400172 frame->setParentTrace(this);
Zack Rusinf6667d12011-03-30 11:03:37 -0400173 }
174
Zack Rusinb56e03d2011-04-20 23:58:52 -0400175 emit endAddingFrames();
Zack Rusinf6667d12011-03-30 11:03:37 -0400176}
177
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400178ApiTraceCall * ApiTrace::callWithIndex(int idx) const
179{
Zack Rusinc1743432011-09-13 17:58:58 -0400180 for (int i = 0; i < m_frames.count(); ++i) {
181 ApiTraceCall *call = m_frames[i]->callWithIndex(idx);
Zack Rusinc5929572011-09-19 03:04:40 -0400182 if (call) {
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400183 return call;
Zack Rusinc5929572011-09-19 03:04:40 -0400184 }
Zack Rusinf04cf8a2011-04-12 23:21:52 -0400185 }
186 return NULL;
187}
188
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400189ApiTraceState ApiTrace::defaultState() const
190{
191 ApiTraceFrame *frame = frameAt(0);
Zack Rusinc5929572011-09-19 03:04:40 -0400192 if (!frame || !frame->isLoaded() || frame->isEmpty()) {
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400193 return ApiTraceState();
Zack Rusinc5929572011-09-19 03:04:40 -0400194 }
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400195
Zack Rusin851d0b02011-09-14 22:04:07 -0400196 ApiTraceCall *firstCall = frame->calls().first();
197 if (!firstCall->hasState()) {
198 return ApiTraceState();
199 }
200
201 return *firstCall->state();
Zack Rusine2dfa2e2011-04-13 01:35:03 -0400202}
203
Zack Rusin661842d2011-04-17 01:59:16 -0400204void ApiTrace::callEdited(ApiTraceCall *call)
205{
Zack Rusin63efea82011-04-17 17:10:45 -0400206 if (!m_editedCalls.contains(call)) {
207 //lets generate a temp filename
208 QString tempPath = QDir::tempPath();
Zack Rusin63efea82011-04-17 17:10:45 -0400209 m_tempFileName = QString::fromLatin1("%1/%2.edited")
210 .arg(tempPath)
211 .arg(m_fileName);
Zack Rusin63efea82011-04-17 17:10:45 -0400212 }
Zack Rusin661842d2011-04-17 01:59:16 -0400213 m_editedCalls.insert(call);
Zack Rusin9af5bff2011-04-18 01:05:50 -0400214 m_needsSaving = true;
Zack Rusin63efea82011-04-17 17:10:45 -0400215
Zack Rusin661842d2011-04-17 01:59:16 -0400216 emit changed(call);
217}
218
219void ApiTrace::callReverted(ApiTraceCall *call)
220{
221 m_editedCalls.remove(call);
Zack Rusin63efea82011-04-17 17:10:45 -0400222
223 if (m_editedCalls.isEmpty()) {
224 m_needsSaving = false;
225 }
Zack Rusin661842d2011-04-17 01:59:16 -0400226 emit changed(call);
227}
228
Zack Rusin0ddd2502011-04-17 02:34:45 -0400229bool ApiTrace::edited() const
Zack Rusin661842d2011-04-17 01:59:16 -0400230{
231 return !m_editedCalls.isEmpty();
232}
233
Zack Rusin63efea82011-04-17 17:10:45 -0400234bool ApiTrace::needsSaving() const
235{
236 return m_needsSaving;
237}
238
239void ApiTrace::save()
240{
241 QFileInfo fi(m_tempFileName);
242 QDir dir;
Zack Rusin9af5bff2011-04-18 01:05:50 -0400243 emit startedSaving();
Zack Rusin63efea82011-04-17 17:10:45 -0400244 dir.mkpath(fi.absolutePath());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400245 m_saver->saveFile(m_tempFileName,
246 m_fileName,
247 m_editedCalls);
Zack Rusin63efea82011-04-17 17:10:45 -0400248}
249
Zack Rusin9af5bff2011-04-18 01:05:50 -0400250void ApiTrace::slotSaved()
251{
252 m_needsSaving = false;
253}
254
255bool ApiTrace::isSaving() const
256{
257 return m_saver->isRunning();
258}
259
Zack Rusincc0b4912011-04-19 01:59:20 -0400260bool ApiTrace::hasErrors() const
261{
262 return !m_errors.isEmpty();
263}
264
Zack Rusin3176ebe2011-09-06 21:11:36 -0400265void ApiTrace::loadFrame(ApiTraceFrame *frame)
Zack Rusinac4dd9a2011-08-28 00:38:13 -0400266{
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400267 Q_ASSERT(!frame->isLoaded());
Zack Rusin3176ebe2011-09-06 21:11:36 -0400268 emit requestFrame(frame);
Zack Rusin35c27932011-08-28 21:16:22 -0400269}
270
Zack Rusinf682e192011-09-07 01:36:41 -0400271void ApiTrace::finishedParsing()
272{
273 ApiTraceFrame *firstFrame = m_frames[0];
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400274 if (firstFrame && !firstFrame->isLoaded()) {
Zack Rusinf682e192011-09-07 01:36:41 -0400275 loadFrame(firstFrame);
276 }
277}
278
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400279void ApiTrace::loaderFrameLoaded(ApiTraceFrame *frame,
280 const QVector<ApiTraceCall*> &calls,
281 quint64 binaryDataSize)
Zack Rusinf682e192011-09-07 01:36:41 -0400282{
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400283 Q_ASSERT(frame->numChildrenToLoad() == calls.size());
284 emit beginLoadingFrame(frame, calls.size());
285 frame->setCalls(calls, binaryDataSize);
Zack Rusinf682e192011-09-07 01:36:41 -0400286 emit endLoadingFrame(frame);
Zack Rusin10fd4772011-09-14 01:45:12 -0400287
288 if (!m_queuedErrors.isEmpty()) {
289 QList< QPair<ApiTraceFrame*, ApiTraceError> >::iterator itr;
290 for (itr = m_queuedErrors.begin(); itr != m_queuedErrors.end();
291 ++itr) {
292 const ApiTraceError &error = (*itr).second;
293 if ((*itr).first == frame) {
294 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
295
296 if (!call) {
297 continue;
298 }
299
300 call->setError(error.message);
301 m_queuedErrors.erase(itr);
302
303 if (call->hasError()) {
304 m_errors.insert(call);
305 } else {
306 m_errors.remove(call);
307 }
308 emit changed(call);
309 }
310 }
311 }
Zack Rusinf682e192011-09-07 01:36:41 -0400312}
313
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400314void ApiTrace::findNext(ApiTraceFrame *frame,
315 ApiTraceCall *from,
316 const QString &str,
317 Qt::CaseSensitivity sensitivity)
318{
319 ApiTraceCall *foundCall = 0;
320 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400321 SearchRequest request(SearchRequest::Next,
322 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400323
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400324 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400325 foundCall = frame->findNextCall(from, str, sensitivity);
326 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400327 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400328 return;
329 }
330
331 //if the frame is loaded we already searched it above
332 // so skip it
333 frameIdx += 1;
334 }
335
Zack Rusinad513b32011-09-25 14:33:41 -0400336 //for the rest of the frames we search from beginning
337 request.from = 0;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400338 for (int i = frameIdx; i < m_frames.count(); ++i) {
339 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400340 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400341 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400342 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400343 return;
344 } else {
345 ApiTraceCall *call = frame->findNextCall(0, str, sensitivity);
346 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400347 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400348 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400349 }
350 }
351 }
Zack Rusinad513b32011-09-25 14:33:41 -0400352 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400353}
354
355void ApiTrace::findPrev(ApiTraceFrame *frame,
356 ApiTraceCall *from,
357 const QString &str,
358 Qt::CaseSensitivity sensitivity)
359{
360 ApiTraceCall *foundCall = 0;
361 int frameIdx = m_frames.indexOf(frame);
Zack Rusinad513b32011-09-25 14:33:41 -0400362 SearchRequest request(SearchRequest::Prev,
363 frame, from, str, sensitivity);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400364
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400365 if (frame->isLoaded()) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400366 foundCall = frame->findPrevCall(from, str, sensitivity);
367 if (foundCall) {
Zack Rusinad513b32011-09-25 14:33:41 -0400368 emit findResult(request, SearchResult_Found, foundCall);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400369 return;
370 }
371
372 //if the frame is loaded we already searched it above
373 // so skip it
374 frameIdx -= 1;
375 }
376
Zack Rusinad513b32011-09-25 14:33:41 -0400377 request.from = 0;
Zack Rusin121e3162011-09-13 01:35:12 -0400378 for (int i = frameIdx; i >= 0; --i) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400379 ApiTraceFrame *frame = m_frames[i];
Zack Rusinad513b32011-09-25 14:33:41 -0400380 request.frame = frame;
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400381 if (!frame->isLoaded()) {
Zack Rusinad513b32011-09-25 14:33:41 -0400382 emit loaderSearch(request);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400383 return;
384 } else {
385 ApiTraceCall *call = frame->findPrevCall(0, str, sensitivity);
386 if (call) {
Zack Rusinad513b32011-09-25 14:33:41 -0400387 emit findResult(request, SearchResult_Found, call);
Zack Rusin121e3162011-09-13 01:35:12 -0400388 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400389 }
390 }
391 }
Zack Rusinad513b32011-09-25 14:33:41 -0400392 emit findResult(request, SearchResult_Wrapped, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400393}
394
Zack Rusinad513b32011-09-25 14:33:41 -0400395void ApiTrace::loaderSearchResult(const ApiTrace::SearchRequest &request,
396 ApiTrace::SearchResult result,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400397 ApiTraceCall *call)
398{
399 //qDebug()<<"Search result = "<<result
400 // <<", call is = "<<call;
Zack Rusinad513b32011-09-25 14:33:41 -0400401 emit findResult(request, result, call);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400402}
403
Zack Rusin93e4d152011-09-13 02:23:39 -0400404void ApiTrace::findFrameStart(ApiTraceFrame *frame)
405{
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400406 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400407 emit foundFrameStart(frame);
408 } else {
409 emit loaderFindFrameStart(frame);
410 }
411}
412
413void ApiTrace::findFrameEnd(ApiTraceFrame *frame)
414{
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400415 if (frame->isLoaded()) {
Zack Rusin93e4d152011-09-13 02:23:39 -0400416 emit foundFrameEnd(frame);
417 } else {
418 emit loaderFindFrameEnd(frame);
419 }
420}
421
Zack Rusinda7579b2011-09-13 17:33:05 -0400422void ApiTrace::findCallIndex(int index)
423{
424 int frameIdx = callInFrame(index);
425 ApiTraceFrame *frame = 0;
426
427 if (frameIdx < 0) {
428 emit foundCallIndex(0);
429 return;
430 }
431
432 frame = m_frames[frameIdx];
433
434 if (frame) {
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400435 if (frame->isLoaded()) {
Zack Rusinda7579b2011-09-13 17:33:05 -0400436 ApiTraceCall *call = frame->callWithIndex(index);
437 emit foundCallIndex(call);
438 } else {
439 emit loaderFindCallIndex(index);
440 }
441 }
442}
443
444int ApiTrace::callInFrame(int callIdx) const
445{
446 unsigned numCalls = 0;
447
448 for (int frameIdx = 0; frameIdx <= m_frames.size(); ++frameIdx) {
449 const ApiTraceFrame *frame = m_frames[frameIdx];
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400450 unsigned numCallsInFrame = frame->isLoaded()
Zack Rusinda7579b2011-09-13 17:33:05 -0400451 ? frame->numChildren()
452 : frame->numChildrenToLoad();
453 unsigned firstCall = numCalls;
454 unsigned endCall = numCalls + numCallsInFrame;
455 if (firstCall <= callIdx && endCall > callIdx) {
456 return frameIdx;
457 }
458 numCalls = endCall;
459 }
460
461 return -1;
462}
463
Zack Rusin10fd4772011-09-14 01:45:12 -0400464void ApiTrace::setCallError(const ApiTraceError &error)
465{
466 int frameIdx = callInFrame(error.callIndex);
467 ApiTraceFrame *frame = 0;
468
469 if (frameIdx < 0) {
470 return;
471 }
472 frame = m_frames[frameIdx];
473
Zack Rusin1a9f7af2011-09-18 19:40:47 -0400474 if (frame->isLoaded()) {
Zack Rusin10fd4772011-09-14 01:45:12 -0400475 ApiTraceCall *call = frame->callWithIndex(error.callIndex);
476 call->setError(error.message);
477 if (call->hasError()) {
478 m_errors.insert(call);
479 } else {
480 m_errors.remove(call);
481 }
482 emit changed(call);
483 } else {
484 emit requestFrame(frame);
485 m_queuedErrors.append(qMakePair(frame, error));
486 }
487}
488
Zack Rusinf6667d12011-03-30 11:03:37 -0400489#include "apitrace.moc"