Threaded networking for editor debugger.

This commit is contained in:
Fabio Alessandrelli 2020-02-24 06:21:15 +01:00
parent 74051c77dc
commit 540ca05a80
10 changed files with 385 additions and 100 deletions

View file

@ -31,9 +31,12 @@
#include "editor_debugger_node.h"
#include "editor/debugger/editor_debugger_tree.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "editor/plugins/script_editor_plugin.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/tab_container.h"
template <typename Func>
void _for_all(TabContainer *p_node, const Func &p_func) {
@ -49,7 +52,6 @@ EditorDebuggerNode *EditorDebuggerNode::singleton = NULL;
EditorDebuggerNode::EditorDebuggerNode() {
if (!singleton)
singleton = this;
server.instance();
add_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT));
add_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_RIGHT));
@ -179,10 +181,9 @@ Error EditorDebuggerNode::start() {
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
}
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
const Error err = server->listen(remote_port);
server = Ref<EditorDebuggerServer>(EditorDebuggerServer::create_default());
const Error err = server->start();
if (err != OK) {
EditorNode::get_log()->add_message(String("Error listening on port ") + itos(remote_port), EditorLog::MSG_TYPE_ERROR);
return err;
}
set_process(true);
@ -191,9 +192,10 @@ Error EditorDebuggerNode::start() {
}
void EditorDebuggerNode::stop() {
if (server->is_listening()) {
if (server.is_valid()) {
server->stop();
EditorNode::get_log()->add_message("--- Debugging process stopped ---", EditorLog::MSG_TYPE_EDITOR);
server.unref();
}
// Also close all debugging sessions.
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
@ -231,9 +233,14 @@ void EditorDebuggerNode::_notification(int p_what) {
break;
}
if (p_what != NOTIFICATION_PROCESS || !server->is_listening())
if (p_what != NOTIFICATION_PROCESS || !server.is_valid())
return;
if (!server.is_valid() || !server->is_active()) {
stop();
return;
}
// Errors and warnings
int error_count = 0;
int warning_count = 0;
@ -293,9 +300,8 @@ void EditorDebuggerNode::_notification(int p_what) {
if (tabs->get_tab_count() <= 4) { // Max 4 debugging sessions active.
debugger = _add_debugger();
} else {
// We already have too many sessions, disconnecting new clients to prevent it from hanging.
// (Not keeping a reference to the connection will disconnect it)
server->take_connection();
// We already have too many sessions, disconnecting new clients to prevent them from hanging.
server->take_connection()->close();
return; // Can't add, stop here.
}
}
@ -462,6 +468,26 @@ void EditorDebuggerNode::reload_scripts() {
});
}
void EditorDebuggerNode::debug_next() {
get_default_debugger()->debug_next();
}
void EditorDebuggerNode::debug_step() {
get_default_debugger()->debug_step();
}
void EditorDebuggerNode::debug_break() {
get_default_debugger()->debug_break();
}
void EditorDebuggerNode::debug_continue() {
get_default_debugger()->debug_continue();
}
String EditorDebuggerNode::get_var_value(const String &p_var) const {
return get_default_debugger()->get_var_value(p_var);
}
// LiveEdit/Inspector
void EditorDebuggerNode::request_remote_tree() {
get_current_debugger()->request_remote_tree();

View file

@ -31,17 +31,30 @@
#ifndef EDITOR_DEBUGGER_NODE_H
#define EDITOR_DEBUGGER_NODE_H
#include "core/io/tcp_server.h"
#include "editor/debugger/script_editor_debugger.h"
#include "scene/gui/button.h"
#include "scene/gui/tab_container.h"
#include "editor/debugger/editor_debugger_server.h"
#include "scene/gui/margin_container.h"
class Button;
class EditorDebuggerTree;
class EditorDebuggerRemoteObject;
class MenuButton;
class ScriptEditorDebugger;
class TabContainer;
class EditorDebuggerNode : public MarginContainer {
GDCLASS(EditorDebuggerNode, MarginContainer);
public:
enum CameraOverride {
OVERRIDE_NONE,
OVERRIDE_2D,
OVERRIDE_3D_1, // 3D Viewport 1
OVERRIDE_3D_2, // 3D Viewport 2
OVERRIDE_3D_3, // 3D Viewport 3
OVERRIDE_3D_4 // 3D Viewport 4
};
private:
enum Options {
DEBUG_NEXT,
@ -71,7 +84,7 @@ private:
}
};
Ref<TCP_Server> server = NULL;
Ref<EditorDebuggerServer> server;
TabContainer *tabs = NULL;
Button *debugger_button = NULL;
MenuButton *script_menu = NULL;
@ -87,7 +100,7 @@ private:
bool auto_switch_remote_scene_tree = false;
bool debug_with_external_editor = false;
bool hide_on_stop = true;
ScriptEditorDebugger::CameraOverride camera_override = ScriptEditorDebugger::OVERRIDE_NONE;
CameraOverride camera_override = OVERRIDE_NONE;
Map<Breakpoint, bool> breakpoints;
ScriptEditorDebugger *_add_debugger();
@ -130,10 +143,10 @@ public:
ScriptEditorDebugger *get_default_debugger() const;
ScriptEditorDebugger *get_debugger(int p_debugger) const;
void debug_next() { get_default_debugger()->debug_next(); }
void debug_step() { get_default_debugger()->debug_step(); }
void debug_break() { get_default_debugger()->debug_break(); }
void debug_continue() { get_default_debugger()->debug_continue(); }
void debug_next();
void debug_step();
void debug_break();
void debug_continue();
void set_script_debug_button(MenuButton *p_button);
@ -141,7 +154,7 @@ public:
debugger_button = p_button;
}
String get_var_value(const String &p_var) const { return get_default_debugger()->get_var_value(p_var); }
String get_var_value(const String &p_var) const;
Ref<Script> get_dump_stack_script() const { return stack_script; } // Why do we need this?
bool get_debug_with_external_editor() { return debug_with_external_editor; }
@ -167,8 +180,8 @@ public:
void live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
// Camera
void set_camera_override(ScriptEditorDebugger::CameraOverride p_override) { camera_override = p_override; }
ScriptEditorDebugger::CameraOverride get_camera_override() { return camera_override; }
void set_camera_override(CameraOverride p_override) { camera_override = p_override; }
CameraOverride get_camera_override() { return camera_override; }
Error start();

