editor_debugger_plugin.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**************************************************************************/
  2. /* editor_debugger_plugin.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "editor_debugger_plugin.h"
  31. #include "editor/debugger/script_editor_debugger.h"
  32. void EditorDebuggerSession::_breaked(bool p_really_did, bool p_can_debug, const String &p_message, bool p_has_stackdump) {
  33. if (p_really_did) {
  34. emit_signal(SNAME("breaked"), p_can_debug);
  35. } else {
  36. emit_signal(SNAME("continued"));
  37. }
  38. }
  39. void EditorDebuggerSession::_started() {
  40. emit_signal(SNAME("started"));
  41. }
  42. void EditorDebuggerSession::_stopped() {
  43. emit_signal(SNAME("stopped"));
  44. }
  45. void EditorDebuggerSession::_bind_methods() {
  46. ClassDB::bind_method(D_METHOD("send_message", "message", "data"), &EditorDebuggerSession::send_message, DEFVAL(Array()));
  47. ClassDB::bind_method(D_METHOD("toggle_profiler", "profiler", "enable", "data"), &EditorDebuggerSession::toggle_profiler, DEFVAL(Array()));
  48. ClassDB::bind_method(D_METHOD("is_breaked"), &EditorDebuggerSession::is_breaked);
  49. ClassDB::bind_method(D_METHOD("is_debuggable"), &EditorDebuggerSession::is_debuggable);
  50. ClassDB::bind_method(D_METHOD("is_active"), &EditorDebuggerSession::is_active);
  51. ClassDB::bind_method(D_METHOD("add_session_tab", "control"), &EditorDebuggerSession::add_session_tab);
  52. ClassDB::bind_method(D_METHOD("remove_session_tab", "control"), &EditorDebuggerSession::remove_session_tab);
  53. ADD_SIGNAL(MethodInfo("started"));
  54. ADD_SIGNAL(MethodInfo("stopped"));
  55. ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "can_debug")));
  56. ADD_SIGNAL(MethodInfo("continued"));
  57. }
  58. void EditorDebuggerSession::add_session_tab(Control *p_tab) {
  59. ERR_FAIL_COND(!p_tab || !debugger);
  60. debugger->add_debugger_tab(p_tab);
  61. tabs.insert(p_tab);
  62. }
  63. void EditorDebuggerSession::remove_session_tab(Control *p_tab) {
  64. ERR_FAIL_COND(!p_tab || !debugger);
  65. debugger->remove_debugger_tab(p_tab);
  66. tabs.erase(p_tab);
  67. }
  68. void EditorDebuggerSession::send_message(const String &p_message, const Array &p_args) {
  69. ERR_FAIL_NULL_MSG(debugger, "Plugin is not attached to debugger.");
  70. debugger->send_message(p_message, p_args);
  71. }
  72. void EditorDebuggerSession::toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data) {
  73. ERR_FAIL_NULL_MSG(debugger, "Plugin is not attached to debugger.");
  74. debugger->toggle_profiler(p_profiler, p_enable, p_data);
  75. }
  76. bool EditorDebuggerSession::is_breaked() {
  77. ERR_FAIL_NULL_V_MSG(debugger, false, "Plugin is not attached to debugger.");
  78. return debugger->is_breaked();
  79. }
  80. bool EditorDebuggerSession::is_debuggable() {
  81. ERR_FAIL_NULL_V_MSG(debugger, false, "Plugin is not attached to debugger.");
  82. return debugger->is_debuggable();
  83. }
  84. bool EditorDebuggerSession::is_active() {
  85. ERR_FAIL_NULL_V_MSG(debugger, false, "Plugin is not attached to debugger.");
  86. return debugger->is_session_active();
  87. }
  88. void EditorDebuggerSession::detach_debugger() {
  89. if (!debugger) {
  90. return;
  91. }
  92. debugger->disconnect("started", callable_mp(this, &EditorDebuggerSession::_started));
  93. debugger->disconnect("stopped", callable_mp(this, &EditorDebuggerSession::_stopped));
  94. debugger->disconnect("breaked", callable_mp(this, &EditorDebuggerSession::_breaked));
  95. debugger->disconnect(SceneStringName(tree_exited), callable_mp(this, &EditorDebuggerSession::_debugger_gone_away));
  96. for (Control *tab : tabs) {
  97. debugger->remove_debugger_tab(tab);
  98. }
  99. tabs.clear();
  100. debugger = nullptr;
  101. }
  102. void EditorDebuggerSession::_debugger_gone_away() {
  103. debugger = nullptr;
  104. tabs.clear();
  105. }
  106. EditorDebuggerSession::EditorDebuggerSession(ScriptEditorDebugger *p_debugger) {
  107. ERR_FAIL_NULL(p_debugger);
  108. debugger = p_debugger;
  109. debugger->connect("started", callable_mp(this, &EditorDebuggerSession::_started));
  110. debugger->connect("stopped", callable_mp(this, &EditorDebuggerSession::_stopped));
  111. debugger->connect("breaked", callable_mp(this, &EditorDebuggerSession::_breaked));
  112. debugger->connect(SceneStringName(tree_exited), callable_mp(this, &EditorDebuggerSession::_debugger_gone_away), CONNECT_ONE_SHOT);
  113. }
  114. EditorDebuggerSession::~EditorDebuggerSession() {
  115. detach_debugger();
  116. }
  117. /// EditorDebuggerPlugin
  118. EditorDebuggerPlugin::~EditorDebuggerPlugin() {
  119. clear();
  120. }
  121. void EditorDebuggerPlugin::clear() {
  122. for (Ref<EditorDebuggerSession> &session : sessions) {
  123. session->detach_debugger();
  124. }
  125. sessions.clear();
  126. }
  127. void EditorDebuggerPlugin::create_session(ScriptEditorDebugger *p_debugger) {
  128. sessions.push_back(Ref<EditorDebuggerSession>(memnew(EditorDebuggerSession(p_debugger))));
  129. setup_session(sessions.size() - 1);
  130. }
  131. void EditorDebuggerPlugin::setup_session(int p_idx) {
  132. GDVIRTUAL_CALL(_setup_session, p_idx);
  133. }
  134. Ref<EditorDebuggerSession> EditorDebuggerPlugin::get_session(int p_idx) {
  135. ERR_FAIL_INDEX_V(p_idx, sessions.size(), nullptr);
  136. return sessions.get(p_idx);
  137. }
  138. Array EditorDebuggerPlugin::get_sessions() {
  139. Array ret;
  140. for (const Ref<EditorDebuggerSession> &session : sessions) {
  141. ret.push_back(session);
  142. }
  143. return ret;
  144. }
  145. bool EditorDebuggerPlugin::has_capture(const String &p_message) const {
  146. bool ret = false;
  147. if (GDVIRTUAL_CALL(_has_capture, p_message, ret)) {
  148. return ret;
  149. }
  150. return false;
  151. }
  152. bool EditorDebuggerPlugin::capture(const String &p_message, const Array &p_data, int p_session_id) {
  153. bool ret = false;
  154. if (GDVIRTUAL_CALL(_capture, p_message, p_data, p_session_id, ret)) {
  155. return ret;
  156. }
  157. return false;
  158. }
  159. void EditorDebuggerPlugin::_bind_methods() {
  160. GDVIRTUAL_BIND(_setup_session, "session_id");
  161. GDVIRTUAL_BIND(_has_capture, "capture");
  162. GDVIRTUAL_BIND(_capture, "message", "data", "session_id");
  163. ClassDB::bind_method(D_METHOD("get_session", "id"), &EditorDebuggerPlugin::get_session);
  164. ClassDB::bind_method(D_METHOD("get_sessions"), &EditorDebuggerPlugin::get_sessions);
  165. }