DebugActor.cpp 12 KB

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