View file

@ -0,0 +1,216 @@
/*************************************************************************/
/* editor_debugger_server.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* 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. */
/*************************************************************************/
#include "editor_debugger_server.h"
#include "core/io/packet_peer.h"
#include "core/io/tcp_server.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
class EditorDebuggerPeerTCP : public EditorDebuggerPeer {
private:
enum {
QUEUE_MAX = 2048,
POLL_USEC_MAX = 100,
};
Ref<StreamPeerTCP> tcp;
Ref<PacketPeerStream> packet_peer;
List<Array> out_queue;
List<Array> in_queue;
Mutex mutex;
bool connected = false;
public:
Error poll() {
MutexLock lock(mutex);
connected = tcp->get_status() == StreamPeerTCP::STATUS_CONNECTED;
Error err = OK;
uint64_t ticks = OS::get_singleton()->get_ticks_usec();
while (connected && packet_peer->get_available_packet_count() > 0 && in_queue.size() < QUEUE_MAX && OS::get_singleton()->get_ticks_usec() - ticks < POLL_USEC_MAX) {
Variant var;
err = packet_peer->get_var(var);
connected = tcp->get_status() == StreamPeerTCP::STATUS_CONNECTED;
if (err != OK) {
ERR_PRINT("Error reading variant from peer");
break;
}
ERR_CONTINUE_MSG(var.get_type() != Variant::ARRAY, "Malformed packet received, not an Array.");
in_queue.push_back(var);
}
ticks = OS::get_singleton()->get_ticks_usec();
while (connected && out_queue.size() > 0 && OS::get_singleton()->get_ticks_usec() - ticks < POLL_USEC_MAX) {
Array arr = out_queue[0];
out_queue.pop_front();
packet_peer->put_var(arr);
connected = tcp->get_status() == StreamPeerTCP::STATUS_CONNECTED;
}
return err;
}
bool has_message() {
return in_queue.size() > 0;
}
Array get_message() {
MutexLock lock(mutex);
ERR_FAIL_COND_V(!has_message(), Array());
Array out = in_queue[0];
in_queue.pop_front();
return out;
}
Error put_message(const Array p_arr) {
MutexLock lock(mutex);
if (out_queue.size() > QUEUE_MAX) {
return ERR_OUT_OF_MEMORY;
}
out_queue.push_back(p_arr);
return OK;
}
int get_max_message_size() const {
return 8 << 20; // 8 MiB
}
bool is_peer_connected() {
return connected;
}
void close() {
MutexLock lock(mutex);
connected = false;
tcp->disconnect_from_host();
}
EditorDebuggerPeerTCP(Ref<StreamPeerTCP> p_stream) {
packet_peer.instance();
tcp = p_stream;
if (tcp.is_null()) {
tcp.instance(); // Bug?
}
packet_peer->set_stream_peer(tcp);
}
~EditorDebuggerPeerTCP() {
close();
packet_peer->set_stream_peer(Ref<StreamPeer>());
}
};
class EditorDebuggerServerTCP : public EditorDebuggerServer {
private:
Ref<TCP_Server> server;
List<Ref<EditorDebuggerPeer> > peers;
Thread *thread = NULL;
Mutex mutex;
bool running = false;
static void _poll_func(void *p_ud);
public:
virtual Error start();
virtual void stop();
virtual bool is_active() const;
virtual bool is_connection_available() const;
virtual Ref<EditorDebuggerPeer> take_connection();
EditorDebuggerServerTCP();
};
EditorDebuggerServerTCP::EditorDebuggerServerTCP() {
server.instance();
}
Error EditorDebuggerServerTCP::start() {
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
const Error err = server->listen(remote_port);
if (err != OK) {
EditorNode::get_log()->add_message(String("Error listening on port ") + itos(remote_port), EditorLog::MSG_TYPE_ERROR);
return err;
}
running = true;
thread = Thread::create(_poll_func, this);
return err;
}
void EditorDebuggerServerTCP::stop() {
server->stop();
if (thread != NULL) {
running = false;
Thread::wait_to_finish(thread);
memdelete(thread);
thread = NULL;
}
}
bool EditorDebuggerServerTCP::is_active() const {
return server->is_listening();
}
bool EditorDebuggerServerTCP::is_connection_available() const {
return server->is_listening() && server->is_connection_available();
}
Ref<EditorDebuggerPeer> EditorDebuggerServerTCP::take_connection() {
ERR_FAIL_COND_V(!is_connection_available(), Ref<EditorDebuggerPeer>());
MutexLock lock(mutex);
Ref<EditorDebuggerPeerTCP> peer = memnew(EditorDebuggerPeerTCP(server->take_connection()));
peers.push_back(peer);
return peer;
}
void EditorDebuggerServerTCP::_poll_func(void *p_ud) {
EditorDebuggerServerTCP *me = (EditorDebuggerServerTCP *)p_ud;
while (me->running) {
me->mutex.lock();
List<Ref<EditorDebuggerPeer> > remove;
for (int i = 0; i < me->peers.size(); i++) {
Ref<EditorDebuggerPeer> peer = me->peers[i];
Error err = ((EditorDebuggerPeerTCP *)peer.ptr())->poll();
if (err != OK || !peer->is_peer_connected())
remove.push_back(peer);
}
for (List<Ref<EditorDebuggerPeer> >::Element *E = remove.front(); E; E = E->next()) {
me->peers.erase(E->get());
}
me->mutex.unlock();
OS::get_singleton()->delay_usec(50);
}
}
EditorDebuggerServer *EditorDebuggerServer::create_default() {
return memnew(EditorDebuggerServerTCP);
}

