DebugActor.cpp 12 KB

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