diff options
author | Fabio Alessandrelli <fabio.alessandrelli@gmail.com> | 2020-03-11 11:23:21 +0100 |
---|---|---|
committer | Fabio Alessandrelli <fabio.alessandrelli@gmail.com> | 2020-05-12 15:09:13 +0200 |
commit | ed225faf31c9b3aa47154260aa1a7826d728acc8 (patch) | |
tree | 9b4ae87b8b500582afd4d1501e98471b874d4d28 | |
parent | beb87504e076afeb37e5f2765c8417f92a044e13 (diff) |
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).
-rw-r--r-- | core/debugger/engine_debugger.cpp | 44 | ||||
-rw-r--r-- | core/debugger/engine_debugger.h | 7 | ||||
-rw-r--r-- | core/debugger/remote_debugger.cpp | 10 | ||||
-rw-r--r-- | core/debugger/remote_debugger.h | 2 | ||||
-rw-r--r-- | core/debugger/remote_debugger_peer.cpp | 14 | ||||
-rw-r--r-- | core/debugger/remote_debugger_peer.h | 4 |
6 files changed, 50 insertions, 31 deletions
diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp index bfe38d0f4a..04eba84b30 100644 --- a/core/debugger/engine_debugger.cpp +++ b/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() { diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h index 7b6b77ca9b..8d5ebb2394 100644 --- a/core/debugger/engine_debugger.h +++ b/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); diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index 97d5c71b6f..18c9602eb2 100644 --- a/core/debugger/remote_debugger.cpp +++ b/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"); diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h index cac0bc3730..dc7e4436e1 100644 --- a/core/debugger/remote_debugger.h +++ b/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); diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp index ed04431177..458c46df93 100644 --- a/core/debugger/remote_debugger_peer.cpp +++ b/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; } diff --git a/core/debugger/remote_debugger_peer.h b/core/debugger/remote_debugger_peer.h index e4b838f145..3a75a2a02b 100644 --- a/core/debugger/remote_debugger_peer.h +++ b/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(); |