Path: blob/master/editor/debugger/script_editor_debugger.h
9902 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};8485AcceptDialog *msgdialog = nullptr;8687LineEdit *clicked_ctrl = nullptr;88LineEdit *clicked_ctrl_type = nullptr;89LineEdit *live_edit_root = nullptr;90Button *le_set = nullptr;91Button *le_clear = nullptr;92Button *export_csv = nullptr;9394VBoxContainer *errors_tab = nullptr;95Tree *error_tree = nullptr;96Button *expand_all_button = nullptr;97Button *collapse_all_button = nullptr;98Button *clear_button = nullptr;99PopupMenu *item_menu = nullptr;100101Tree *breakpoints_tree = nullptr;102PopupMenu *breakpoints_menu = nullptr;103104EditorFileDialog *file_dialog = nullptr;105enum FileDialogPurpose {106SAVE_MONITORS_CSV,107SAVE_VRAM_CSV,108};109FileDialogPurpose file_dialog_purpose;110111int error_count;112int warning_count;113114bool skip_breakpoints_value = false;115bool ignore_error_breaks_value = false;116Ref<Script> stack_script;117118TabContainer *tabs = nullptr;119120RichTextLabel *reason = nullptr;121122Button *skip_breakpoints = nullptr;123Button *ignore_error_breaks = nullptr;124Button *copy = nullptr;125Button *step = nullptr;126Button *next = nullptr;127Button *dobreak = nullptr;128Button *docontinue = nullptr;129// Reference to "Remote" tab in scene tree. Needed by _live_edit_set and buttons state.130// Each debugger should have it's tree in the future I guess.131const Tree *editor_remote_tree = nullptr;132133HashMap<int, String> profiler_signature;134135Tree *vmem_tree = nullptr;136Button *vmem_refresh = nullptr;137Button *vmem_export = nullptr;138LineEdit *vmem_total = nullptr;139TextureRect *vmem_notice_icon = nullptr;140141Tree *stack_dump = nullptr;142LineEdit *search = nullptr;143OptionButton *threads = nullptr;144EditorDebuggerInspector *inspector = nullptr;145SceneDebuggerTree *scene_tree = nullptr;146147Ref<RemoteDebuggerPeer> peer;148149HashMap<NodePath, int> node_path_cache;150int last_path_id = 0;151HashMap<String, int> res_path_cache;152153EditorProfiler *profiler = nullptr;154EditorVisualProfiler *visual_profiler = nullptr;155EditorPerformanceProfiler *performance_profiler = nullptr;156EditorExpressionEvaluator *expression_evaluator = nullptr;157158OS::ProcessID remote_pid = 0;159bool move_to_foreground = true;160bool can_request_idle_draw = false;161162bool live_debug = true;163164uint64_t debugging_thread_id = Thread::UNASSIGNED_ID;165166struct ThreadDebugged {167String name;168String error;169bool can_debug = false;170bool has_stackdump = false;171uint32_t debug_order = 0;172uint64_t thread_id = Thread::UNASSIGNED_ID; // for order173};174175struct ThreadSort {176bool operator()(const ThreadDebugged *a, const ThreadDebugged *b) const {177return a->debug_order < b->debug_order;178}179};180181HashMap<uint64_t, ThreadDebugged> threads_debugged;182bool thread_list_updating = false;183184void _select_thread(int p_index);185186bool debug_mute_audio = false;187188EditorDebuggerNode::CameraOverride camera_override;189190void _stack_dump_frame_selected();191192void _file_selected(const String &p_file);193194/// Message handler function for _parse_message.195typedef void (ScriptEditorDebugger::*ParseMessageFunc)(uint64_t p_thread_id, const Array &p_data);196static HashMap<String, ParseMessageFunc> parse_message_handlers;197static void _init_parse_message_handlers();198199void _msg_debug_enter(uint64_t p_thread_id, const Array &p_data);200void _msg_debug_exit(uint64_t p_thread_id, const Array &p_data);201void _msg_set_pid(uint64_t p_thread_id, const Array &p_data);202void _msg_scene_click_ctrl(uint64_t p_thread_id, const Array &p_data);203void _msg_scene_scene_tree(uint64_t p_thread_id, const Array &p_data);204void _msg_scene_inspect_objects(uint64_t p_thread_id, const Array &p_data);205#ifndef DISABLE_DEPRECATED206void _msg_scene_inspect_object(uint64_t p_thread_id, const Array &p_data);207#endif // DISABLE_DEPRECATED208void _msg_servers_memory_usage(uint64_t p_thread_id, const Array &p_data);209void _msg_servers_drawn(uint64_t p_thread_id, const Array &p_data);210void _msg_stack_dump(uint64_t p_thread_id, const Array &p_data);211void _msg_stack_frame_vars(uint64_t p_thread_id, const Array &p_data);212void _msg_stack_frame_var(uint64_t p_thread_id, const Array &p_data);213void _msg_output(uint64_t p_thread_id, const Array &p_data);214void _msg_performance_profile_frame(uint64_t p_thread_id, const Array &p_data);215void _msg_visual_hardware_info(uint64_t p_thread_id, const Array &p_data);216void _msg_visual_profile_frame(uint64_t p_thread_id, const Array &p_data);217void _msg_error(uint64_t p_thread_id, const Array &p_data);218void _msg_servers_function_signature(uint64_t p_thread_id, const Array &p_data);219void _msg_servers_profile_common(const Array &p_data, const bool p_final);220void _msg_servers_profile_frame(uint64_t p_thread_id, const Array &p_data);221void _msg_servers_profile_total(uint64_t p_thread_id, const Array &p_data);222void _msg_request_quit(uint64_t p_thread_id, const Array &p_data);223void _msg_remote_objects_selected(uint64_t p_thread_id, const Array &p_data);224void _msg_remote_nothing_selected(uint64_t p_thread_id, const Array &p_data);225void _msg_remote_selection_invalidated(uint64_t p_thread_id, const Array &p_data);226void _msg_show_selection_limit_warning(uint64_t p_thread_id, const Array &p_data);227void _msg_performance_profile_names(uint64_t p_thread_id, const Array &p_data);228void _msg_filesystem_update_file(uint64_t p_thread_id, const Array &p_data);229void _msg_evaluation_return(uint64_t p_thread_id, const Array &p_data);230void _msg_window_title(uint64_t p_thread_id, const Array &p_data);231void _msg_embed_suspend_toggle(uint64_t p_thread_id, const Array &p_data);232void _msg_embed_next_frame(uint64_t p_thread_id, const Array &p_data);233234void _parse_message(const String &p_msg, uint64_t p_thread_id, const Array &p_data);235void _set_reason_text(const String &p_reason, MessageType p_type);236void _update_reason_content_height();237void _update_buttons_state();238void _remote_object_selected(ObjectID p_object);239void _remote_objects_edited(const String &p_prop, const TypedDictionary<uint64_t, Variant> &p_values, const String &p_field);240void _remote_object_property_updated(ObjectID p_id, const String &p_property);241242void _video_mem_request();243void _video_mem_export();244245void _resources_reimported(const PackedStringArray &p_resources);246247int _get_node_path_cache(const NodePath &p_path);248249int _get_res_path_cache(const String &p_path);250251void _live_edit_set();252void _live_edit_clear();253254void _method_changed(Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount);255void _property_changed(Object *p_base, const StringName &p_property, const Variant &p_value);256257void _error_activated();258void _error_selected();259260void _expand_errors_list();261void _collapse_errors_list();262263void _vmem_item_activated();264265void _profiler_activate(bool p_enable, int p_profiler);266void _profiler_seeked();267268void _clear_errors_list();269270void _breakpoints_item_rmb_selected(const Vector2 &p_pos, MouseButton p_button);271void _error_tree_item_rmb_selected(const Vector2 &p_pos, MouseButton p_button);272void _item_menu_id_pressed(int p_option);273void _tab_changed(int p_tab);274275void _put_msg(const String &p_message, const Array &p_data, uint64_t p_thread_id = Thread::MAIN_ID);276void _export_csv();277278void _clear_execution();279void _stop_and_notify();280281void _set_breakpoint(const String &p_path, const int &p_line, const bool &p_enabled);282void _clear_breakpoints();283284void _breakpoint_tree_clicked();285286String _format_frame_text(const ScriptLanguage::StackInfo *info);287288void _thread_debug_enter(uint64_t p_thread_id);289290protected:291void _notification(int p_what);292static void _bind_methods();293294public:295enum EmbedShortcutAction {296EMBED_SUSPEND_TOGGLE,297EMBED_NEXT_FRAME,298};299300void request_remote_objects(const TypedArray<uint64_t> &p_obj_ids, bool p_update_selection = true);301void update_remote_object(ObjectID p_obj_id, const String &p_prop, const Variant &p_value, const String &p_field = "");302303void clear_inspector(bool p_send_msg = true);304305// Needed by _live_edit_set, buttons state.306void set_editor_remote_tree(const Tree *p_tree) { editor_remote_tree = p_tree; }307308void request_remote_tree();309const SceneDebuggerTree *get_remote_tree();310311void request_remote_evaluate(const String &p_expression, int p_stack_frame);312313void start(Ref<RemoteDebuggerPeer> p_peer);314void stop();315316void debug_skip_breakpoints();317void debug_ignore_error_breaks();318void debug_copy();319320void debug_next();321void debug_step();322void debug_break();323void debug_continue();324bool is_breaked() const { return threads_debugged.size() > 0; }325bool is_debuggable() const { return threads_debugged.size() > 0 && threads_debugged[debugging_thread_id].can_debug; }326bool is_session_active() { return peer.is_valid() && peer->is_peer_connected(); }327int get_remote_pid() const { return remote_pid; }328329bool is_move_to_foreground() const;330void set_move_to_foreground(const bool &p_move_to_foreground);331332int get_error_count() const { return error_count; }333int get_warning_count() const { return warning_count; }334String get_stack_script_file() const;335int get_stack_script_line() const;336int get_stack_script_frame() const;337338bool request_stack_dump(const int &p_frame);339340void update_tabs();341void clear_style();342String get_var_value(const String &p_var) const;343344void save_node(ObjectID p_id, const String &p_file);345void set_live_debugging(bool p_enable);346347void live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name);348void live_debug_instantiate_node(const NodePath &p_parent, const String &p_path, const String &p_name);349void live_debug_remove_node(const NodePath &p_at);350void live_debug_remove_and_keep_node(const NodePath &p_at, ObjectID p_keep_id);351void live_debug_restore_node(ObjectID p_id, const NodePath &p_at, int p_at_pos);352void live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name);353void live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);354355bool get_debug_mute_audio() const;356void set_debug_mute_audio(bool p_mute);357358EditorDebuggerNode::CameraOverride get_camera_override() const;359void set_camera_override(EditorDebuggerNode::CameraOverride p_override);360361void set_breakpoint(const String &p_path, int p_line, bool p_enabled);362363void update_live_edit_root();364365void reload_all_scripts();366void reload_scripts(const Vector<String> &p_script_paths);367368bool is_skip_breakpoints() const;369bool is_ignore_error_breaks() const;370371virtual Size2 get_minimum_size() const override;372373void add_debugger_tab(Control *p_control);374void remove_debugger_tab(Control *p_control);375int get_current_debugger_tab() const;376void switch_to_debugger(int p_debugger_tab_idx);377378void send_message(const String &p_message, const Array &p_args);379void toggle_profiler(const String &p_profiler, bool p_enable, const Array &p_data);380381ScriptEditorDebugger();382~ScriptEditorDebugger();383};384385386