Threaded networking for editor debugger.
This commit is contained in:
parent
74051c77dc
commit
540ca05a80
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
216
editor/debugger/editor_debugger_server.cpp
Normal file
216
editor/debugger/editor_debugger_server.cpp
Normal 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);
|
||||
}
|
59
editor/debugger/editor_debugger_server.h
Normal file
59
editor/debugger/editor_debugger_server.h
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user