1 #include "debugscript.h"
9 void DebugScript::ParseAction(View * view, Screen * scr)
12 if (m_input == NULL || !m_input->good())
14 istream & inp = *m_input;
15 Debug("Get action type...");
16 std::string actionType;
18 Debug("Action type: %s", actionType.c_str());
20 while (actionType[0] == '#')
23 std::getline(inp, tmp);
24 inp >> std::ws >> actionType;
26 if (actionType == "loop")
28 inp >> currentAction.loops >> actionType;
32 currentAction.loops = 1;
35 if (actionType == "wait")
37 currentAction.type = AT_WaitFrame;
40 else if (actionType == "translate")
44 currentAction.type = AT_Translate;
45 currentAction.x = RealFromStr(_x.c_str());
46 currentAction.y = RealFromStr(_y.c_str());
49 else if (actionType == "zoom")
51 std::string _x, _y, _z;
52 inp >> _x >> _y >> _z;
53 currentAction.type = AT_Zoom;
54 currentAction.x = RealFromStr(_x.c_str());
55 currentAction.y = RealFromStr(_y.c_str());
56 currentAction.z = RealFromStr(_z.c_str());
58 else if (actionType == "pxtranslate")
60 inp >> currentAction.ix >> currentAction.iy;
61 currentAction.type = AT_TranslatePx;
63 else if (actionType == "pxzoom")
65 inp >> currentAction.ix >> currentAction.iy >> currentAction.iz;
66 currentAction.type = AT_ZoomPx;
68 else if (actionType == "gpu")
70 currentAction.type = AT_SetGPURendering;
72 else if (actionType == "cpu")
74 currentAction.type = AT_SetCPURendering;
76 else if (actionType == "lazy")
78 currentAction.type = AT_EnableLazyRendering;
80 else if (actionType == "nolazy")
82 currentAction.type = AT_DisableLazyRendering;
84 else if (actionType == "quit")
86 currentAction.type = AT_Quit;
88 else if (actionType == "loadsvg")
90 currentAction.type = AT_LoadSVG;
91 inp >> currentAction.textargs;
93 else if (actionType == "label")
95 currentAction.type = AT_Label;
96 inp >> currentAction.textargs;
98 else if (actionType == "goto")
100 currentAction.type = AT_Goto;
101 inp >> currentAction.textargs;
103 else if (actionType == "debug")
105 currentAction.type = AT_Debug;
106 getline(inp,currentAction.textargs);
108 else if (actionType == "clear")
110 currentAction.type = AT_ClearDocument;
112 else if (actionType == "clearperf")
114 currentAction.type = AT_ClearPerformance;
116 else if (actionType == "printperf")
118 currentAction.type = AT_PrintPerformance;
120 else if (actionType == "recordperf")
122 currentAction.type = AT_RecordPerformance;
124 else if (actionType == "debugfont")
126 currentAction.type = AT_DebugFont;
127 inp >> currentAction.textargs;
129 else if (actionType == "approachz") // approach zenoistically
131 currentAction.type = AT_ApproachBoundsZeno;
132 std::string _x, _y, _w, _h, _z;
133 inp >> _x >> _y >> _w >> _h >> _z;
134 currentAction.x = RealFromStr(_x.c_str());
135 currentAction.y = RealFromStr(_y.c_str());
136 currentAction.w = RealFromStr(_w.c_str());
137 currentAction.h = RealFromStr(_h.c_str());
138 currentAction.z = RealFromStr(_z.c_str());
140 else if (actionType == "approachl") // approach linearly
142 currentAction.type = AT_ApproachBoundsLinear;
143 std::string _x, _y, _w, _h, _z;
144 inp >> _x >> _y >> _w >> _h >> _z;
145 currentAction.x = RealFromStr(_x.c_str());
146 currentAction.y = RealFromStr(_y.c_str());
147 currentAction.w = RealFromStr(_w.c_str());
148 currentAction.h = RealFromStr(_h.c_str());
149 currentAction.z = RealFromStr(_z.c_str());
150 currentAction.x = (currentAction.x - view->GetBounds().x)/currentAction.z;
151 currentAction.y = (currentAction.y - view->GetBounds().y)/currentAction.z;
152 currentAction.w = (currentAction.w - view->GetBounds().w)/currentAction.z;
153 currentAction.h = (currentAction.h - view->GetBounds().h)/currentAction.z;
155 else if (actionType == "setbounds")
157 currentAction.type = AT_SetBounds;
158 std::string _x, _y, _w, _h;
159 inp >> _x >> _y >> _w >> _h;
160 currentAction.x = RealFromStr(_x.c_str());
161 currentAction.y = RealFromStr(_y.c_str());
162 currentAction.w = RealFromStr(_w.c_str());
163 currentAction.h = RealFromStr(_h.c_str());
165 else if (actionType == "querygpubounds")
167 currentAction.type = AT_QueryGPUBounds;
168 inp >> currentAction.textargs;
169 currentAction.loops = 1;
171 else if (actionType == "screenshot")
173 currentAction.type = AT_ScreenShot;
174 inp >> currentAction.textargs;
176 else if (actionType == "printspf")
178 currentAction.type = AT_PrintSPF;
179 currentAction.iz = currentAction.loops;
182 m_spf_cpu_stddev = 0;
183 m_spf_gpu_stddev = 0;
185 else if (actionType == "printbounds")
187 currentAction.type = AT_PrintBounds;
189 else if (actionType == "profileon")
191 currentAction.type = AT_ProfileDisplay;
192 currentAction.iz = 1;
194 else if (actionType == "profileoff")
196 currentAction.type = AT_ProfileDisplay;
197 currentAction.iz = 0;
200 Fatal("Unknown action %s", actionType.c_str());
204 bool DebugScript::Execute(View *view, Screen *scr)
206 if (currentAction.loops <= 0)
208 if (m_index >= m_actions.size())
210 ParseAction(view, scr);
211 if (m_labels.size() > 0)
213 m_actions.push_back(currentAction);
219 currentAction = m_actions[m_index++];
222 switch(currentAction.type)
229 view->Translate(Double(currentAction.x), Double(currentAction.y));
232 view->Translate(Real(currentAction.ix)/Real(scr->ViewportWidth()), Real(currentAction.iy)/Real(scr->ViewportHeight()));
235 view->ScaleAroundPoint(Double(currentAction.x), Double(currentAction.y), Double(currentAction.z));
238 view->ScaleAroundPoint(Real(currentAction.ix)/Real(scr->ViewportWidth()),Real(currentAction.iy)/Real(scr->ViewportHeight()), exp(Real(-currentAction.iz)/Real(20)));
240 case AT_SetGPURendering:
241 view->SetGPURendering(true);
243 case AT_SetCPURendering:
244 view->SetGPURendering(false);
246 case AT_EnableLazyRendering:
247 view->SetLazyRendering(true);
249 case AT_DisableLazyRendering:
250 view->SetLazyRendering(false);
254 #ifndef QUADTREE_DISABLED
255 view->Doc().SetQuadtreeInsertNode(view->GetCurrentQuadtreeNode());
257 #ifdef TRANSFORM_OBJECTS_NOT_VIEW
258 view->Doc().LoadSVG(currentAction.textargs, Rect(Real(1)/Real(2),Real(1)/Real(2),Real(1)/Real(800),Real(1)/Real(600)));
260 const Rect & bounds = view->GetBounds();
261 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)));
263 #ifndef QUADTREE_DISABLED
264 view->Doc().PropagateQuadChanges(view->GetCurrentQuadtreeNode());
265 view->Doc().PropagateQuadChanges(view->Doc().GetQuadTree().GetNeighbour(view->GetCurrentQuadtreeNode(), 0, 1, 0));
266 view->Doc().PropagateQuadChanges(view->Doc().GetQuadTree().GetNeighbour(view->GetCurrentQuadtreeNode(), 1, 0, 0));
267 view->Doc().PropagateQuadChanges(view->Doc().GetQuadTree().GetNeighbour(view->GetCurrentQuadtreeNode(), 1, 1, 0));
269 currentAction.type = AT_WaitFrame;
270 view->ForceRenderDirty();
271 view->ForceBufferDirty();
272 view->ForceBoundsDirty();
273 currentAction.loops = 1;
277 m_labels[currentAction.textargs] = m_index;
278 currentAction.type = AT_WaitFrame;
279 currentAction.loops = 1;
282 m_index = m_labels[currentAction.textargs];
283 currentAction.loops = 1;
286 Debug("View bounds: %s", view->GetBounds().Str().c_str());
287 if (currentAction.textargs.size() > 0)
288 Debug("%s", currentAction.textargs.c_str());
290 case AT_ClearDocument:
291 view->Doc().ClearObjects();
292 currentAction.loops = 1;
294 case AT_ClearPerformance:
295 ClearPerformance(view, scr);
296 currentAction.loops = 1;
298 case AT_PrintPerformance:
299 PrintPerformance(view, scr);
300 currentAction.loops = 1;
302 case AT_RecordPerformance:
303 PrintPerformance(view, scr);
306 scr->ShowDebugFont(currentAction.textargs == "1" || currentAction.textargs == "on");
307 currentAction.loops = 1;
310 case AT_ApproachBoundsZeno:
312 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
313 if (currentAction.z != VReal(1))
315 target.x = view->GetBounds().x + (target.x-view->GetBounds().x)/VReal(currentAction.z);
316 target.y = view->GetBounds().y + (target.y-view->GetBounds().y)/VReal(currentAction.z);
317 target.w = view->GetBounds().w + (target.w-view->GetBounds().w)/VReal(currentAction.z);
318 target.h = view->GetBounds().h + (target.h-view->GetBounds().h)/VReal(currentAction.z);
322 VReal s = target.w/(view->GetBounds().w);
327 x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w);
328 y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h);
329 view->ScaleAroundPoint(Double(x0), Double(y0), Double(s));
330 currentAction.loops++;
334 Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops);
335 currentAction.type = AT_WaitFrame;
339 case AT_ApproachBoundsLinear:
341 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
342 target.x += view->GetBounds().x;
343 target.y += view->GetBounds().y;
344 target.w += view->GetBounds().w;
345 target.h += view->GetBounds().h;
346 VReal s = target.w/(view->GetBounds().w);
351 x0 = (view->GetBounds().x - target.x)/((s - VReal(1))*view->GetBounds().w);
352 y0 = (view->GetBounds().y - target.y)/((s - VReal(1))*view->GetBounds().h);
353 view->ScaleAroundPoint(Double(x0), Double(y0), Double(s));
354 currentAction.loops++;
358 Debug("Already at target view; Waiting for remaining %d frames", currentAction.loops);
359 currentAction.type = AT_WaitFrame;
365 VRect target(currentAction.x, currentAction.y, currentAction.w, currentAction.h);
366 view->SetBounds(target);
370 case AT_QueryGPUBounds:
372 view->QueryGPUBounds(currentAction.textargs.c_str(), "w");
373 currentAction.loops = 1;
378 view->SaveBMP(currentAction.textargs.c_str());
379 currentAction.loops = 1;
384 // Using a (apparently) Soviet trick to calculate the stddev in one pass
385 // This was my favourite algorithm in my Physics honours project
387 // The horrible horrible memories
388 // At least things won't get that bad
390 if (currentAction.loops <= 1)
392 double n = double(currentAction.iz);
396 m_spf_cpu_stddev = sqrt(m_spf_cpu_stddev / n - m_spf_cpu_mean*m_spf_cpu_mean);
397 m_spf_gpu_stddev = sqrt(m_spf_gpu_stddev / n - m_spf_gpu_mean*m_spf_gpu_mean);
401 printf("%d\t%f\t%f\t%f\t%f\n", currentAction.iz,
402 m_spf_gpu_mean, m_spf_gpu_stddev,
403 m_spf_cpu_mean, m_spf_cpu_stddev);
408 double spf_cpu = scr->GetLastFrameTimeCPU();
409 double spf_gpu = scr->GetLastFrameTimeGPU();
411 m_spf_cpu_mean += spf_cpu;
412 m_spf_gpu_mean += spf_gpu;
414 m_spf_cpu_stddev += spf_cpu*spf_cpu;
415 m_spf_gpu_stddev += spf_gpu*spf_gpu;
421 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());
424 case AT_ProfileDisplay:
426 g_profiler.Enable(currentAction.iz);
430 Fatal("Unknown script command in queue.");
432 currentAction.loops--;
436 void DebugScript::ClearPerformance(View * view, Screen * scr)
438 m_perf_start.clock = clock();
439 m_perf_start.object_count = view->Doc().ObjectCount();
440 m_perf_start.view_bounds = view->GetBounds();
441 m_perf_last = m_perf_start;
444 void DebugScript::PrintPerformance(View * view, Screen * scr)
446 DebugScript::PerformanceData now;
448 now.object_count = view->Doc().ObjectCount();
449 now.view_bounds = view->GetBounds();
451 // object_count clock delta_clock x Log10(x) y Log10(y) w Log10(w) Size(w)
452 //#ifdef QUADTREE_DISABLED
453 printf("%d\t%llu\t%llu\t%s\t%s\t%s\t%s\t%s\t%s\t%u\n",
454 now.object_count, (long long unsigned)now.clock,
455 (long long unsigned)(now.clock - m_perf_last.clock),
456 "", "", "", "", "", "", 0);
457 /*Str(now.view_bounds.x).c_str(), Str(Log10(Abs(now.view_bounds.x))).c_str(),
458 Str(now.view_bounds.y).c_str(), Str(Log10(Abs(now.view_bounds.y))).c_str(),
459 Str(now.view_bounds.w).c_str(), Str(Log10(now.view_bounds.w)).c_str(),
460 (unsigned)Size(now.view_bounds.w));*/