diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index 23ee977df4..a2e3fab82c 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -39,89 +39,6 @@ #include "core/object/script_language.h" #include "core/os/os.h" -class RemoteDebugger::MultiplayerProfiler : public EngineProfiler { - struct BandwidthFrame { - uint32_t timestamp; - int packet_size; - }; - - int bandwidth_in_ptr = 0; - Vector bandwidth_in; - int bandwidth_out_ptr = 0; - Vector bandwidth_out; - uint64_t last_bandwidth_time = 0; - - int bandwidth_usage(const Vector &p_buffer, int p_pointer) { - ERR_FAIL_COND_V(p_buffer.size() == 0, 0); - int total_bandwidth = 0; - - uint64_t timestamp = OS::get_singleton()->get_ticks_msec(); - uint64_t final_timestamp = timestamp - 1000; - - int i = (p_pointer + p_buffer.size() - 1) % p_buffer.size(); - - while (i != p_pointer && p_buffer[i].packet_size > 0) { - if (p_buffer[i].timestamp < final_timestamp) { - return total_bandwidth; - } - total_bandwidth += p_buffer[i].packet_size; - i = (i + p_buffer.size() - 1) % p_buffer.size(); - } - - ERR_FAIL_COND_V_MSG(i == p_pointer, total_bandwidth, "Reached the end of the bandwidth profiler buffer, values might be inaccurate."); - return total_bandwidth; - } - -public: - void toggle(bool p_enable, const Array &p_opts) { - if (!p_enable) { - bandwidth_in.clear(); - bandwidth_out.clear(); - } else { - bandwidth_in_ptr = 0; - bandwidth_in.resize(16384); // ~128kB - for (int i = 0; i < bandwidth_in.size(); ++i) { - bandwidth_in.write[i].packet_size = -1; - } - bandwidth_out_ptr = 0; - bandwidth_out.resize(16384); // ~128kB - for (int i = 0; i < bandwidth_out.size(); ++i) { - bandwidth_out.write[i].packet_size = -1; - } - } - } - - void add(const Array &p_data) { - ERR_FAIL_COND(p_data.size() < 3); - const String inout = p_data[0]; - int time = p_data[1]; - int size = p_data[2]; - if (inout == "in") { - bandwidth_in.write[bandwidth_in_ptr].timestamp = time; - bandwidth_in.write[bandwidth_in_ptr].packet_size = size; - bandwidth_in_ptr = (bandwidth_in_ptr + 1) % bandwidth_in.size(); - } else if (inout == "out") { - bandwidth_out.write[bandwidth_out_ptr].timestamp = time; - bandwidth_out.write[bandwidth_out_ptr].packet_size = size; - bandwidth_out_ptr = (bandwidth_out_ptr + 1) % bandwidth_out.size(); - } - } - - void tick(double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time) { - uint64_t pt = OS::get_singleton()->get_ticks_msec(); - if (pt - last_bandwidth_time > 200) { - last_bandwidth_time = pt; - int incoming_bandwidth = bandwidth_usage(bandwidth_in, bandwidth_in_ptr); - int outgoing_bandwidth = bandwidth_usage(bandwidth_out, bandwidth_out_ptr); - - Array arr; - arr.push_back(incoming_bandwidth); - arr.push_back(outgoing_bandwidth); - EngineDebugger::get_singleton()->send_message("multiplayer:bandwidth", arr); - } - } -}; - class RemoteDebugger::PerformanceProfiler : public EngineProfiler { Object *performance = nullptr; int last_perf_time = 0; @@ -659,10 +576,6 @@ RemoteDebugger::RemoteDebugger(Ref p_peer) { max_errors_per_second = GLOBAL_GET("network/limits/debugger/max_errors_per_second"); max_warnings_per_second = GLOBAL_GET("network/limits/debugger/max_warnings_per_second"); - // Multiplayer Profiler - multiplayer_profiler.instantiate(); - multiplayer_profiler->bind("multiplayer"); - // Performance Profiler Object *perf = Engine::get_singleton()->get_singleton_object("Performance"); if (perf) { diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h index fe4bbe86ea..944229d361 100644 --- a/core/debugger/remote_debugger.h +++ b/core/debugger/remote_debugger.h @@ -50,10 +50,8 @@ public: private: typedef DebuggerMarshalls::OutputError ErrorMessage; - class MultiplayerProfiler; class PerformanceProfiler; - Ref multiplayer_profiler; Ref performance_profiler; Ref peer; diff --git a/doc/classes/EditorDebuggerPlugin.xml b/doc/classes/EditorDebuggerPlugin.xml index c3e0a995c6..10da1edd56 100644 --- a/doc/classes/EditorDebuggerPlugin.xml +++ b/doc/classes/EditorDebuggerPlugin.xml @@ -1,88 +1,88 @@ - + A base class to implement debugger plugins. [EditorDebuggerPlugin] provides functions related to the editor side of the debugger. - You don't need to instantiate this class; that is automatically handled by the debugger. [Control] nodes can be added as child nodes to provide a GUI for the plugin. - Do not free or reparent this node, otherwise it becomes unusable. - To use [EditorDebuggerPlugin], register it using the [method EditorPlugin.add_debugger_plugin] method first. + To interact with the debugger, an instance of this class must be added to the editor via [method EditorPlugin.add_debugger_plugin]. + Once added, the [method _setup_session] callback will be called for every [EditorDebuggerSession] available to the plugin, and when new ones are created (the sessions may be inactive during this stage). + You can retrieve the available [EditorDebuggerSession]s via [method get_sessions] or get a specific one via [method get_session]. + [codeblocks] + [gdscript] + @tool + extends EditorPlugin + + class ExampleEditorDebugger extends EditorDebuggerPlugin: + + func _has_capture(prefix): + # Return true if you wish to handle message with this prefix. + return prefix == "my_plugin" + + func _capture(message, data, session_id): + if message == "my_plugin:ping": + get_session(session_id).send_message("my_plugin:echo", data) + + func _setup_session(session_id): + # Add a new tab in the debugger session UI containing a label. + var label = Label.new() + label.name = "Example plugin" + label.text = "Example plugin" + var session = get_session(session_id) + # Listens to the session started and stopped signals. + session.started.connect(func (): print("Session started")) + session.stopped.connect(func (): print("Session stopped")) + session.add_session_tab(label) + + var debugger = ExampleEditorDebugger.new() + + func _enter_tree(): + add_debugger_plugin(debugger) + + func _exit_tree(): + remove_debugger_plugin(debugger) + [/gdscript] + [/codeblocks] - + - - - Returns [code]true[/code] if a message capture with given name is present otherwise [code]false[/code]. - - - - - - Returns [code]true[/code] if the game is in break state otherwise [code]false[/code]. - - - - - - Returns [code]true[/code] if the game can be debugged otherwise [code]false[/code]. - - - - - - Returns [code]true[/code] if there is an instance of the game running with the attached debugger otherwise [code]false[/code]. - - - - - - - - Registers a message capture with given [param name]. If [param name] is "my_message" then messages starting with "my_message:" will be called with the given callable. - Callable must accept a message string and a data array as argument. If the message and data are valid then callable must return [code]true[/code] otherwise [code]false[/code]. - - - - + - Sends a message with given [param message] and [param data] array. + Override this method to process incoming messages. The [param session_id] is the ID of the [EditorDebuggerSession] that received the message (which you can retrieve via [method get_session]). - - - + + + - Unregisters the message capture with given name. + Override this method to enable receiving messages from the debugger. If [param capture] is "my_message" then messages starting with "my_message:" will be passes to the [method _capture] method. + + + + + + + Override this method to be notified whenever a new [EditorDebuggerSession] is created (the session may be inactive during this stage). + + + + + + + Returns the [EditorDebuggerSession] with the given [param id]. + + + + + + Returns an array of [EditorDebuggerSession] currently available to this debugger plugin. + Note: Not sessions in the array may be inactive, check their state via [method EditorDebuggerSession.is_active] - - - - - Emitted when the game enters a break state. - - - - - Emitted when the game exists a break state. - - - - - Emitted when the debugging starts. - - - - - Emitted when the debugging stops. - - - diff --git a/doc/classes/EditorDebuggerSession.xml b/doc/classes/EditorDebuggerSession.xml new file mode 100644 index 0000000000..faf528c143 --- /dev/null +++ b/doc/classes/EditorDebuggerSession.xml @@ -0,0 +1,86 @@ + + + + A class to interact with the editor debugger. + + + This class cannot be directly instantiated and must be retrieved via a [EditorDebuggerPlugin]. + You can add tabs to the session UI via [method add_session_tab], send messages via [method send_message], and toggle [EngineProfiler]s via [method toggle_profiler]. + + + + + + + + + Adds the given [param control] to the debug session UI in the debugger bottom panel. + + + + + + Returns [code]true[/code] if the debug session is currently attached to a remote instance. + + + + + + Returns [code]true[/code] if the attached remote instance is currently in the debug loop. + + + + + + Returns [code]true[/code] if the attached remote instance can be debugged. + + + + + + + Removes the given [param control] from the debug session UI in the debugger bottom panel. + + + + + + + + Sends the given [param message] to the attached remote instance, optionally passing additionally [param data]. See [EngineDebugger] for how to retrieve those messages. + + + + + + + + + Toggle the given [param profiler] on the attached remote instance, optionally passing additionally [param data]. See [EngineProfiler] for more details. + + + + + + + + Emitted when the attached remote instance enters a break state. If [param can_debug] is [code]true[/code], the remote instance will enter the debug loop. + + + + + Emitted when the attached remote instance exits a break state. + + + + + Emitted when a remote instance is attached to this session (i.e. the session becomes active). + + + + + Emitted when a remote instance is detached from this session (i.e. the session becomes inactive). + + + + diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index 2289a373bf..806588d100 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -415,7 +415,7 @@ - + Adds a [Script] as debugger plugin to the Debugger. The script must extend [EditorDebuggerPlugin]. @@ -599,7 +599,7 @@ - + Removes the debugger plugin with given script from the Debugger. diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 68aff328ed..49fbaa81bc 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -119,8 +119,8 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { } if (!debugger_plugins.is_empty()) { - for (const Ref