DebugActor.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  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::setCornerPosition(int corner)
  95. {
  96. setCorner(corner);
  97. }
  98. void DebugActor::addButton(float& x, const char* name, const char* anim)
  99. {
  100. spButton btn;
  101. btn = initActor(new Button,
  102. arg_resAnim = resSystem->getResAnim(anim),
  103. arg_y = 1,
  104. arg_name = name,
  105. arg_attachTo = this);
  106. x = x - btn->getWidth();
  107. btn->setX(x);
  108. btn->addEventListener(TouchEvent::CLICK, CLOSURE(this, &DebugActor::_btnClicked));
  109. }
  110. DebugActor::DebugActor(): _frames(0), _startTime(0), _showTexel2PixelErrors(false), _showTouchedActor(false), _dragging(false)
  111. {
  112. DebugActor::initialize();
  113. setName(getDefaultName());
  114. _startTime = getTimeMS();
  115. setPriority(30000);
  116. setTouchEnabled(false);
  117. TextStyle st;
  118. st.font = NULL;
  119. if (ResFont* fnt = resSystem->getResFont("mono"))
  120. {
  121. st.font = fnt;
  122. }
  123. OX_ASSERT(st.font != NULL);
  124. st.vAlign = TextStyle::VALIGN_TOP;
  125. st.hAlign = TextStyle::HALIGN_LEFT;
  126. //st.color = Color(rand()%255, rand()%255, rand()%255, 255);
  127. st.color = Color(Color::Black, 255);
  128. st.multiline = true;
  129. setWidth(230);
  130. setHeight(45);
  131. _bg = new ColorRectSprite;
  132. _bg->setColor(Color(Color::White, 180));
  133. _bg->setSize(getSize());
  134. _bg->setTouchEnabled(false);
  135. addChild(_bg);
  136. float x = getWidth();
  137. addButton(x, "tree", "tree");
  138. addButton(x, "finger", "finger");
  139. #ifdef OXYGINE_DEBUG_T2P
  140. addButton(x, "t2p", "t2p");
  141. #endif
  142. #ifdef OXYGINE_DEBUG_TRACE_LEAKS
  143. addButton(x, "images", "images");
  144. #endif
  145. _text = new TextField;
  146. addChild(_text);
  147. _text->setPosition(2, 7);
  148. _text->setTouchEnabled(false);
  149. _text->setStyle(st);
  150. _text->setWidth(getWidth());
  151. _text->setText("debug text");
  152. instance = this;
  153. /*
  154. float dpi = 0;
  155. float dpi1 = 0;
  156. float dpi2 = 0;
  157. int ret = SDL_GetDisplayDPI(0, &dpi, &dpi1, &dpi2);
  158. {
  159. log::messageln("dpi>>>>> %d %f %f %f", ret, dpi, dpi1, dpi2);
  160. }
  161. */
  162. }
  163. void DebugActor::onAdded2Stage()
  164. {
  165. _dragging = false;
  166. _stage->addEventListener(TouchEvent::MOVE, CLOSURE(this, &DebugActor::onDAEvent));
  167. _stage->addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DebugActor::onDAEvent));
  168. _stage->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &DebugActor::onDAEvent));
  169. }
  170. void DebugActor::onRemovedFromStage()
  171. {
  172. _stage->removeEventListeners(this);
  173. }
  174. void DebugActor::addDebugString(const char* format, ...)
  175. {
  176. char buff[1024] = "";
  177. va_list args;
  178. va_start(args, format);
  179. int len = (int)strlen(buff);
  180. vsnprintf(buff + len, sizeof(buff) - len, format, args);
  181. va_end(args);
  182. if (DebugActor::instance)
  183. {
  184. std::string& str = DebugActor::instance->_debugText;
  185. str += buff;
  186. str += "\n";
  187. if (str.size() > 500)
  188. {
  189. str.resize(500);
  190. }
  191. }
  192. }
  193. void DebugActor::_btnClicked(Event* ev)
  194. {
  195. std::string name = ev->currentTarget->getName();
  196. if (name == "finger")
  197. {
  198. showTouchedActor(!_showTouchedActor);
  199. return;
  200. }
  201. if (name == "t2p")
  202. {
  203. showTexel2PixelErrors(!_showTexel2PixelErrors);
  204. return;
  205. }
  206. spActor inspector = _getStage()->getChild(DeveloperMenu::getDefaultName(), ep_ignore_error);
  207. if (inspector)
  208. inspector->detach();
  209. else
  210. {
  211. spDeveloperMenu dm = new DeveloperMenu();
  212. dm->setPriority(getPriority() + 1);
  213. float scale = _getStage()->getScaleX();
  214. Vector2 size = core::getDisplaySize();
  215. Vector2 s = size;// * scale;
  216. s.y -= 24;
  217. if (name == "tree")
  218. {
  219. spTreeInspector tree = new TreeInspector;
  220. tree->init(s, _getStage());
  221. dm->init(s, "Tree Inspector", tree, Color(230, 230, 230, 255));
  222. }
  223. if (name == "images")
  224. {
  225. spTexturesInspector tree = new TexturesInspector(s);
  226. dm->init(s, "Textures Inspector", tree, Color(60, 60, 60, 255));
  227. }
  228. dm->setScale(1.0f / scale);
  229. Vector2 p = -_getStage()->getPosition() / scale;
  230. dm->setPosition(p);
  231. _getStage()->addChild(dm);
  232. }
  233. }
  234. DebugActor::~DebugActor()
  235. {
  236. }
  237. std::string aligned(int v, int width)
  238. {
  239. char str[32];
  240. str[0] = '%';
  241. str[1] = width + 48;
  242. str[2] = 'd';
  243. str[3] = 0;
  244. char rs[32];
  245. safe_sprintf(rs, str, v);
  246. return rs;
  247. }
  248. void DebugActor::doUpdate(const UpdateState& us)
  249. {
  250. }
  251. void DebugActor::render(RenderState const& parentRS)
  252. {
  253. timeMS tm = getTimeMS();
  254. static int fps = 0;
  255. ++_frames;
  256. if (_frames > 50)
  257. {
  258. if (tm != _startTime)
  259. {
  260. fps = int(((float)_frames / (tm - _startTime)) * 1000);
  261. }
  262. _startTime = tm;
  263. _frames = 0;
  264. }
  265. std::stringstream s;
  266. s << "fps=" << fps << std::endl;
  267. #ifdef __S3E__
  268. int mem_used = -1;
  269. int mem_free = -1;
  270. mem_used = s3eMemoryGetInt(S3E_MEMORY_USED);
  271. mem_free = s3eMemoryGetInt(S3E_MEMORY_FREE);
  272. s << "mfree=" << mem_free << " mem=" << mem_used << std::endl;
  273. #endif
  274. const IVideoDriver::Stats& vstats = IVideoDriver::_stats;
  275. #ifdef OXYGINE_DEBUG_TRACE_LEAKS
  276. s << "objects=" << (int)ObjectBase::__getCreatedObjects().size() << std::endl;
  277. #endif
  278. #if OXYGINE_TRACE_VIDEO_STATS
  279. int primitives = 0;
  280. primitives += vstats.elements[IVideoDriver::PT_TRIANGLES] / 3;
  281. if (vstats.elements[IVideoDriver::PT_TRIANGLE_STRIP])
  282. primitives += vstats.elements[IVideoDriver::PT_TRIANGLE_STRIP] - 2;
  283. s << "batches=" << aligned(vstats.batches, 3) << " primitives=" << aligned(primitives, 3) << std::endl;
  284. #endif
  285. s << "update=" << aligned(getStage()->_statUpdate, 2) << "ms ";
  286. s << "render=" << aligned(vstats.duration, 2) << "ms ";
  287. s << "textures=" << aligned(NativeTexture::created, 2) << " ";
  288. #ifdef __APPLE__
  289. size_t mem;
  290. iosGetMemoryUsage(mem);
  291. s << "memory=" << mem / 1024 << "kb ";
  292. #endif
  293. #ifdef __WIN32__
  294. PROCESS_MEMORY_COUNTERS_EX pmc;
  295. GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmc, sizeof(pmc));
  296. s << "memory=" << pmc.PrivateUsage / 1024 << "kb ";
  297. #endif
  298. if (!_debugText.empty())
  299. {
  300. s << "\n";
  301. s << _debugText;
  302. }
  303. _debugText = "";
  304. _text->setText(s.str());
  305. setHeight(_text->getTextRect().size.y + _text->getY() + 3);
  306. _bg->setSize(getSize());
  307. Vector2 ds = core::getDisplaySize();
  308. Vector2 pos(0, 0);
  309. switch (_corner)
  310. {
  311. case 1:
  312. pos.x = ds.x;
  313. break;
  314. case 2:
  315. pos = ds;
  316. break;
  317. case 3:
  318. pos.y = ds.y;
  319. break;
  320. }
  321. pos = getStage()->parent2local(pos);
  322. Vector2 realSize = getScaledSize();
  323. switch (_corner)
  324. {
  325. case 1:
  326. pos.x -= realSize.x;
  327. break;
  328. case 2:
  329. pos -= realSize;
  330. break;
  331. case 3:
  332. pos.y -= realSize.y;
  333. break;
  334. }
  335. //setPosition(pos);
  336. setScale(1.0f / getStage()->getScaleX());
  337. RenderState rs = parentRS;
  338. parentRS.material->finish();
  339. STDRenderer renderer;
  340. STDMaterial mat(&renderer);
  341. mat.apply(0);
  342. IVideoDriver* driver = renderer.getDriver();
  343. Rect vp(Point(0, 0), core::getDisplaySize());
  344. driver->setViewport(vp);
  345. renderer.initCoordinateSystem(vp.getWidth(), vp.getHeight());
  346. renderer.resetSettings();
  347. rs.material = &mat;
  348. Actor::render(rs);
  349. renderer.drawBatch();
  350. mat.finish();
  351. Material::setCurrent(0);
  352. timeMS dur = getTimeMS() - tm;
  353. IVideoDriver::_stats.start += dur;
  354. }
  355. void DebugActor::showTexel2PixelErrors(bool show)
  356. {
  357. _showTexel2PixelErrors = show;
  358. #ifdef OXYGINE_DEBUG_T2P
  359. STDRenderer::showTexel2PixelErrors(_showTexel2PixelErrors);
  360. spActor btn = getChild("t2p");
  361. btn->removeTweens(true);
  362. if (show)
  363. btn->addTween(Actor::TweenAlpha(0), 300, 999999, true);
  364. #endif
  365. }
  366. void DebugActor::showTouchedActor(bool show)
  367. {
  368. _getStage()->removeEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DebugActor::onEvent));
  369. _showTouchedActor = show;
  370. if (show)
  371. _getStage()->addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &DebugActor::onEvent));
  372. spActor btn = getChild("finger");
  373. btn->removeTweens(true);
  374. if (show)
  375. btn->addTween(Actor::TweenAlpha(0), 300, 999999, true);
  376. }
  377. void DebugActor::onDAEvent(Event* ev)
  378. {
  379. TouchEvent* t = safeCast<TouchEvent*>(ev);
  380. Vector2 loc = stage2local(t->localPosition, _getStage());
  381. if (t->type == TouchEvent::MOVE)
  382. {
  383. setAlpha(isOn(loc) ? 64 : 255);
  384. if (_dragging)
  385. {
  386. setPosition(t->localPosition - _local);
  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)->setDetachActor(true);
  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. }