DebugActor.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. #include <sstream>
  2. #include "core/oxygine.h"
  3. #include "res/ResAnim.h"
  4. #include "res/ResFont.h"
  5. #include "res/Resources.h"
  6. #include "utils/stringUtils.h"
  7. #include "core/NativeTexture.h"
  8. #include "core/ZipFileSystem.h"
  9. #include "core/system_data.h"
  10. #include "STDRenderer.h"
  11. #include "dev_tools/DeveloperMenu.h"
  12. #include "dev_tools/TreeInspector.h"
  13. #include "dev_tools/TexturesInspector.h"
  14. #include "STDRenderer.h"
  15. #include "DebugActor.h"
  16. #include "Stage.h"
  17. #include "TextField.h"
  18. #include "ColorRectSprite.h"
  19. #include "Button.h"
  20. #include "Event.h"
  21. #include "RenderState.h"
  22. #include "initActor.h"
  23. #include "MaskedSprite.h"
  24. #include "STDMaterial.h"
  25. #include <stdio.h>
  26. #include <stdarg.h>
  27. #include <iomanip>
  28. #ifdef __S3E__
  29. #include "s3eMemory.h"
  30. #elif __APPLE__
  31. #include "core/ios/ios.h"
  32. #endif
  33. #ifndef __S3E__
  34. #include "SDL_video.h"
  35. #endif
  36. #ifdef _WIN32
  37. #pragma comment(lib, "psapi.lib") // Added to support GetProcessMemoryInfo()
  38. #include <windows.h>
  39. #include <Psapi.h>
  40. #endif
  41. namespace oxygine
  42. {
  43. Resources* DebugActor::resSystem = 0;
  44. file::ZipFileSystem zp;
  45. spDebugActor DebugActor::instance;
  46. int _corner = 0;
  47. void DebugActor::initialize()
  48. {
  49. if (resSystem)
  50. return;
  51. log::messageln("DebugActor::initialize");
  52. zp.setPrefix("system/");
  53. zp.add(system_data, system_size);
  54. file::mount(&zp);
  55. resSystem = new Resources;
  56. resSystem->loadXML("system/res.xml", ResourcesLoadOptions().prebuiltFolder("system"));
  57. }
  58. void DebugActor::show()
  59. {
  60. initialize();
  61. if (!DebugActor::instance)
  62. DebugActor::instance = new DebugActor;
  63. getStage()->addChild(DebugActor::instance);
  64. }
  65. void DebugActor::toggle()
  66. {
  67. if (!DebugActor::instance)
  68. {
  69. show();
  70. return;
  71. }
  72. if (DebugActor::instance->_getStage())
  73. hide();
  74. else
  75. show();
  76. }
  77. void DebugActor::hide()
  78. {
  79. if (DebugActor::instance)
  80. DebugActor::instance->detach();
  81. }
  82. void DebugActor::setCorner(int corner)
  83. {
  84. _corner = corner;
  85. }
  86. void DebugActor::release()
  87. {
  88. instance = 0;
  89. delete resSystem;
  90. resSystem = 0;
  91. file::unmount(&zp);
  92. zp.reset();
  93. }
  94. void DebugActor::addButton(float& x, const char* name, const char* anim)
  95. {
  96. spButton btn;
  97. btn = initActor(new Button,
  98. arg_resAnim = resSystem->getResAnim(anim),
  99. arg_y = 1,
  100. arg_name = name,
  101. arg_attachTo = this);
  102. x = x - btn->getWidth();
  103. btn->setX(x);
  104. btn->addEventListener(TouchEvent::CLICK, CLOSURE(this, &DebugActor::_btnClicked));
  105. }
  106. DebugActor::DebugActor(): _frames(0), _startTime(0), _showTexel2PixelErrors(false), _showTouchedActor(false), _dragging(false)
  107. {
  108. DebugActor::initialize();
  109. setName(getDefaultName());
  110. _startTime = getTimeMS();
  111. setPriority(30000);
  112. setTouchEnabled(false);
  113. TextStyle st;
  114. st.font = NULL;
  115. if (ResFont* fnt = resSystem->getResFont("mono"))
  116. {
  117. st.font = fnt;
  118. }
  119. OX_ASSERT(st.font != NULL);
  120. st.vAlign = TextStyle::VALIGN_TOP;
  121. st.hAlign = TextStyle::HALIGN_LEFT;
  122. //st.color = Color(rand()%255, rand()%255, rand()%255, 255);
  123. st.color = Color(Color::Black, 255);
  124. st.multiline = true;
  125. setWidth(230);
  126. setHeight(45);
  127. _bg = new ColorRectSprite;
  128. _bg->setColor(Color(Color::White, 180));
  129. _bg->setSize(getSize());
  130. _bg->setTouchEnabled(false);
  131. addChild(_bg);
  132. float x = getWidth();
  133. addButton(x, "tree", "tree");
  134. addButton(x, "finger", "finger");
  135. #ifdef OXYGINE_DEBUG_T2P
  136. addButton(x, "t2p", "t2p");
  137. #endif
  138. #ifdef OXYGINE_DEBUG_TRACE_LEAKS
  139. addButton(x, "images", "images");
  140. #endif
  141. _text = new TextField;
  142. addChild(_text);
  143. _text->setPosition(2, 7);
  144. _text->setTouchEnabled(false);
  145. _text->setStyle(st);
  146. _text->setWidth(getWidth());
  147. _text->setText("debug text");
  148. instance = this;
  149. /*
  150. float dpi = 0;
  151. float dpi1 = 0;
  152. float dpi2 = 0;
  153. int ret = SDL_GetDisplayDPI(0, &dpi, &dpi1, &dpi2);
  154. {
  155. log::messageln("dpi>>>>> %d %f %f %f", ret, dpi, dpi1, dpi2);
  156. }
  157. */
  158. }
  159. void DebugActor::onAdded2Stage()
  160. {
  161. _dragging = false;
  162. _stage->addEventListener(TouchEvent::MOVE, CLOSURE(this, &DebugActor::onDAEvent));
  163. _stage->addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DebugActor::onDAEvent));
  164. _stage->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &DebugActor::onDAEvent));
  165. }
  166. void DebugActor::onRemovedFromStage()
  167. {
  168. _stage->removeEventListeners(this);
  169. }
  170. void DebugActor::addDebugString(const char* format, ...)
  171. {
  172. char buff[1024] = "";
  173. va_list args;
  174. va_start(args, format);
  175. int len = (int)strlen(buff);
  176. vsnprintf(buff + len, sizeof(buff) - len, format, args);
  177. va_end(args);
  178. if (DebugActor::instance)
  179. {
  180. std::string& str = DebugActor::instance->_debugText;
  181. str += buff;
  182. str += "\n";
  183. if (str.size() > 500)
  184. {
  185. str.resize(500);
  186. }
  187. }
  188. }
  189. void DebugActor::_btnClicked(Event* ev)
  190. {
  191. std::string name = ev->currentTarget->getName();
  192. if (name == "finger")
  193. {
  194. showTouchedActor(!_showTouchedActor);
  195. return;
  196. }
  197. if (name == "t2p")
  198. {
  199. showTexel2PixelErrors(!_showTexel2PixelErrors);
  200. return;
  201. }
  202. spActor inspector = _getStage()->getChild(DeveloperMenu::getDefaultName(), ep_ignore_error);
  203. if (inspector)
  204. inspector->detach();
  205. else
  206. {
  207. spDeveloperMenu dm = new DeveloperMenu();
  208. dm->setPriority(getPriority() + 1);
  209. float scale = _getStage()->getScaleX();
  210. Vector2 size = core::getDisplaySize();
  211. Vector2 s = size;// * scale;
  212. s.y -= 24;
  213. if (name == "tree")
  214. {
  215. spTreeInspector tree = new TreeInspector;
  216. tree->init(s, _getStage());
  217. dm->init(s, "Tree Inspector", tree, Color(230, 230, 230, 255));
  218. }
  219. if (name == "images")
  220. {
  221. spTexturesInspector tree = new TexturesInspector(s);
  222. dm->init(s, "Textures Inspector", tree, Color(60, 60, 60, 255));
  223. }
  224. dm->setScale(1.0f / scale);
  225. Vector2 p = -_getStage()->getPosition() / scale;
  226. dm->setPosition(p);
  227. _getStage()->addChild(dm);
  228. }
  229. }
  230. DebugActor::~DebugActor()
  231. {
  232. }
  233. std::string aligned(int v, int width)
  234. {
  235. char str[32];
  236. str[0] = '%';
  237. str[1] = width + 48;
  238. str[2] = 'd';
  239. str[3] = 0;
  240. char rs[32];
  241. safe_sprintf(rs, str, v);
  242. return rs;
  243. }
  244. void DebugActor::doUpdate(const UpdateState& us)
  245. {
  246. }
  247. void DebugActor::render(RenderState const& parentRS)
  248. {
  249. timeMS tm = getTimeMS();
  250. static int fps = 0;
  251. ++_frames;
  252. if (_frames > 50)
  253. {
  254. if (tm != _startTime)
  255. {
  256. fps = int(((float)_frames / (tm - _startTime)) * 1000);
  257. }
  258. _startTime = tm;
  259. _frames = 0;
  260. }
  261. std::stringstream s;
  262. s << "fps=" << fps << std::endl;
  263. #ifdef __S3E__
  264. int mem_used = -1;
  265. int mem_free = -1;
  266. mem_used = s3eMemoryGetInt(S3E_MEMORY_USED);
  267. mem_free = s3eMemoryGetInt(S3E_MEMORY_FREE);
  268. s << "mfree=" << mem_free << " mem=" << mem_used << std::endl;
  269. #endif
  270. const IVideoDriver::Stats& vstats = IVideoDriver::_stats;
  271. #ifdef OXYGINE_DEBUG_TRACE_LEAKS
  272. s << "objects=" << (int)ObjectBase::__getCreatedObjects().size() << std::endl;
  273. #endif
  274. #if OXYGINE_TRACE_VIDEO_STATS
  275. int primitives = 0;
  276. primitives += vstats.elements[IVideoDriver::PT_TRIANGLES] / 3;
  277. if (vstats.elements[IVideoDriver::PT_TRIANGLE_STRIP])
  278. primitives += vstats.elements[IVideoDriver::PT_TRIANGLE_STRIP] - 2;
  279. s << "batches=" << aligned(vstats.batches, 3) << " primitives=" << aligned(primitives, 3) << std::endl;
  280. #endif
  281. s << "update=" << aligned(getStage()->_statUpdate, 2) << "ms ";
  282. s << "render=" << aligned(vstats.duration, 2) << "ms ";
  283. s << "textures=" << aligned(NativeTexture::created, 2) << " ";
  284. #ifdef __APPLE__
  285. size_t mem;
  286. iosGetMemoryUsage(mem);
  287. s << "memory=" << mem / 1024 << "kb ";
  288. #endif
  289. #ifdef _WIN32
  290. PROCESS_MEMORY_COUNTERS_EX pmc;
  291. GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmc, sizeof(pmc));
  292. s << "memory=" << pmc.PrivateUsage / 1024 << "kb ";
  293. #endif
  294. if (!_debugText.empty())
  295. {
  296. s << "\n";
  297. s << _debugText;
  298. }
  299. _debugText = "";
  300. _text->setText(s.str());
  301. setHeight(_text->getTextRect().size.y + _text->getY() + 3);
  302. _bg->setSize(getSize());
  303. Vector2 ds = core::getDisplaySize();
  304. Vector2 pos(0, 0);
  305. switch (_corner)
  306. {
  307. case 1:
  308. pos.x = ds.x;
  309. break;
  310. case 2:
  311. pos = ds;
  312. break;
  313. case 3:
  314. pos.y = ds.y;
  315. break;
  316. }
  317. pos = getStage()->parent2local(pos);
  318. Vector2 realSize = getScaledSize();
  319. switch (_corner)
  320. {
  321. case 1:
  322. pos.x -= realSize.x;
  323. break;
  324. case 2:
  325. pos -= realSize;
  326. break;
  327. case 3:
  328. pos.y -= realSize.y;
  329. break;
  330. }
  331. //setPosition(pos);
  332. setScale(1.0f / getStage()->getScaleX());
  333. RenderState rs = parentRS;
  334. parentRS.material->finish();
  335. STDRenderer renderer;
  336. STDMaterial mat(&renderer);
  337. mat.apply(0);
  338. IVideoDriver* driver = renderer.getDriver();
  339. Rect vp(Point(0, 0), core::getDisplaySize());
  340. driver->setViewport(vp);
  341. renderer.initCoordinateSystem(vp.getWidth(), vp.getHeight());
  342. renderer.resetSettings();
  343. rs.material = &mat;
  344. Actor::render(rs);
  345. renderer.drawBatch();
  346. mat.finish();
  347. Material::setCurrent(0);
  348. timeMS dur = getTimeMS() - tm;
  349. IVideoDriver::_stats.start += dur;
  350. }
  351. void DebugActor::showTexel2PixelErrors(bool show)
  352. {
  353. _showTexel2PixelErrors = show;
  354. #ifdef OXYGINE_DEBUG_T2P
  355. STDRenderer::showTexel2PixelErrors(_showTexel2PixelErrors);
  356. spActor btn = getChild("t2p");
  357. btn->removeTweens(true);
  358. if (show)
  359. btn->addTween(Actor::TweenAlpha(0), 300, 999999, true);
  360. #endif
  361. }
  362. void DebugActor::showTouchedActor(bool show)
  363. {
  364. _getStage()->removeEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DebugActor::onEvent));
  365. _showTouchedActor = show;
  366. if (show)
  367. _getStage()->addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DebugActor::onEvent));
  368. spActor btn = getChild("finger");
  369. btn->removeTweens(true);
  370. if (show)
  371. btn->addTween(Actor::TweenAlpha(0), 300, 999999, true);
  372. }
  373. void DebugActor::onDAEvent(Event* ev)
  374. {
  375. TouchEvent* t = safeCast<TouchEvent*>(ev);
  376. Vector2 loc = parent2local(t->localPosition);
  377. if (t->type == TouchEvent::MOVE)
  378. {
  379. setAlpha(isOn(loc) ? 64 : 255);
  380. if (_dragging)
  381. {
  382. Transform tr = getTransform();
  383. tr.x = 0;
  384. tr.y = 0;
  385. Vector2 p = tr.transform(_local);
  386. setPosition(t->localPosition - p);
  387. }
  388. }
  389. if (t->type == TouchEvent::TOUCH_DOWN)
  390. {
  391. if (isOn(loc))
  392. {
  393. _local = loc;
  394. _dragging = true;
  395. }
  396. }
  397. if (t->type == TouchEvent::TOUCH_UP)
  398. {
  399. _dragging = false;
  400. }
  401. }
  402. void DebugActor::onEvent(Event* ev)
  403. {
  404. TouchEvent* te = safeCast<TouchEvent*>(ev);
  405. spActor actor = safeSpCast<Actor>(ev->target);
  406. spColorRectSprite cr = new ColorRectSprite;
  407. cr->setTouchEnabled(false);
  408. cr->setColor(Color(rand() % 255, rand() % 255, rand() % 255, 0));
  409. cr->setSize(actor->getSize());
  410. cr->addTween(ColorRectSprite::TweenColor(Color(Color::White, 200)), 700, 1, true, 0, Tween::ease_inCubic)->detachWhenDone();
  411. actor->addChild(cr);
  412. std::string dmp = actor->dump(0);
  413. log::messageln(">>>>>>>>>>>>>>>>>>>>\ntouched actor '%s' local pos: (%.0f,%.0f), pos: (%.0f,%.0f)\n%s",
  414. actor->getName().c_str(),
  415. te->localPosition.x, te->localPosition.y,
  416. te->position.x, te->position.y,
  417. dmp.c_str());
  418. actor = actor->getParent();
  419. while (actor)
  420. {
  421. log::messageln("parent: %s", actor->getName().c_str());
  422. actor = actor->getParent();
  423. }
  424. }
  425. }