| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  editor_debugger_plugin.cpp                                            */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining  */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the        */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including    */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,    */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to     */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to  */ | 
					
						
							|  |  |  | /* the following conditions:                                              */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be         */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.        */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | #include "editor_debugger_plugin.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "editor/debugger/script_editor_debugger.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-15 13:25:58 -03:00
										 |  |  | void EditorDebuggerSession::_breaked(bool p_really_did, bool p_can_debug, const String &p_message, bool p_has_stackdump) { | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 	if (p_really_did) { | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 		emit_signal(SNAME("breaked"), p_can_debug); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 		emit_signal(SNAME("continued")); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::_started() { | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 	emit_signal(SNAME("started")); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::_stopped() { | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 	emit_signal(SNAME("stopped")); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("send_message", "message", "data"), &EditorDebuggerSession::send_message, DEFVAL(Array())); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("toggle_profiler", "profiler", "enable", "data"), &EditorDebuggerSession::toggle_profiler, DEFVAL(Array())); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_breaked"), &EditorDebuggerSession::is_breaked); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_debuggable"), &EditorDebuggerSession::is_debuggable); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_active"), &EditorDebuggerSession::is_active); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("add_session_tab", "control"), &EditorDebuggerSession::add_session_tab); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("remove_session_tab", "control"), &EditorDebuggerSession::remove_session_tab); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | 	ADD_SIGNAL(MethodInfo("started")); | 
					
						
							|  |  |  | 	ADD_SIGNAL(MethodInfo("stopped")); | 
					
						
							|  |  |  | 	ADD_SIGNAL(MethodInfo("breaked", PropertyInfo(Variant::BOOL, "can_debug"))); | 
					
						
							|  |  |  | 	ADD_SIGNAL(MethodInfo("continued")); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::add_session_tab(Control *p_tab) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!p_tab || !debugger); | 
					
						
							|  |  |  | 	debugger->add_debugger_tab(p_tab); | 
					
						
							|  |  |  | 	tabs.insert(p_tab); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::remove_session_tab(Control *p_tab) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!p_tab || !debugger); | 
					
						
							|  |  |  | 	debugger->remove_debugger_tab(p_tab); | 
					
						
							|  |  |  | 	tabs.erase(p_tab); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::send_message(const String &p_message, const Array &p_args) { | 
					
						
							| 
									
										
										
										
											2023-09-09 17:24:40 +02:00
										 |  |  | 	ERR_FAIL_NULL_MSG(debugger, "Plugin is not attached to debugger."); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 	debugger->send_message(p_message, p_args); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data) { | 
					
						
							| 
									
										
										
										
											2023-09-09 17:24:40 +02:00
										 |  |  | 	ERR_FAIL_NULL_MSG(debugger, "Plugin is not attached to debugger."); | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | 	debugger->toggle_profiler(p_profiler, p_enable, p_data); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | bool EditorDebuggerSession::is_breaked() { | 
					
						
							| 
									
										
										
										
											2023-09-09 17:24:40 +02:00
										 |  |  | 	ERR_FAIL_NULL_V_MSG(debugger, false, "Plugin is not attached to debugger."); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 	return debugger->is_breaked(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | bool EditorDebuggerSession::is_debuggable() { | 
					
						
							| 
									
										
										
										
											2023-09-09 17:24:40 +02:00
										 |  |  | 	ERR_FAIL_NULL_V_MSG(debugger, false, "Plugin is not attached to debugger."); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 	return debugger->is_debuggable(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | bool EditorDebuggerSession::is_active() { | 
					
						
							| 
									
										
										
										
											2023-09-09 17:24:40 +02:00
										 |  |  | 	ERR_FAIL_NULL_V_MSG(debugger, false, "Plugin is not attached to debugger."); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | 	return debugger->is_session_active(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | void EditorDebuggerSession::detach_debugger() { | 
					
						
							|  |  |  | 	if (!debugger) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	debugger->disconnect("started", callable_mp(this, &EditorDebuggerSession::_started)); | 
					
						
							|  |  |  | 	debugger->disconnect("stopped", callable_mp(this, &EditorDebuggerSession::_stopped)); | 
					
						
							|  |  |  | 	debugger->disconnect("breaked", callable_mp(this, &EditorDebuggerSession::_breaked)); | 
					
						
							|  |  |  | 	debugger->disconnect("tree_exited", callable_mp(this, &EditorDebuggerSession::_debugger_gone_away)); | 
					
						
							|  |  |  | 	for (Control *tab : tabs) { | 
					
						
							|  |  |  | 		debugger->remove_debugger_tab(tab); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	tabs.clear(); | 
					
						
							|  |  |  | 	debugger = nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorDebuggerSession::_debugger_gone_away() { | 
					
						
							|  |  |  | 	debugger = nullptr; | 
					
						
							|  |  |  | 	tabs.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EditorDebuggerSession::EditorDebuggerSession(ScriptEditorDebugger *p_debugger) { | 
					
						
							| 
									
										
										
										
											2023-09-09 17:24:40 +02:00
										 |  |  | 	ERR_FAIL_NULL(p_debugger); | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | 	debugger = p_debugger; | 
					
						
							|  |  |  | 	debugger->connect("started", callable_mp(this, &EditorDebuggerSession::_started)); | 
					
						
							|  |  |  | 	debugger->connect("stopped", callable_mp(this, &EditorDebuggerSession::_stopped)); | 
					
						
							|  |  |  | 	debugger->connect("breaked", callable_mp(this, &EditorDebuggerSession::_breaked)); | 
					
						
							|  |  |  | 	debugger->connect("tree_exited", callable_mp(this, &EditorDebuggerSession::_debugger_gone_away), CONNECT_ONE_SHOT); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EditorDebuggerSession::~EditorDebuggerSession() { | 
					
						
							|  |  |  | 	detach_debugger(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// EditorDebuggerPlugin
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | EditorDebuggerPlugin::~EditorDebuggerPlugin() { | 
					
						
							| 
									
										
										
										
											2022-10-03 15:21:25 +02:00
										 |  |  | 	clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorDebuggerPlugin::clear() { | 
					
						
							|  |  |  | 	for (int i = 0; i < sessions.size(); i++) { | 
					
						
							|  |  |  | 		sessions[i]->detach_debugger(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sessions.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorDebuggerPlugin::create_session(ScriptEditorDebugger *p_debugger) { | 
					
						
							|  |  |  | 	sessions.push_back(Ref<EditorDebuggerSession>(memnew(EditorDebuggerSession(p_debugger)))); | 
					
						
							|  |  |  | 	setup_session(sessions.size() - 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorDebuggerPlugin::setup_session(int p_idx) { | 
					
						
							|  |  |  | 	GDVIRTUAL_CALL(_setup_session, p_idx); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<EditorDebuggerSession> EditorDebuggerPlugin::get_session(int p_idx) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, sessions.size(), nullptr); | 
					
						
							|  |  |  | 	return sessions[p_idx]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Array EditorDebuggerPlugin::get_sessions() { | 
					
						
							|  |  |  | 	Array ret; | 
					
						
							|  |  |  | 	for (int i = 0; i < sessions.size(); i++) { | 
					
						
							|  |  |  | 		ret.push_back(sessions[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool EditorDebuggerPlugin::has_capture(const String &p_message) const { | 
					
						
							|  |  |  | 	bool ret = false; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_CALL(_has_capture, p_message, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool EditorDebuggerPlugin::capture(const String &p_message, const Array &p_data, int p_session_id) { | 
					
						
							|  |  |  | 	bool ret = false; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_CALL(_capture, p_message, p_data, p_session_id, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorDebuggerPlugin::_bind_methods() { | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_setup_session, "session_id"); | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_has_capture, "capture"); | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_capture, "message", "data", "session_id"); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_session", "id"), &EditorDebuggerPlugin::get_session); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_sessions"), &EditorDebuggerPlugin::get_sessions); | 
					
						
							| 
									
										
										
										
											2020-05-18 20:25:49 +05:30
										 |  |  | } |