View file

@ -0,0 +1,59 @@
/*************************************************************************/
/* editor_debugger_server.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* 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. */
/*************************************************************************/
#ifndef EDITOR_DEBUGGER_CONNECTION_H
#define EDITOR_DEBUGGER_CONNECTION_H
#include "core/reference.h"
class EditorDebuggerPeer : public Reference {
public:
virtual bool has_message() = 0;
virtual Array get_message() = 0;
virtual Error put_message(const Array p_arr) = 0;
virtual int get_max_message_size() const = 0;
virtual bool is_peer_connected() = 0;
virtual void close() = 0;
};
class EditorDebuggerServer : public Reference {
public:
static EditorDebuggerServer *create_default();
virtual Error start() = 0;
virtual void stop() = 0;
virtual bool is_active() const = 0;
virtual bool is_connection_available() const = 0;
virtual Ref<EditorDebuggerPeer> take_connection() = 0;
};
#endif // EDITOR_DEBUGGER_CONNECTION_H

View file

@ -45,6 +45,7 @@
#include "editor/plugins/spatial_editor_plugin.h"
#include "editor/property_editor.h"
#include "main/performance.h"
#include "scene/3d/camera.h"
#include "scene/debugger/scene_debugger.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/label.h"
@ -58,12 +59,14 @@
#include "scene/gui/tree.h"
#include "scene/resources/packed_scene.h"
using CameraOverride = EditorDebuggerNode::CameraOverride;
void ScriptEditorDebugger::_put_msg(String p_message, Array p_data) {
if (is_session_active()) {
Array msg;
msg.push_back(p_message);
msg.push_back(p_data);
ppeer->put_var(msg);
peer->put_message(msg);
}
}
@ -776,7 +779,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
if (is_session_active()) {
if (camera_override == OVERRIDE_2D) {
if (camera_override == CameraOverride::OVERRIDE_2D) {
CanvasItemEditor *editor = CanvasItemEditor::get_singleton();
Dictionary state = editor->get_state();
@ -791,8 +794,8 @@ void ScriptEditorDebugger::_notification(int p_what) {
msg.push_back(transform);
_put_msg("override_camera_2D:transform", msg);
} else if (camera_override >= OVERRIDE_3D_1) {
int viewport_idx = camera_override - OVERRIDE_3D_1;
} else if (camera_override >= CameraOverride::OVERRIDE_3D_1) {
int viewport_idx = camera_override - CameraOverride::OVERRIDE_3D_1;
SpatialEditorViewport *viewport = SpatialEditor::get_singleton()->get_editor_viewport(viewport_idx);
Camera *const cam = viewport->get_camera();
@ -811,30 +814,11 @@ void ScriptEditorDebugger::_notification(int p_what) {
}
}
if (!is_session_active()) {
_stop_and_notify();
break;
};
if (ppeer->get_available_packet_count() <= 0) {
break;
};
const uint64_t until = OS::get_singleton()->get_ticks_msec() + 20;
while (ppeer->get_available_packet_count() > 0) {
while (peer->has_message()) {
Variant cmd;
Error ret = ppeer->get_var(cmd);
if (ret != OK) {
_stop_and_notify();
ERR_FAIL_MSG("Error decoding variant from peer");
}
if (cmd.get_type() != Variant::ARRAY) {
_stop_and_notify();
ERR_FAIL_MSG("Invalid message format received from peer");
}
Array arr = cmd;
Array arr = peer->get_message();
if (arr.size() != 2 || arr[0].get_type() != Variant::STRING || arr[1].get_type() != Variant::ARRAY) {
_stop_and_notify();
ERR_FAIL_MSG("Invalid message format received from peer");
@ -844,6 +828,10 @@ void ScriptEditorDebugger::_notification(int p_what) {
if (OS::get_singleton()->get_ticks_msec() > until)
break;
}
if (!is_session_active()) {
_stop_and_notify();
break;
};
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
@ -875,14 +863,13 @@ void ScriptEditorDebugger::_clear_execution() {
inspector->clear_stack_variables();
}
void ScriptEditorDebugger::start(Ref<StreamPeerTCP> p_connection) {
void ScriptEditorDebugger::start(Ref<EditorDebuggerPeer> p_peer) {
error_count = 0;
warning_count = 0;
stop();
connection = p_connection;
ppeer->set_stream_peer(connection);
peer = p_peer;
perf_history.clear();
for (int i = 0; i < Performance::MONITOR_MAX; i++) {
@ -893,7 +880,7 @@ void ScriptEditorDebugger::start(Ref<StreamPeerTCP> p_connection) {
set_process(true);
breaked = false;
can_debug = true;
camera_override = OVERRIDE_NONE;
camera_override = CameraOverride::OVERRIDE_NONE;
tabs->set_current_tab(0);
_set_reason_text(TTR("Debug session started."), MESSAGE_SUCCESS);
@ -936,10 +923,10 @@ void ScriptEditorDebugger::stop() {
_clear_execution();
inspector->clear_cache();
ppeer->set_stream_peer(Ref<StreamPeer>());
if (connection.is_valid()) {
connection.unref();
if (peer.is_valid()) {
peer->close();
peer.unref();
reason->set_text("");
reason->set_tooltip("");
}
@ -971,9 +958,6 @@ void ScriptEditorDebugger::_profiler_activate(bool p_enable) {
void ScriptEditorDebugger::_visual_profiler_activate(bool p_enable) {
if (!connection.is_valid())
return;
if (p_enable) {
profiler_signature.clear();
_put_msg("start_visual_profiling", Array());
@ -1328,25 +1312,25 @@ void ScriptEditorDebugger::live_debug_reparent_node(const NodePath &p_at, const
}
}
ScriptEditorDebugger::CameraOverride ScriptEditorDebugger::get_camera_override() const {
CameraOverride ScriptEditorDebugger::get_camera_override() const {
return camera_override;
}
void ScriptEditorDebugger::set_camera_override(CameraOverride p_override) {
if (p_override == OVERRIDE_2D && camera_override != OVERRIDE_2D) {
if (p_override == CameraOverride::OVERRIDE_2D && camera_override != CameraOverride::OVERRIDE_2D) {
Array msg;
msg.push_back(true);
_put_msg("override_camera_2D:set", msg);
} else if (p_override != OVERRIDE_2D && camera_override == OVERRIDE_2D) {
} else if (p_override != CameraOverride::OVERRIDE_2D && camera_override == CameraOverride::OVERRIDE_2D) {
Array msg;
msg.push_back(false);
_put_msg("override_camera_2D:set", msg);
} else if (p_override >= OVERRIDE_3D_1 && camera_override < OVERRIDE_3D_1) {
} else if (p_override >= CameraOverride::OVERRIDE_3D_1 && camera_override < CameraOverride::OVERRIDE_3D_1) {
Array msg;
msg.push_back(true);
_put_msg("override_camera_3D:set", msg);
} else if (p_override < OVERRIDE_3D_1 && camera_override >= OVERRIDE_3D_1) {
} else if (p_override < CameraOverride::OVERRIDE_3D_1 && camera_override >= CameraOverride::OVERRIDE_3D_1) {
Array msg;
msg.push_back(false);
_put_msg("override_camera_3D:set", msg);
@ -1423,7 +1407,6 @@ void ScriptEditorDebugger::_clear_errors_list() {
error_tree->clear();
error_count = 0;
warning_count = 0;
update_tabs();
}
// Right click on specific file(s) or folder(s).
@ -1502,8 +1485,6 @@ void ScriptEditorDebugger::_bind_methods() {
ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
ppeer = Ref<PacketPeerStream>(memnew(PacketPeerStream));
ppeer->set_input_buffer_max_size((1024 * 1024 * 8) - 4); // 8 MiB should be enough, minus 4 bytes for separator.
editor = p_editor;
tabs = memnew(TabContainer);
@ -1824,7 +1805,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
add_child(msgdialog);
live_debug = true;
camera_override = OVERRIDE_NONE;
camera_override = CameraOverride::OVERRIDE_NONE;
last_path_id = false;
error_count = 0;
warning_count = 0;
@ -1833,6 +1814,9 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
ScriptEditorDebugger::~ScriptEditorDebugger() {
ppeer->set_stream_peer(Ref<StreamPeer>());
if (peer.is_valid()) {
peer->close();
peer.unref();
}
memdelete(scene_tree);
}

View file

@ -31,14 +31,13 @@
#ifndef SCRIPT_EDITOR_DEBUGGER_H
#define SCRIPT_EDITOR_DEBUGGER_H
#include "core/io/packet_peer.h"
#include "core/io/stream_peer_tcp.h"
#include "core/os/os.h"
#include "editor/debugger/editor_debugger_inspector.h"
#include "editor/editor_inspector.h"
#include "editor/property_editor.h"
#include "scene/3d/camera.h"
#include "scene/gui/box_container.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/editor_debugger_server.h"
#include "editor/editor_file_dialog.h"
#include "scene/gui/button.h"
#include "scene/gui/margin_container.h"
class Tree;
class EditorNode;
@ -61,16 +60,6 @@ class ScriptEditorDebugger : public MarginContainer {
friend class EditorDebuggerNode;
public:
enum CameraOverride {
OVERRIDE_NONE,
OVERRIDE_2D,
OVERRIDE_3D_1, // 3D Viewport 1
OVERRIDE_3D_2, // 3D Viewport 2
OVERRIDE_3D_3, // 3D Viewport 3
OVERRIDE_3D_4 // 3D Viewport 4
};
private:
enum MessageType {
MESSAGE_ERROR,
@ -132,8 +121,7 @@ private:
EditorDebuggerInspector *inspector;
SceneDebuggerTree *scene_tree;
Ref<StreamPeerTCP> connection;
Ref<PacketPeerStream> ppeer;
Ref<EditorDebuggerPeer> peer;
HashMap<NodePath, int> node_path_cache;
int last_path_id;
@ -151,7 +139,7 @@ private:
bool live_debug;
CameraOverride camera_override;
EditorDebuggerNode::CameraOverride camera_override;
void _performance_draw();
void _performance_select();
@ -216,7 +204,7 @@ public:
void request_remote_tree();
const SceneDebuggerTree *get_remote_tree();
void start(Ref<StreamPeerTCP> p_connection);
void start(Ref<EditorDebuggerPeer> p_peer);
void stop();
void debug_skip_breakpoints();
@ -228,7 +216,7 @@ public:
void debug_continue();
bool is_breaked() const { return breaked; }
bool is_debuggable() const { return can_debug; }
bool is_session_active() { return connection.is_valid() && connection->is_connected_to_host(); };
bool is_session_active() { return peer.is_valid() && peer->is_peer_connected(); };
int get_remote_pid() const { return remote_pid; }
int get_error_count() const { return error_count; }
@ -252,8 +240,8 @@ public:
void live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name);
void live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
CameraOverride get_camera_override() const;
void set_camera_override(CameraOverride p_override);
EditorDebuggerNode::CameraOverride get_camera_override() const;
void set_camera_override(EditorDebuggerNode::CameraOverride p_override);
void set_breakpoint(const String &p_path, int p_line, bool p_enabled);

View file

@ -3992,7 +3992,7 @@ void CanvasItemEditor::_notification(int p_what) {
if (!is_visible() && override_camera_button->is_pressed()) {
EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE);
override_camera_button->set_pressed(false);
}
}
@ -4348,9 +4348,9 @@ void CanvasItemEditor::_button_override_camera(bool p_pressed) {
EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
if (p_pressed) {
debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_2D);
debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_2D);
} else {
debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE);
}
}

View file

@ -37,7 +37,6 @@
#include "core/os/os.h"
#include "core/project_settings.h"
#include "editor/debugger/editor_debugger_node.h"
#include "editor/debugger/script_editor_debugger.h"
#include "editor/editor_node.h"
#include "editor/editor_run_script.h"
#include "editor/editor_scale.h"

View file

@ -4487,12 +4487,12 @@ void SpatialEditor::_menu_item_toggled(bool pressed, int p_option) {
case MENU_TOOL_OVERRIDE_CAMERA: {
EditorDebuggerNode *const debugger = EditorDebuggerNode::get_singleton();
using Override = EditorDebuggerNode::CameraOverride;
if (pressed) {
using Override = ScriptEditorDebugger::CameraOverride;
debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id));
} else {
debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
debugger->set_camera_override(Override::OVERRIDE_NONE);
}
} break;
@ -4545,8 +4545,8 @@ void SpatialEditor::_update_camera_override_viewport(Object *p_viewport) {
EditorDebuggerNode *const debugger = EditorDebuggerNode::get_singleton();
camera_override_viewport_id = current_viewport->index;
if (debugger->get_camera_override() >= ScriptEditorDebugger::OVERRIDE_3D_1) {
using Override = ScriptEditorDebugger::CameraOverride;
if (debugger->get_camera_override() >= EditorDebuggerNode::OVERRIDE_3D_1) {
using Override = EditorDebuggerNode::CameraOverride;
debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id));
}
@ -5503,7 +5503,7 @@ void SpatialEditor::_notification(int p_what) {
if (!is_visible() && tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->is_pressed()) {
EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
debugger->set_camera_override(EditorDebuggerNode::OVERRIDE_NONE);
tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_pressed(false);
}
}

View file

@ -39,7 +39,7 @@
#include "core/reference.h"
#ifdef TOOLS_ENABLED
#include "editor/debugger/script_editor_debugger.h"
#include "editor/debugger/editor_debugger_node.h"
#endif
#include "../csharp_script.h"