1 #include "debugscript.h"
8 void DebugScript::ParseAction(View * view, Screen * scr)
11 if (m_input == NULL || !m_input->good())
13 istream & inp = *m_input;
14 Debug("Get action type...");
15 std::string actionType;
17 Debug("Action type: %s", actionType.c_str());
19 while (actionType[0] == '#')
22 std::getline(inp, tmp);
23 inp >> std::ws >> actionType;
25 if (actionType == "loop")
27 inp >> currentAction.loops >> actionType;
31 currentAction.loops = 1;
34 if (actionType == "wait")
36 currentAction.type = AT_WaitFrame;
39 else if (actionType == "translate")
43 currentAction.type = AT_Translate;
44 currentAction.x = RealFromStr(_x.c_str());
45 currentAction.y = RealFromStr(_y.c_str());
48 else if (actionType == "zoom")
50 std::string _x, _y, _z;
51 inp >> _x >> _y >> _z;
52 currentAction.type = AT_Zoom;
53 currentAction.x = RealFromStr(_x.c_str());
54 currentAction.y = RealFromStr(_y.c_str());
55 currentAction.z = RealFromStr(_z.c_str());
57 else if (actionType == "pxtranslate")
59 inp >> currentAction.ix >> currentAction.iy;
60 currentAction.type = AT_TranslatePx;
62 else if (actionType == "pxzoom")
64 inp >> currentAction.ix >> currentAction.iy >> currentAction.iz;
65 currentAction.type = AT_ZoomPx;
67 else if (actionType == "gpu")
69 currentAction.type = AT_SetGPURendering;
71 else if (actionType == "cpu")
73 currentAction.type = AT_SetCPURendering;
75 else if (actionType == "lazy")
77 currentAction.type = AT_EnableLazyRendering;
79 else if (actionType == "nolazy")
81 currentAction.type = AT_DisableLazyRendering;
83 else if (actionType == "quit")
85 currentAction.type = AT_Quit;
87 else if (actionType == "loadsvg")
89 currentAction.type = AT_LoadSVG;
90 inp >> currentAction.textargs;
92 else if (actionType == "label")
94 currentAction.type = AT_Label;
95 inp >> currentAction.textargs;
97 else if (actionType == "goto")
99 currentAction.type = AT_Goto;
100 inp >> currentAction.textargs;
102 else if (actionType == "debug")
104 currentAction.type = AT_Debug;
105 getline(inp,currentAction.textargs);
107 else if (actionType == "clear")
109 currentAction.type = AT_ClearDocument;
111 else if (actionType == "clearperf")
113 currentAction.type = AT_ClearPerformance;
115 else if (actionType == "printperf")
117 currentAction.type = AT_PrintPerformance;
119 else if (actionType == "recordperf")
121 currentAction.type = AT_RecordPerformance;
123 else if (actionType == "debugfont")
125 currentAction.type = AT_DebugFont;
126 inp >> currentAction.textargs;
128 else if (actionType == "approachz") // approach zenoistically
130 currentAction.type = AT_ApproachBoundsZeno;
131 std::string _x, _y, _w, _h, _z;
132 inp >> _x >> _y >> _w >> _h >> _z;
133 currentAction.x = RealFromStr(_x.c_str());
134 currentAction.y = RealFromStr(_y.c_str());
135 currentAction.w = RealFromStr(_w.c_str());
136 currentAction.h = RealFromStr(_h.c_str());
137 currentAction.z = RealFromStr(_z.c_str());
139 else if (actionType == "approachl") // approach linearly
141 currentAction.type = AT_ApproachBoundsLinear;
142 std::string _x, _y, _w, _h, _z;
143 inp >> _x >> _y >> _w >> _h >> _z;
144 currentAction.x = RealFromStr(_x.c_str());
145 currentAction.y = RealFromStr(_y.c_str());
146 currentAction.w = RealFromStr(_w.c_str());
147 currentAction.h = RealFromStr(_h.c_str());
148 currentAction.z = RealFromStr(_z.c_str());
149 currentAction.x = (currentAction.x - view->GetBounds().x)/currentAction.z;
150 currentAction.y = (currentAction.y - view->GetBounds().y)/currentAction.z;
151 currentAction.w = (currentAction.w - view->GetBounds().w)/currentAction.z;
152 currentAction.h = (currentAction.h - view->GetBounds().h)/currentAction.z;
154 else if (actionType == "setbounds")
156 currentAction.type = AT_SetBounds;
157 std::string _x, _y, _w, _h;
158 inp >> _x >> _y >> _w >> _h;
159 currentAction.x = RealFromStr(_x.c_str());
160 currentAction.y = RealFromStr(_y.c_str());
161 currentAction.w = RealFromStr(_w.c_str());
162 currentAction.h = RealFromStr(_h.c_str());
164 else if (actionType == "querygpubounds")
166 currentAction.type = AT_QueryGPUBounds;
167 inp >> currentAction.textargs;
168 currentAction.loops = 1;
170 else if (actionType == "screenshot")
172 currentAction.type = AT_ScreenShot;
173 inp >> currentAction.textargs;
175 else if (actionType == "printspf")
177 currentAction.type = AT_PrintSPF;
178 currentAction.iz = currentAction.loops;
181 m_spf_cpu_stddev = 0;
182 m_spf_gpu_stddev = 0;
184 else if (actionType == "printbounds")
186 currentAction.type = AT_PrintBounds;
189 Fatal("Unknown action %s", actionType.c_str());
193 bool DebugScript::Execute(View *view, Screen *scr)
195 if (currentAction.loops <= 0)
197 if (m_index >= m_actions.size())
199 ParseAction(view, scr);
200 if (m_labels.size() > 0)
202 m_actions.push_back(currentAction);
208 currentAction = m_actions[m_index++];
211 switch(currentAction.type)
218 view->Translate(Double(currentAction.x), Double(currentAction.y));
221 view->Translate(Real(currentAction.ix)/Real(scr->ViewportWidth()), Real(currentAction.iy)/Real(scr->ViewportHeight()));
224 view->ScaleAroundPoint(Double(currentAction.x), Double(currentAction.y), Double(currentAction.z));
227 view->ScaleAroundPoint(Real(currentAction.ix)/Real(scr->ViewportWidth()),Real(currentAction.iy)/Real(scr->ViewportHeight()), exp(Real(-currentAction.iz)/Real(20)));
229 case AT_SetGPURendering:
230 view->SetGPURendering(true);
232 case AT_SetCPURendering:
233 view->SetGPURendering(false);
235 case AT_EnableLazyRendering:
236 view->SetLazyRendering(true);
238 case AT_DisableLazyRendering:
239 view->SetLazyRendering(false);
243 #ifdef TRANSFORM_OBJECTS_NOT_VIEW
244 view->Doc().LoadSVG(currentAction.textargs, Rect(Real(1)/Real(2),Real(1)/Real(2),Real(1)/Real(800),Real(1)/Real(600)));
246 const Rect & bounds = view->GetBounds();
247 view->Doc().LoadSVG(currentAction.textargs, Rect(bounds.x+bounds.w/Real(2),bounds.y+bounds.h/Real(2),bounds.w/Real(800),bounds.h/Real(600)));
249 currentAction.type = AT_WaitFrame;
250 view->ForceRenderDirty();
251 view->ForceBufferDirty();
252 view->ForceBoundsDirty();
253 currentAction.loops = 1;
257 m_labels[currentAction.textargs] = m_index;
258 currentAction.type = AT_WaitFrame;
259 currentAction.loops = 1;
262 m_index = m_labels[currentAction.textargs];
263 currentAction.loops = 1;
266 Debug("View bounds: %s", view->GetBounds().Str().c_str());
267 if (currentAction.textargs.size() > 0)
268 Debug("%s", currentAction.textargs.c_str());
270 case AT_ClearDocument:
271 view->Doc().ClearObjects();
272 currentAction.loops = 1;
274 case AT_ClearPerformance:
275 ClearPerformance(view, scr);
276 currentAction.loops = 1;
278 case AT_PrintPerformance:
279 PrintPerformance(view, scr);
280 currentAction.loops = 1;
282 case AT_RecordPerformance:
283 PrintPerformance(view, scr);
286 scr->ShowDebugFont(currentAction.textargs == "1" || currentAction.textargs == "on");
287 currentAction.loops = 1;
290 case AT_ApproachBoundsZeno:
292 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
293 if (currentAction.z != VReal(1))
295 target.x = view->GetBounds().x + (target.x-view->GetBounds().x)/VReal(currentAction.z);
296 target.y = view->GetBounds().y + (target.y-view->GetBounds().y)/VReal(currentAction.z);
297 target.w = view->GetBounds().w + (target.w-view->GetBounds().w)/VReal(currentAction.z);
298 target.h = view->GetBounds().h + (target.h-view->GetBounds().h)/VReal(currentAction.z);
302 VReal s = target.w/(view->GetBounds().w);
307 x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w);
308 y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h);
309 view->ScaleAroundPoint(Double(x0), Double(y0), Double(s));
310 currentAction.loops++;
314 Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops);
315 currentAction.type = AT_WaitFrame;
319 case AT_ApproachBoundsLinear:
321 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
322 target.x += view->GetBounds().x;
323 target.y += view->GetBounds().y;
324 target.w += view->GetBounds().w;
325 target.h += view->GetBounds().h;
326 VReal s = target.w/(view->GetBounds().w);
331 x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w);
332 y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h);
333 view->ScaleAroundPoint(Double(x0), Double(y0), Double(s));
334 currentAction.loops++;
338 Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops);
339 currentAction.type = AT_WaitFrame;
345 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
346 view->SetBounds(target);
350 case AT_QueryGPUBounds:
352 view->QueryGPUBounds(currentAction.textargs.c_str(), "w");
353 currentAction.loops = 1;
358 view->SaveBMP(currentAction.textargs.c_str());
359 currentAction.loops = 1;
364 // Using a (apparently) Soviet trick to calculate the stddev in one pass
365 // This was my favourite algorithm in my Physics honours project
367 // The horrible horrible memories
368 // At least things won't get that bad
370 if (currentAction.loops <= 1)
372 double n = double(currentAction.iz);
376 m_spf_cpu_stddev = sqrt(m_spf_cpu_stddev / n - m_spf_cpu_mean*m_spf_cpu_mean);
377 m_spf_gpu_stddev = sqrt(m_spf_gpu_stddev / n - m_spf_gpu_mean*m_spf_gpu_mean);
381 printf("%d\t%f\t%f\t%f\t%f\n", currentAction.iz,
382 m_spf_gpu_mean, m_spf_gpu_stddev,
383 m_spf_cpu_mean, m_spf_cpu_stddev);
388 double spf_cpu = scr->GetLastFrameTimeCPU();
389 double spf_gpu = scr->GetLastFrameTimeGPU();
391 m_spf_cpu_mean += spf_cpu;
392 m_spf_gpu_mean += spf_gpu;
394 m_spf_cpu_stddev += spf_cpu*spf_cpu;
395 m_spf_gpu_stddev += spf_gpu*spf_gpu;
401 printf("%s\t%s\t%s\t%s\t%s\t%s\n", Str(view->GetBounds().x).c_str(), Str(view->GetBounds().y).c_str(), Str(view->GetBounds().w).c_str(), Str(view->GetBounds().h).c_str(), Str(Log10(view->GetBounds().w)).c_str(), Str(Log10(view->GetBounds().h)).c_str());
405 Fatal("Unknown script command in queue.");
407 currentAction.loops--;
411 void DebugScript::ClearPerformance(View * view, Screen * scr)
413 m_perf_start.clock = clock();
414 m_perf_start.object_count = view->Doc().ObjectCount();
415 m_perf_start.view_bounds = view->GetBounds();
416 m_perf_last = m_perf_start;
419 void DebugScript::PrintPerformance(View * view, Screen * scr)
421 DebugScript::PerformanceData now;
423 now.object_count = view->Doc().ObjectCount();
424 now.view_bounds = view->GetBounds();
426 // object_count clock delta_clock x Log10(x) y Log10(y) w Log10(w) Size(w)
427 #ifdef QUADTREE_DISABLED
428 printf("%d\t%llu\t%llu\t%s\t%s\t%s\t%s\t%s\t%s\t%u\n",
429 now.object_count, (long long unsigned)now.clock,
430 (long long unsigned)(now.clock - m_perf_last.clock),
431 Str(now.view_bounds.x).c_str(), Str(Log10(Abs(now.view_bounds.x))).c_str(),
432 Str(now.view_bounds.y).c_str(), Str(Log10(Abs(now.view_bounds.y))).c_str(),
433 Str(now.view_bounds.w).c_str(), Str(Log10(now.view_bounds.w)).c_str(),
434 (unsigned)Size(now.view_bounds.w));