Path: blob/master/editor/debugger/script_editor_debugger.h
20778 views
/**************************************************************************/1/* script_editor_debugger.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/object/script_language.h"33#include "core/os/os.h"34#include "editor/debugger/editor_debugger_inspector.h"35#include "editor/debugger/editor_debugger_node.h"36#include "scene/gui/margin_container.h"3738class Button;39class Tree;40class LineEdit;41class TabContainer;42class RichTextLabel;43class TextureButton;44class AcceptDialog;45class TreeItem;46class HSplitContainer;47class ItemList;48class EditorProfiler;49class EditorFileDialog;50class EditorVisualProfiler;51class EditorPerformanceProfiler;52class SceneDebuggerTree;53class EditorDebuggerPlugin;54class DebugAdapterProtocol;55class DebugAdapterParser;56class EditorExpressionEvaluator;5758class ScriptEditorDebugger : public MarginContainer {59GDCLASS(ScriptEditorDebugger, MarginContainer);6061friend class EditorDebuggerNode;62friend class DebugAdapterProtocol;63friend class DebugAdapterParser;6465private:66enum MessageType {67MESSAGE_ERROR,68MESSAGE_WARNING,69MESSAGE_SUCCESS,70};7172enum ProfilerType {73PROFILER_VISUAL,74PROFILER_SCRIPTS_SERVERS75};7677enum Actions {78ACTION_COPY_ERROR,79ACTION_OPEN_SOURCE,80ACTION_DELETE_BREAKPOINT,81ACTION_DELETE_BREAKPOINTS_IN_FILE,82ACTION_DELETE_ALL_BREAKPOINTS,83};8485enum VMemMenu {86VMEM_MENU_SHOW_IN_FILESYSTEM,87VMEM_MENU_SHOW_IN_EXPLORER,88VMEM_MENU_OWNERS,89};9091AcceptDialog *msgdialog = nullptr;9293LineEdit *clicked_ctrl = nullptr;94LineEdit *clicked_ctrl_type = nullptr;95LineEdit *live_edit_root = nullptr;96Button *le_set = nullptr;97Button *le_clear = nullptr;98Button *export_csv = nullptr;99100VBoxContainer *errors_tab = nullptr;101Tree *error_tree = nullptr;102Button *expand_all_button = nullptr;103Button *collapse_all_button = nullptr;104Button *clear_button = nullptr;105PopupMenu *item_menu = nullptr;106107Tree *breakpoints_tree = nullptr;108PopupMenu *breakpoints_menu = nullptr;109110EditorFileDialog *file_dialog = nullptr;111enum FileDialogPurpose {112SAVE_MONITORS_CSV,113SAVE_VRAM_CSV,114};115FileDialogPurpose file_dialog_purpose = SAVE_MONITORS_CSV;116117int error_count;118int warning_count;119120bool skip_breakpoints_value = false;121bool ignore_error_breaks_value = false;122Ref<Script> stack_script;123124TabContainer *tabs = nullptr;125126RichTextLabel *reason = nullptr;127128Button *skip_breakpoints = nullptr;129Button *ignore_error_breaks = nullptr;130Button *copy = nullptr;131Button *step = nullptr;132Button *next = nullptr;133Button *out = nullptr;134Button *dobreak = nullptr;135Button *docontinue = nullptr;136// Reference to "Remote" tab in scene tree. Needed by _live_edit_set and buttons state.137// Each debugger should have it's tree in the future I guess.138const Tree *editor_remote_tree = nullptr;139140HashMap<int, String> profiler_signature;141142Tree *vmem_tree = nullptr;143Button *vmem_refresh = nullptr;144Button *vmem_export = nullptr;145LineEdit *vmem_total = nullptr;146TextureRect *vmem_notice_icon = nullptr;147PopupMenu *vmem_item_menu = nullptr;148149Tree *stack_dump = nullptr;150LineEdit *search = nullptr;151OptionButton *threads = nullptr;152EditorDebuggerInspector *inspector = nullptr;153SceneDebuggerTree *scene_tree = nullptr;154155Ref<RemoteDebuggerPeer> peer;156157HashMap<NodePath, int> node_path_cache;158int last_path_id = 0;159HashMap<String, int> res_path_cache;160161EditorProfiler *profiler = nullptr;162EditorVisualProfiler *visual_profiler = nullptr;163EditorPerformanceProfiler *performance_profiler = nullptr;164EditorExpressionEvaluator *expression_evaluator = nullptr;165166OS::ProcessID remote_pid = 0;167bool move_to_foreground = true;168bool can_request_idle_draw = false;169170bool live_debug = true;171172uint64_t debugging_thread_id = Thread::UNASSIGNED_ID;173174struct ThreadDebugged {175String name;176String error;177bool can_debug = false;178bool has_stackdump = false;179uint32_t debug_order = 0;180uint64_t thread_id = Thread::UNASSIGNED_ID; // for order181};182183struct ThreadSort {184bool operator()(const ThreadDebugged *a, const ThreadDebugged *b) const {185return a->debug_order < b->debug_order;186}187};188189HashMap<uint64_t, ThreadDebugged> threads_debugged;190bool thread_list_updating = false;191192void _select_thread(int p_index);193194bool debug_mute_audio = false;195bool audio_muted_on_break = false;196void _mute_audio_on_break(bool p_mute);197void _send_debug_mute_audio_msg(bool p_mute);198199EditorDebuggerNode::CameraOverride camera_override;200201void _stack_dump_frame_selected();202203void _file_selected(const String &p_file);204205/// Message handler function for _parse_message.206typedef void (ScriptEditorDebugger::*ParseMessageFunc)(uint64_t p_thread_id, const Array &p_data);207static HashMap<String, ParseMessageFunc> parse_message_handlers;208static void _init_parse_message_handlers();209210void _msg_debug_enter(uint64_t p_thread_id, const Array &p_data);211void _msg_debug_exit(uint64_t p_thread_id, const Array &p_data);212void _msg_set_pid(uint64_t p_thread_id, const Array &p_data);213void _msg_scene_click_ctrl(uint64_t p_thread_id, const Array &p_data);214void _msg_scene_scene_tree(uint64_t p_thread_id, const Array &p_data);215void _msg_scene_inspect_objects(uint64_t p_thread_id, const Array &p_data);216#ifndef DISABLE_DEPRECATED217void _msg_scene_inspect_object(uint64_t p_thread_id, const Array &p_data);218#endif // DISABLE_DEPRECATED219void _msg_scene_debug_mute_audio(uint64_t p_thread_id, const Array &p_data);220void _msg_servers_memory_usage(uint64_t p_thread_id, const Array &p_data);221void _msg_servers_drawn(uint64_t p_thread_id, const Array &p_data);222void _msg_stack_dump(uint64_t p_thread_id, const Array &p_data);223void _msg_stack_frame_vars(uint64_t p_thread_id, const Array &p_data);224void _msg_stack_frame_var(uint64_t p_thread_id, const Array &p_data);225void _msg_output(uint64_t p_thread_id, const Array &p_data);226void _msg_performance_profile_frame(uint64_t p_thread_id, const Array &p_data);227void _msg_visual_hardware_info(uint64_t p_thread_id, const Array &p_data);228void _msg_visual_profile_frame(uint64_t p_thread_id, const Array &p_data);229void _msg_error(uint64_t p_thread_id, const Array &p_data);230void _msg_servers_function_signature(uint64_t p_thread_id, const Array &p_data);231void _msg_servers_profile_common(const Array &p_data, const bool p_final);232void _msg_servers_profile_frame(uint64_t p_thread_id, const Array &p_data);233void _msg_servers_profile_total(uint64_t p_thread_id, const Array &p_data);234void _msg_request_quit(uint64_t p_thread_id, const Array &p_data);235void _msg_remote_objects_selected(uint64_t p_thread_id, const Array &p_data);236void _msg_remote_nothing_selected(uint64_t p_thread_id, const Array &p_data);237void _msg_remote_selection_invalidated(uint64_t p_thread_id, const Array &p_data);238void _msg_show_selection_limit_warning(uint64_t p_thread_id, const Array &p_data);239void _msg_performance_profile_names(uint64_t p_thread_id, const Array &p_data);240void _msg_filesystem_update_file(uint64_t p_thread_id, const Array &p_data);241void _msg_evaluation_return(uint64_t p_thread_id, const Array &p_data);242void _msg_window_title(uint64_t p_thread_id, const Array &p_data);243void _msg_embed_suspend_toggle(uint64_t p_thread_id, const Array &p_data);244void _msg_embed_next_frame(uint64_t p_thread_id, const Array &p_data);245246void _parse_message(const String &p_msg, uint64_t p_thread_id, const Array &p_data);247void _set_reason_text(const String &p_reason, MessageType p_type);248void _update_reason_content_height();249void _update_buttons_state();250void _remote_object_selected(ObjectID p_object);251void _remote_objects_edited(const String &p_prop, const TypedDictionary<uint64_t, Variant> &p_values, const String &p_field);252void _remote_object_property_updated(ObjectID p_id, const String &p_property);253254void _video_mem_request();255void _video_mem_export();256257void _resources_reimported(const PackedStringArray &p_resources);258259int _get_node_path_cache(const NodePath &p_path);260261int _get_res_path_cache(const String &p_path);262263void _live_edit_set();264void _live_edit_clear();265266void _method_changed(Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount);267void _property_changed(Object *p_base, const StringName &p_property, const Variant &p_value);268269void _error_activated();270void _error_selected();271272void _expand_errors_list();273void _collapse_errors_list();274275void _vmem_item_activated();276void _vmem_tree_rmb_selected(const Vector2 &p_pos, MouseButton p_button);277void _vmem_item_menu_id_pressed(int p_option);278279void _profiler_activate(bool p_enable, int p_profiler);280void _profiler_seeked();281282void _clear_errors_list();283284void _breakpoints_item_rmb_selected(const Vector2 &p_pos, MouseButton p_button);285void _error_tree_item_rmb_selected(const Vector2 &p_pos, MouseButton p_button);286void _item_menu_id_pressed(int p_option);287void _tab_changed(int p_tab);288289void _put_msg(const String &p_message, const Array &p_data, uint64_t p_thread_id = Thread::MAIN_ID);290void _export_csv();291292void _clear_execution();293void _stop_and_notify();294295void _set_breakpoint(const String &p_path, const int &p_line, const bool &p_enabled);296void _clear_breakpoints();297298void _breakpoint_tree_clicked();299300String _format_frame_text(const ScriptLanguage::StackInfo *info);301302void _thread_debug_enter(uint64_t p_thread_id);303304protected:305void _notification(int p_what);306static void _bind_methods();307308public:309enum EmbedShortcutAction {310EMBED_SUSPEND_TOGGLE,311EMBED_NEXT_FRAME,312};313314void request_remote_objects(const TypedArray<uint64_t> &p_obj_ids, bool p_update_selection = true);315void update_remote_object(ObjectID p_obj_id, const String &p_prop, const Variant &p_value, const String &p_field = "");316317void clear_inspector(bool p_send_msg = true);318319// Needed by _live_edit_set, buttons state.320void set_editor_remote_tree(const Tree *p_tree) { editor_remote_tree = p_tree; }321322void request_remote_tree();323const SceneDebuggerTree *get_remote_tree();324325void request_remote_evaluate(const String &p_expression, int p_stack_frame);326327void start(Ref<RemoteDebuggerPeer> p_peer);328void stop();329330void debug_skip_breakpoints();331void debug_ignore_error_breaks();332void debug_copy();333334void debug_out();335void debug_next();336void debug_step();337void debug_break();338void debug_continue();339bool is_breaked() const { return threads_debugged.size() > 0; }340bool is_debuggable() const { return threads_debugged.size() > 0 && threads_debugged[debugging_thread_id].can_debug; }341bool is_session_active() { return peer.is_valid() && peer->is_peer_connected(); }342int get_remote_pid() const { return remote_pid; }343344bool is_move_to_foreground() const;345void set_move_to_foreground(const bool &p_move_to_foreground);346347int get_error_count() const { return error_count; }348int get_warning_count() const { return warning_count; }349String get_stack_script_file() const;350int get_stack_script_line() const;351int get_stack_script_frame() const;352353bool request_stack_dump(const int &p_frame);354355void update_tabs();356void clear_style();357String get_var_value(const String &p_var) const;358359void save_node(ObjectID p_id, const String &p_file);360void set_live_debugging(bool p_enable);361362void live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name);363void live_debug_instantiate_node(const NodePath &p_parent, const String &p_path, const String &p_name);364void live_debug_remove_node(const NodePath &p_at);365void live_debug_remove_and_keep_node(const NodePath &p_at, ObjectID p_keep_id);366void live_debug_restore_node(ObjectID p_id, const NodePath &p_at, int p_at_pos);367void live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name);368void live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);369370bool get_debug_mute_audio() const;371void set_debug_mute_audio(bool p_mute);372373EditorDebuggerNode::CameraOverride get_camera_override() const;374void set_camera_override(EditorDebuggerNode::CameraOverride p_override);375376void set_breakpoint(const String &p_path, int p_line, bool p_enabled);377378void update_live_edit_root();379380void reload_all_scripts();381void reload_scripts(const Vector<String> &p_script_paths);382383bool is_skip_breakpoints() const;384bool is_ignore_error_breaks() const;385386virtual Size2 get_minimum_size() const override;387388void add_debugger_tab(Control *p_control);389void remove_debugger_tab(Control *p_control);390int get_current_debugger_tab() const;391void switch_to_debugger(int p_debugger_tab_idx);392393void send_message(const String &p_message, const Array &p_args);394void toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data);395396ScriptEditorDebugger();397~ScriptEditorDebugger();398};399400401