Ver código fonte

Add support for multiple RemoteDebuggerPeer(s).

It is now possible to register protocol handlers (default tcp://) to
support additional debugging communication layers (e.g. websocket).
Fabio Alessandrelli 5 anos atrás
pai
commit
ed225faf31

+ 29 - 15
core/debugger/engine_debugger.cpp

@@ -32,6 +32,7 @@
 
 #include "core/debugger/local_debugger.h"
 #include "core/debugger/remote_debugger.h"
+#include "core/debugger/remote_debugger_peer.h"
 #include "core/debugger/script_debugger.h"
 #include "core/os/os.h"
 
@@ -40,6 +41,7 @@ ScriptDebugger *EngineDebugger::script_debugger = nullptr;
 
 Map<StringName, EngineDebugger::Profiler> EngineDebugger::profilers;
 Map<StringName, EngineDebugger::Capture> EngineDebugger::captures;
+Map<String, EngineDebugger::CreatePeerFunc> EngineDebugger::protocols;
 
 void EngineDebugger::register_profiler(const StringName &p_name, const Profiler &p_func) {
 	ERR_FAIL_COND_MSG(profilers.has(p_name), "Profiler already registered: " + p_name);
@@ -66,6 +68,11 @@ void EngineDebugger::unregister_message_capture(const StringName &p_name) {
 	captures.erase(p_name);
 }
 
+void EngineDebugger::register_uri_handler(const String &p_protocol, CreatePeerFunc p_func) {
+	ERR_FAIL_COND_MSG(protocols.has(p_protocol), "Protocol handler already registered: " + p_protocol);
+	protocols.insert(p_protocol, p_func);
+}
+
 void EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts) {
 	ERR_FAIL_COND_MSG(!profilers.has(p_name), "Can't change profiler state, no profiler: " + p_name);
 	Profiler &p = profilers[p_name];
@@ -125,6 +132,7 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, ui
 }
 
 void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) {
+	register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
 	if (p_uri.empty())
 		return;
 	if (p_uri == "local://") {
@@ -132,10 +140,14 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
 		script_debugger = memnew(ScriptDebugger);
 		// Tell the OS that we want to handle termination signals.
 		OS::get_singleton()->initialize_debugging();
-	} else {
-		singleton = RemoteDebugger::create_for_uri(p_uri);
-		if (!singleton)
+	} else if (p_uri.find("://") >= 0) {
+		const String proto = p_uri.substr(0, p_uri.find("://") + 3);
+		if (!protocols.has(proto))
+			return;
+		RemoteDebuggerPeer *peer = protocols[proto](p_uri);
+		if (!peer)
 			return;
+		singleton = memnew(RemoteDebugger(Ref<RemoteDebuggerPeer>(peer)));
 		script_debugger = memnew(ScriptDebugger);
 		// Notify editor of our pid (to allow focus stealing).
 		Array msg;
@@ -160,22 +172,24 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
 }
 
 void EngineDebugger::deinitialize() {
-	if (!singleton)
-		return;
-
-	// Stop all profilers
-	for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
-		if (E->get().active)
-			singleton->profiler_enable(E->key(), false);
+	if (singleton) {
+		// Stop all profilers
+		for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
+			if (E->get().active)
+				singleton->profiler_enable(E->key(), false);
+		}
+
+		// Flush any remaining message
+		singleton->poll_events(false);
+
+		memdelete(singleton);
+		singleton = nullptr;
 	}
 
-	// Flush any remaining message
-	singleton->poll_events(false);
-
-	memdelete(singleton);
-	singleton = nullptr;
+	// Clear profilers/captuers/protocol handlers.
 	profilers.clear();
 	captures.clear();
+	protocols.clear();
 }
 
 EngineDebugger::~EngineDebugger() {

+ 7 - 0
core/debugger/engine_debugger.h

@@ -38,6 +38,7 @@
 #include "core/variant.h"
 #include "core/vector.h"
 
+class RemoteDebuggerPeer;
 class ScriptDebugger;
 
 class EngineDebugger {
@@ -45,8 +46,11 @@ public:
 	typedef void (*ProfilingToggle)(void *p_user, bool p_enable, const Array &p_opts);
 	typedef void (*ProfilingTick)(void *p_user, float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time);
 	typedef void (*ProfilingAdd)(void *p_user, const Array &p_arr);
+
 	typedef Error (*CaptureFunc)(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
 
+	typedef RemoteDebuggerPeer *(*CreatePeerFunc)(const String &p_uri);
+
 	class Profiler {
 		friend class EngineDebugger;
 
@@ -94,6 +98,7 @@ protected:
 
 	static Map<StringName, Profiler> profilers;
 	static Map<StringName, Capture> captures;
+	static Map<String, CreatePeerFunc> protocols;
 
 public:
 	_FORCE_INLINE_ static EngineDebugger *get_singleton() { return singleton; }
@@ -113,6 +118,8 @@ public:
 	static void unregister_message_capture(const StringName &p_name);
 	static bool has_capture(const StringName &p_name);
 
+	static void register_uri_handler(const String &p_protocol, CreatePeerFunc p_func);
+
 	void iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, uint64_t p_physics_ticks, float p_physics_frame_time);
 	void profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts = Array());
 	Error capture_parse(const StringName &p_name, const String &p_msg, const Array &p_args, bool &r_captured);

+ 3 - 7
core/debugger/remote_debugger.cpp

@@ -673,6 +673,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
 
 	ERR_FAIL_COND_MSG(!is_peer_connected(), "Script Debugger failed to connect, but being used anyway.");
 
+	if (!peer->can_block())
+		return; // Peer does not support blocking IO. We could at least send the error though.
+
 	ScriptLanguage *script_lang = script_debugger->get_break_language();
 	const String error_str = script_lang ? script_lang->debug_get_error() : "";
 	Array msg;
@@ -886,13 +889,6 @@ Error RemoteDebugger::_profiler_capture(const String &p_cmd, const Array &p_data
 	return OK;
 }
 
-RemoteDebugger *RemoteDebugger::create_for_uri(const String &p_uri) {
-	Ref<RemoteDebuggerPeer> peer = RemoteDebuggerPeer::create_from_uri(p_uri);
-	if (peer.is_valid())
-		return memnew(RemoteDebugger(peer));
-	return nullptr;
-}
-
 RemoteDebugger::RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer) {
 	peer = p_peer;
 	max_chars_per_second = GLOBAL_GET("network/limits/debugger/max_chars_per_second");

+ 0 - 2
core/debugger/remote_debugger.h

@@ -108,8 +108,6 @@ private:
 	Error _try_capture(const String &p_name, const Array &p_data, bool &r_captured);
 
 public:
-	static RemoteDebugger *create_for_uri(const String &p_uri);
-
 	// Overrides
 	void poll_events(bool p_is_idle);
 	void send_message(const String &p_message, const Array &p_args);

+ 8 - 6
core/debugger/remote_debugger_peer.cpp

@@ -218,9 +218,8 @@ void RemoteDebuggerPeerTCP::_poll() {
 	}
 }
 
-Ref<RemoteDebuggerPeer> RemoteDebuggerPeer::create_from_uri(const String p_uri) {
-	if (!p_uri.begins_with("tcp://"))
-		return Ref<RemoteDebuggerPeer>(); // Only TCP supported for now, more to come.
+RemoteDebuggerPeer *RemoteDebuggerPeerTCP::create(const String &p_uri) {
+	ERR_FAIL_COND_V(!p_uri.begins_with("tcp://"), nullptr);
 
 	String debug_host = p_uri.replace("tcp://", "");
 	uint16_t debug_port = 6007;
@@ -230,10 +229,13 @@ Ref<RemoteDebuggerPeer> RemoteDebuggerPeer::create_from_uri(const String p_uri)
 		debug_port = debug_host.substr(sep_pos + 1).to_int();
 		debug_host = debug_host.substr(0, sep_pos);
 	}
-	Ref<RemoteDebuggerPeerTCP> peer = Ref<RemoteDebuggerPeer>(memnew(RemoteDebuggerPeerTCP));
+
+	RemoteDebuggerPeerTCP *peer = memnew(RemoteDebuggerPeerTCP);
 	Error err = peer->connect_to_host(debug_host, debug_port);
-	if (err != OK)
-		return Ref<RemoteDebuggerPeer>();
+	if (err != OK) {
+		memdelete(peer);
+		return nullptr;
+	}
 	return peer;
 }
 

+ 3 - 1
core/debugger/remote_debugger_peer.h

@@ -42,7 +42,6 @@ protected:
 	int max_queued_messages = 4096;
 
 public:
-	static Ref<RemoteDebuggerPeer> create_from_uri(const String p_uri);
 	virtual bool is_peer_connected() = 0;
 	virtual bool has_message() = 0;
 	virtual Error put_message(const Array &p_arr) = 0;
@@ -50,6 +49,7 @@ public:
 	virtual void close() = 0;
 	virtual void poll() = 0;
 	virtual int get_max_message_size() const = 0;
+	virtual bool can_block() const { return true; } // If blocking io is allowed on main thread (debug).
 
 	RemoteDebuggerPeer();
 };
@@ -77,6 +77,8 @@ private:
 	void _read_in();
 
 public:
+	static RemoteDebuggerPeer *create(const String &p_uri);
+
 	Error connect_to_host(const String &p_host, uint16_t p_port);
 
 	void poll();