diff options
Diffstat (limited to 'tools/editor')
27 files changed, 894 insertions, 73 deletions
diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp index c0f35a4ac2..a9119349c8 100644 --- a/tools/editor/create_dialog.cpp +++ b/tools/editor/create_dialog.cpp @@ -128,7 +128,7 @@ void CreateDialog::_update_search() { _parse_fs(EditorFileSystem::get_singleton()->get_filesystem()); */ - List<String> type_list; + List<StringName> type_list; ObjectTypeDB::get_type_list(&type_list); HashMap<String,TreeItem*> types; @@ -137,7 +137,7 @@ void CreateDialog::_update_search() { root->set_text(0,base_type); - List<String>::Element *I=type_list.front(); + List<StringName>::Element *I=type_list.front(); TreeItem *to_select=NULL; for(;I;I=I->next()) { diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp index c4808d0cad..7f42f19a9b 100644 --- a/tools/editor/editor_data.cpp +++ b/tools/editor/editor_data.cpp @@ -432,6 +432,7 @@ int EditorData::add_edited_scene(int p_at_pos) { es.root=NULL; es.history_current=-1; es.version=0; + es.live_edit_root=NodePath(String("/root")); if (p_at_pos==edited_scene.size()) edited_scene.push_back(es); @@ -507,6 +508,31 @@ uint64_t EditorData::get_scene_version(int p_idx) const{ return edited_scene[p_idx].version; } +String EditorData::get_scene_type(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String()); + if (!edited_scene[p_idx].root) + return ""; + return edited_scene[p_idx].root->get_type(); + +} + +Ref<Script> EditorData::get_scene_root_script(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),Ref<Script>()); + if (!edited_scene[p_idx].root) + return Ref<Script>(); + Ref<Script> s=edited_scene[p_idx].root->get_script(); + if (!s.is_valid()) { + Node *n = edited_scene[p_idx].root->get_child(0); + while(!s.is_valid() && n && n->get_filename()==String()) { + s=n->get_script(); + n=n->get_parent(); + } + } + return s; +} + String EditorData::get_scene_title(int p_idx) const { ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String()); if (!edited_scene[p_idx].root) @@ -527,6 +553,23 @@ String EditorData::get_scene_path(int p_idx) const { } +void EditorData::set_edited_scene_live_edit_root(const NodePath& p_root) { + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + + edited_scene[current_edited_scene].live_edit_root=p_root; + +} +NodePath EditorData::get_edited_scene_live_edit_root() { + + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),String()); + + return edited_scene[current_edited_scene].live_edit_root; + + + +} + + void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary& p_custom) { ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h index e3fdd52d01..cbec2295f6 100644 --- a/tools/editor/editor_data.h +++ b/tools/editor/editor_data.h @@ -129,6 +129,7 @@ private: int history_current; Dictionary custom_state; uint64_t version; + NodePath live_edit_root; }; @@ -177,10 +178,14 @@ public: int get_edited_scene_count() const; String get_scene_title(int p_idx) const; String get_scene_path(int p_idx) const; + String get_scene_type(int p_idx) const; + Ref<Script> get_scene_root_script(int p_idx) const; void set_edited_scene_version(uint64_t version); uint64_t get_edited_scene_version() const; uint64_t get_scene_version(int p_idx) const; void clear_edited_scenes(); + void set_edited_scene_live_edit_root(const NodePath& p_root); + NodePath get_edited_scene_live_edit_root(); void set_plugin_window_layout(Ref<ConfigFile> p_layout); diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index 25fc526bf9..213c18e1b0 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -79,7 +79,7 @@ void EditorHelpSearch::_update_search() { _parse_fs(EditorFileSystem::get_singleton()->get_filesystem()); */ - List<String> type_list; + List<StringName> type_list; ObjectTypeDB::get_type_list(&type_list); DocData *doc=EditorHelp::get_doc_data(); @@ -1241,13 +1241,13 @@ void EditorHelp::_update_doc() { class_list->clear(); - List<String> type_list; + List<StringName> type_list; tree_item_map.clear(); TreeItem *root = class_list->create_item(); class_list->set_hide_root(true); - List<String>::Element *I=type_list.front(); + List<StringName>::Element *I=type_list.front(); for(Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp index 4e6435b22e..b28b349c86 100644 --- a/tools/editor/editor_import_export.cpp +++ b/tools/editor/editor_import_export.cpp @@ -40,6 +40,7 @@ #include "io/resource_saver.h" #include "io/md5.h" #include "io_plugins/editor_texture_import_plugin.h" +#include "tools/editor/plugins/script_editor_plugin.h" String EditorImportPlugin::validate_source_path(const String& p_path) { @@ -916,6 +917,48 @@ static int _get_pad(int p_alignment, int p_n) { return pad; }; +void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, bool p_dumb, bool p_remote_debug) { + + String host = EditorSettings::get_singleton()->get("network/debug_host"); + + if (p_dumb) { + int port = EditorSettings::get_singleton()->get("file_server/port"); + String passwd = EditorSettings::get_singleton()->get("file_server/password"); + r_flags.push_back("-rfs"); + r_flags.push_back(host+":"+itos(port)); + if (passwd!="") { + r_flags.push_back("-rfs_pass"); + r_flags.push_back(passwd); + } + } + + if (p_remote_debug) { + + r_flags.push_back("-rdebug"); + r_flags.push_back(host+":"+String::num(GLOBAL_DEF("debug/debug_port", 6007))); + + List<String> breakpoints; + ScriptEditor::get_singleton()->get_breakpoints(&breakpoints); + + + if (breakpoints.size()) { + + r_flags.push_back("-bp"); + String bpoints; + for(const List<String>::Element *E=breakpoints.front();E;E=E->next()) { + + bpoints+=E->get().replace(" ","%20"); + if (E->next()) + bpoints+=","; + } + + r_flags.push_back(bpoints); + } + + } + +} + Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { @@ -1029,7 +1072,7 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles, int p return OK; } -Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug, bool p_dumb) { +Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug, bool p_dumb,bool p_remote_debug) { diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h index 9704d4a695..f134a479a4 100644 --- a/tools/editor/editor_import_export.h +++ b/tools/editor/editor_import_export.h @@ -104,6 +104,7 @@ protected: }; + void gen_export_flags(Vector<String> &r_flags,bool p_dumb,bool p_remote_debug); static Error save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total); public: @@ -131,14 +132,14 @@ public: virtual int get_device_count() const { return 0; } virtual String get_device_name(int p_device) const { return ""; } virtual String get_device_info(int p_device) const { return ""; } - virtual Error run(int p_device,bool p_dumb=false) { return OK; } + virtual Error run(int p_device,bool p_dumb=false,bool p_remote_debug=false) { return OK; } virtual bool can_export(String *r_error=NULL) const=0; virtual bool requieres_password(bool p_debug) const { return false; } virtual String get_binary_extension() const=0; - virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false)=0; + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false,bool p_remote_debug=false)=0; EditorExportPlatform() {}; }; @@ -188,7 +189,7 @@ public: virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; } virtual String get_binary_extension() const { return binary_extension; } - virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); + virtual Error export_project(const String& p_path, bool p_debug, bool p_dumb=false, bool p_remote_debug=false); virtual void set_release_binary32(const String& p_binary) { release_binary32=p_binary; } virtual void set_debug_binary32(const String& p_binary) { debug_binary32=p_binary; } virtual void set_release_binary64(const String& p_binary) { release_binary64=p_binary; } diff --git a/tools/editor/editor_log.cpp b/tools/editor/editor_log.cpp index 8d49655960..2d26490a8a 100644 --- a/tools/editor/editor_log.cpp +++ b/tools/editor/editor_log.cpp @@ -104,6 +104,17 @@ void EditorLog::_close_request() { } +void EditorLog::_clear_request() { + + log->clear(); + +} + +void EditorLog::clear() { + _clear_request(); +} + + void EditorLog::add_message(const String& p_msg,bool p_error) { @@ -167,9 +178,12 @@ void EditorLog::_bind_methods() { ObjectTypeDB::bind_method(_MD("_close_request"),&EditorLog::_close_request ); ObjectTypeDB::bind_method(_MD("_flip_request"),&EditorLog::_flip_request ); + ObjectTypeDB::bind_method(_MD("_clear_request"),&EditorLog::_clear_request ); + //ObjectTypeDB::bind_method(_MD("_dragged"),&EditorLog::_dragged ); ADD_SIGNAL( MethodInfo("close_request")); ADD_SIGNAL( MethodInfo("show_request")); + ADD_SIGNAL( MethodInfo("clear_request")); } EditorLog::EditorLog() { @@ -198,6 +212,11 @@ EditorLog::EditorLog() { //pd->connect("dragged",this,"_dragged"); //pd->set_default_cursor_shape(Control::CURSOR_MOVE); + clearbutton = memnew( Button ); + hb->add_child(clearbutton); + clearbutton->set_text("Clear"); + clearbutton->connect("pressed", this,"_clear_request"); + tb = memnew( TextureButton ); hb->add_child(tb); tb->connect("pressed",this,"_close_request"); @@ -241,8 +260,8 @@ void EditorLog::deinit() { } + EditorLog::~EditorLog() { } - diff --git a/tools/editor/editor_log.h b/tools/editor/editor_log.h index 1141d03911..6950ffa1a0 100644 --- a/tools/editor/editor_log.h +++ b/tools/editor/editor_log.h @@ -45,6 +45,7 @@ class EditorLog : public PanelContainer { OBJ_TYPE( EditorLog, PanelContainer ); ToolButton *button; + Button *clearbutton; Label *title; RichTextLabel *log; TextureButton *tb; @@ -58,10 +59,10 @@ class EditorLog : public PanelContainer { Thread::ID current; - // void _dragged(const Point2& p_ofs); void _close_request(); void _flip_request(); + void _clear_request(); static void _undo_redo_cbk(void *p_self,const String& p_name); protected: @@ -73,6 +74,7 @@ public: void deinit(); ToolButton *get_button(); + void clear(); EditorLog(); ~EditorLog(); }; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 7b44f2cad9..b0a2c568de 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -93,6 +93,7 @@ #include "plugins/light_occluder_2d_editor_plugin.h" #include "plugins/color_ramp_editor_plugin.h" #include "plugins/collision_shape_2d_editor_plugin.h" + // end #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "tools/editor/io_plugins/editor_scene_import_plugin.h" @@ -103,16 +104,38 @@ #include "plugins/editor_preview_plugins.h" +#include "script_editor_debugger.h" EditorNode *EditorNode::singleton=NULL; void EditorNode::_update_scene_tabs() { scene_tabs->clear_tabs(); + Ref<Texture> script_icon = gui_base->get_icon("Script","EditorIcons"); for(int i=0;i<editor_data.get_edited_scene_count();i++) { + + String type=editor_data.get_scene_type(i); + Ref<Texture> icon; + if (type!=String()) { + + if (!gui_base->has_icon(type,"EditorIcons")) { + type="Node"; + } + + icon=gui_base->get_icon(type,"EditorIcons"); + + } + + + int current = editor_data.get_edited_scene(); bool unsaved = (i==current)?saved_version!=editor_data.get_undo_redo().get_version():editor_data.get_scene_version(i)!=0; - scene_tabs->add_tab(editor_data.get_scene_title(i)+(unsaved?"(*)":"")); + scene_tabs->add_tab(editor_data.get_scene_title(i)+(unsaved?"(*)":""),icon); + + if (editor_data.get_scene_root_script(i).is_valid()) { + scene_tabs->set_tab_right_button(i,script_icon); + } + } scene_tabs->set_current_tab(editor_data.get_edited_scene()); @@ -206,7 +229,7 @@ void EditorNode::_notification(int p_what) { circle_step=0; circle_step_msec=tick; - circle_step_frame=frame+1; + circle_step_frame=frame+1; update_menu->set_icon(gui_base->get_icon("Progress"+itos(circle_step+1),"EditorIcons")); @@ -1564,7 +1587,6 @@ void EditorNode::_run(bool p_current,const String& p_custom) { Node *scene = editor_data.get_edited_scene_root(); if (!scene) { - current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("I see.."); @@ -1645,6 +1667,10 @@ void EditorNode::_run(bool p_current,const String& p_custom) { editor_data.save_editor_external_data(); } + if (bool(EDITOR_DEF("run/always_clear_output_on_play", true))) { + log->clear(); + } + List<String> breakpoints; editor_data.get_editor_breakpoints(&breakpoints); @@ -2343,6 +2369,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { _run(true); } break; + case RUN_PLAY_NATIVE: { + + emit_signal("play_pressed"); + editor_run.run_native_notify(); + + + } break; case RUN_SCENE_SETTINGS: { run_settings_dialog->popup_run_settings(); @@ -2374,28 +2407,43 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case RUN_FILE_SERVER: { //file_server - bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER)); + bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER)); if (ischecked) { file_server->stop(); - fileserver_menu->set_icon(gui_base->get_icon("FileServer","EditorIcons")); - fileserver_menu->get_popup()->set_item_text( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Enable File Server"); + //debug_button->set_icon(gui_base->get_icon("FileServer","EditorIcons")); + //debug_button->get_popup()->set_item_text( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),"Enable File Server"); } else { file_server->start(); - fileserver_menu->set_icon(gui_base->get_icon("FileServerActive","EditorIcons")); - fileserver_menu->get_popup()->set_item_text( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Disable File Server"); + //debug_button->set_icon(gui_base->get_icon("FileServerActive","EditorIcons")); + //debug_button->get_popup()->set_item_text( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),"Disable File Server"); } - fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_FILE_SERVER),!ischecked); + debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),!ischecked); } break; + case RUN_LIVE_DEBUG: { + + bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_LIVE_DEBUG)); + + debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_LIVE_DEBUG),!ischecked); + ScriptEditor::get_singleton()->get_debugger()->set_live_debugging(!ischecked); + } break; + case RUN_DEPLOY_DUMB_CLIENTS: { - bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS)); - fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked); + bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS)); + debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked); run_native->set_deploy_dumb(!ischecked); } break; + case RUN_DEPLOY_REMOTE_DEBUG: { + + bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG)); + debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG),!ischecked); + run_native->set_deploy_debug_remote(!ischecked); + + } break; case SETTINGS_UPDATE_ALWAYS: { update_menu->get_popup()->set_item_checked(0,true); @@ -2997,6 +3045,7 @@ void EditorNode::set_current_scene(int p_idx) { call_deferred("_set_main_scene_state",state); //do after everything else is done setting up //print_line("set current 6 "); changing_scene=false; + ScriptEditor::get_singleton()->get_debugger()->update_live_edit_root(); } @@ -3134,6 +3183,8 @@ Error EditorNode::load_scene(const String& p_scene) { prev_scene->set_disabled(previous_scenes.size()==0); opening_prev=false; + ScriptEditor::get_singleton()->get_debugger()->update_live_edit_root(); + //top_pallete->set_current_tab(0); //always go to scene push_item(new_scene); @@ -3569,6 +3620,7 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("set_current_scene",&EditorNode::set_current_scene); ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version); ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed); + ObjectTypeDB::bind_method("_scene_tab_script_edited",&EditorNode::_scene_tab_script_edited); ObjectTypeDB::bind_method("_set_main_scene_state",&EditorNode::_set_main_scene_state); ObjectTypeDB::bind_method("_update_scene_tabs",&EditorNode::_update_scene_tabs); @@ -4013,6 +4065,13 @@ void EditorNode::_load_docks() { } +void EditorNode::_scene_tab_script_edited(int p_tab) { + + Ref<Script> script = editor_data.get_scene_root_script(p_tab); + if (script.is_valid()) + edit_resource(script); +} + void EditorNode::_scene_tab_changed(int p_tab) { @@ -4167,6 +4226,7 @@ EditorNode::EditorNode() { scene_tabs->add_tab("unsaved"); scene_tabs->set_tab_align(Tabs::ALIGN_CENTER); scene_tabs->connect("tab_changed",this,"_scene_tab_changed"); + scene_tabs->connect("right_button_pressed",this,"_scene_tab_script_edited"); top_dark_vb->add_child(scene_tabs); //left left_l_hsplit = memnew( HSplitContainer ); @@ -4564,6 +4624,7 @@ EditorNode::EditorNode() { menu_hb->add_child(native_play_button); native_play_button->hide(); native_play_button->get_popup()->connect("item_pressed",this,"_run_in_device"); + run_native->connect("native_run",this,"_menu_option",varray(RUN_PLAY_NATIVE)); // VSeparator *s1 = memnew( VSeparator ); // play_hb->add_child(s1); @@ -4584,21 +4645,21 @@ EditorNode::EditorNode() { play_custom_scene_button->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY_CUSTOM_SCENE)); play_custom_scene_button->set_tooltip("Play custom scene ("+keycode_get_string(KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_F5)+")."); - fileserver_menu = memnew( MenuButton ); - play_hb->add_child(fileserver_menu); - fileserver_menu->set_flat(true); - fileserver_menu->set_focus_mode(Control::FOCUS_NONE); - fileserver_menu->set_icon(gui_base->get_icon("FileServer","EditorIcons")); - //fileserver_menu->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY_CUSTOM_SCENE)); - fileserver_menu->set_tooltip("Serve the project filesystem to remote clients."); - - p=fileserver_menu->get_popup(); - p->add_check_item("Enable File Server",RUN_FILE_SERVER); - p->set_item_tooltip(p->get_item_index(RUN_FILE_SERVER),"Enable/Disable the File Server."); + debug_button = memnew( MenuButton ); + debug_button->set_flat(true); + play_hb->add_child(debug_button); + //debug_button->set_toggle_mode(true); + debug_button->set_focus_mode(Control::FOCUS_NONE); + debug_button->set_icon(gui_base->get_icon("Remote","EditorIcons")); + //debug_button->connect("pressed", this,"_menu_option",make_binds(RUN_LIVE_DEBUG)); + debug_button->set_tooltip("Debug Options"); + + p=debug_button->get_popup(); + p->add_check_item("Live Editing",RUN_LIVE_DEBUG); + p->add_check_item("File Server",RUN_FILE_SERVER); p->add_separator(); - p->add_check_item("Deploy Dumb Clients",RUN_DEPLOY_DUMB_CLIENTS); - //p->set_item_checked( p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),true ); - p->set_item_tooltip(p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),"Deploy dumb clients when the File Server is active."); + p->add_check_item("Deploy Remote Debug",RUN_DEPLOY_REMOTE_DEBUG); + p->add_check_item("Deploy File Server Clients",RUN_DEPLOY_DUMB_CLIENTS); p->connect("item_pressed",this,"_menu_option"); /* diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 293da2031d..d40658a056 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -146,12 +146,15 @@ class EditorNode : public Node { RUN_PAUSE, RUN_STOP, RUN_PLAY_SCENE, + RUN_PLAY_NATIVE, RUN_PLAY_CUSTOM_SCENE, RUN_SCENE_SETTINGS, RUN_SETTINGS, RUN_PROJECT_MANAGER, RUN_FILE_SERVER, RUN_DEPLOY_DUMB_CLIENTS, + RUN_LIVE_DEBUG, + RUN_DEPLOY_REMOTE_DEBUG, SETTINGS_UPDATE_ALWAYS, SETTINGS_UPDATE_CHANGES, SETTINGS_IMPORT, @@ -239,8 +242,9 @@ class EditorNode : public Node { ToolButton *animation_menu; ToolButton *play_scene_button; ToolButton *play_custom_scene_button; + MenuButton *debug_button; TextureProgress *audio_vu; - MenuButton *fileserver_menu; + //MenuButton *fileserver_menu; TextEdit *load_errors; AcceptDialog *load_error_dialog; @@ -469,6 +473,7 @@ class EditorNode : public Node { void _dock_split_dragged(int ofs); void _dock_popup_exit(); void _scene_tab_changed(int p_tab); + void _scene_tab_script_edited(int p_tab); Dictionary _get_main_scene_state(); void _set_main_scene_state(Dictionary p_state); diff --git a/tools/editor/editor_run.h b/tools/editor/editor_run.h index 5541cc84fa..402d5e3820 100644 --- a/tools/editor/editor_run.h +++ b/tools/editor/editor_run.h @@ -48,6 +48,7 @@ public: Status get_status() const; Error run(const String& p_scene,const String p_custom_args,const List<String>& p_breakpoints,const String& p_edited_scene); + void run_native_notify() { status=STATUS_PLAY; } void stop(); EditorRun(); }; diff --git a/tools/editor/editor_run_native.cpp b/tools/editor/editor_run_native.cpp index 83b1753ea2..42c7f89608 100644 --- a/tools/editor/editor_run_native.cpp +++ b/tools/editor/editor_run_native.cpp @@ -101,12 +101,18 @@ void EditorRunNative::_run_native(int p_idx,const String& p_platform) { Ref<EditorExportPlatform> eep = EditorImportExport::get_singleton()->get_export_platform(p_platform); ERR_FAIL_COND(eep.is_null()); - eep->run(p_idx,deploy_dumb); + if (deploy_debug_remote) { + emit_signal("native_run"); + + } + eep->run(p_idx,deploy_dumb,deploy_debug_remote); } void EditorRunNative::_bind_methods() { ObjectTypeDB::bind_method("_run_native",&EditorRunNative::_run_native); + + ADD_SIGNAL(MethodInfo("native_run")); } void EditorRunNative::set_deploy_dumb(bool p_enabled) { @@ -119,10 +125,21 @@ bool EditorRunNative::is_deploy_dumb_enabled() const{ return deploy_dumb; } +void EditorRunNative::set_deploy_debug_remote(bool p_enabled) { + + deploy_debug_remote=p_enabled; +} + +bool EditorRunNative::is_deploy_debug_remote_enabled() const{ + + return deploy_debug_remote; +} + EditorRunNative::EditorRunNative() { set_process(true); first=true; deploy_dumb=false; + deploy_debug_remote=false; } diff --git a/tools/editor/editor_run_native.h b/tools/editor/editor_run_native.h index 1512dc5dd9..a0baf527f1 100644 --- a/tools/editor/editor_run_native.h +++ b/tools/editor/editor_run_native.h @@ -39,6 +39,7 @@ class EditorRunNative : public HBoxContainer { Map<StringName,MenuButton*> menus; bool first; bool deploy_dumb; + bool deploy_debug_remote; void _run_native(int p_idx,const String& p_platform); @@ -50,6 +51,10 @@ public: void set_deploy_dumb(bool p_enabled); bool is_deploy_dumb_enabled() const; + + void set_deploy_debug_remote(bool p_enabled); + bool is_deploy_debug_remote_enabled() const; + EditorRunNative(); }; diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 0df9fcadef..2f61d4f09d 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -274,6 +274,7 @@ void EditorSettings::create() { print_line("EditorSettings: Load OK!"); } + singleton->setup_network(); singleton->load_favorites(); singleton->scan_plugins(); @@ -289,6 +290,7 @@ void EditorSettings::create() { singleton->config_file_path=config_file_path; singleton->settings_path=config_path+"/"+config_dir; singleton->_load_defaults(); + singleton->setup_network(); singleton->scan_plugins(); @@ -330,6 +332,35 @@ Error EditorSettings::_load_plugin(const String& p_path, Plugin &plugin) { return OK; } +void EditorSettings::setup_network() { + + List<IP_Address> local_ip; + IP::get_singleton()->get_local_addresses(&local_ip); + String lip; + String hint; + String current=get("network/debug_host"); + + for(List<IP_Address>::Element *E=local_ip.front();E;E=E->next()) { + + String ip = E->get(); + if (ip=="127.0.0.1") + continue; + + if (lip!="") + lip=ip; + if (ip==current) + lip=current; //so it saves + if (hint!="") + hint+=","; + hint+=ip; + + } + + set("network/debug_host",lip); + add_property_hint(PropertyInfo(Variant::STRING,"network/debug_host",PROPERTY_HINT_ENUM,hint)); + +} + void EditorSettings::scan_plugins() { Map<String,Plugin> new_plugins; @@ -465,6 +496,7 @@ void EditorSettings::_load_defaults() { set("2d_editor/bone_selected_color",Color(0.9,0.45,0.45,0.9)); set("2d_editor/bone_ik_color",Color(0.9,0.9,0.45,0.9)); + set("on_save/compress_binary_resources",true); set("on_save/save_modified_external_resources",true); set("on_save/save_paths_as_relative",false); diff --git a/tools/editor/editor_settings.h b/tools/editor/editor_settings.h index 6b7e6eb989..4ba940cd1c 100644 --- a/tools/editor/editor_settings.h +++ b/tools/editor/editor_settings.h @@ -113,6 +113,7 @@ public: void scan_plugins(); void enable_plugins(); + void setup_network(); void raise_order(const String& p_name); static void create(); diff --git a/tools/editor/fileserver/editor_file_server.cpp b/tools/editor/fileserver/editor_file_server.cpp index b66a1d522b..ea95e4da1c 100644 --- a/tools/editor/fileserver/editor_file_server.cpp +++ b/tools/editor/fileserver/editor_file_server.cpp @@ -318,27 +318,7 @@ EditorFileServer::EditorFileServer() { cmd=CMD_NONE; thread=Thread::create(_thread_start,this); - List<IP_Address> local_ip; - IP::get_singleton()->get_local_addresses(&local_ip); EDITOR_DEF("file_server/port",6010); - String lip; - String hint; - for(List<IP_Address>::Element *E=local_ip.front();E;E=E->next()) { - - String ip = E->get(); - if (ip=="127.0.0.1") - continue; - - if (lip!="") - lip=ip; - if (hint!="") - hint+=","; - hint+=ip; - - } - - EDITOR_DEF("file_server/host",lip); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"file_server/host",PROPERTY_HINT_ENUM,hint)); EDITOR_DEF("file_server/password",""); } diff --git a/tools/editor/icons/icon_debug.png b/tools/editor/icons/icon_debug.png Binary files differnew file mode 100644 index 0000000000..03b98aa9e4 --- /dev/null +++ b/tools/editor/icons/icon_debug.png diff --git a/tools/editor/icons/icon_live_debug.png b/tools/editor/icons/icon_live_debug.png Binary files differnew file mode 100644 index 0000000000..ad55646b9a --- /dev/null +++ b/tools/editor/icons/icon_live_debug.png diff --git a/tools/editor/icons/icon_remote.png b/tools/editor/icons/icon_remote.png Binary files differnew file mode 100644 index 0000000000..792d958a46 --- /dev/null +++ b/tools/editor/icons/icon_remote.png diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index b15abf8096..302e4f2196 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -321,10 +321,10 @@ void ScriptTextEditor::_load_theme_settings() { //colorize engine types Color type_color= EDITOR_DEF("text_editor/engine_type_color",Color(0.0,0.2,0.4)); - List<String> types; + List<StringName> types; ObjectTypeDB::get_type_list(&types); - for(List<String>::Element *E=types.front();E;E=E->next()) { + for(List<StringName>::Element *E=types.front();E;E=E->next()) { get_text_edit()->add_keyword_color(E->get(),type_color); } @@ -1101,6 +1101,7 @@ void ScriptEditor::_menu_option(int p_option) { int line=current->get_text_edit()->cursor_get_line(); bool dobreak = !current->get_text_edit()->is_line_set_as_breakpoint(line); current->get_text_edit()->set_line_as_breakpoint(line,dobreak); + get_debugger()->set_breakpoint(current->get_edited_script()->get_path(),line+1,dobreak); } break; case DEBUG_NEXT: { diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index 0dd152cb25..59173068fb 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -250,6 +250,8 @@ public: void set_window_layout(Ref<ConfigFile> p_layout); void get_window_layout(Ref<ConfigFile> p_layout); + ScriptEditorDebugger *get_debugger() { return debugger; } + ScriptEditor(EditorNode *p_editor); ~ScriptEditor(); }; diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 017a26441d..66c7a39096 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -107,8 +107,8 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo if (p_with_undo) { - undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose); - undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose); + undo_redo->add_do_method(node,"set_cellv",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose); + undo_redo->add_undo_method(node,"set_cellv",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose); } else { node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); @@ -314,8 +314,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); - undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); + undo_redo->add_do_method(node,"set_cellv",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + undo_redo->add_undo_method(node,"set_cellv",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -344,7 +344,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { //return true; _set_cell(local,TileMap::INVALID_CELL); return true; - } else { + } else if (!mb.pressed) { if (tool==TOOL_ERASING) { @@ -353,9 +353,10 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - //undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); - _set_cell(p,TileMap::INVALID_CELL,false,false,false,true); - undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); + //undo_redo->add_do_method(node,"set_cell",p,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + //_set_cell(p,TileMap::INVALID_CELL,false,false,false,true); + undo_redo->add_do_method(node,"set_cellv",Point2(p),TileMap::INVALID_CELL,false,false,false); + undo_redo->add_undo_method(node,"set_cellv",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index e38c672a3e..a087f23c25 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -1131,7 +1131,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) { tree->set_column_min_width(1,90); filters = memnew( LineEdit ); - vb->add_margin_child("Filters for Non-Resources (Comma Separated):",filters); + vb->add_margin_child("Filters to export non-resource files (Comma Separated, ie: *.json, *.txt):",filters); filters->connect("text_changed",this,"_filters_edited"); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 2fa8b98ff1..955c426d2b 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -614,9 +614,9 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty Set<String> valid_inheritors; valid_inheritors.insert(base); - List<String> inheritors; + List<StringName> inheritors; ObjectTypeDB::get_inheriters_from(base.strip_edges(),&inheritors); - List<String>::Element *E=inheritors.front(); + List<StringName>::Element *E=inheritors.front(); while(E) { valid_inheritors.insert(E->get()); E=E->next(); diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 49cbebdb43..ae0b58a665 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -33,7 +33,8 @@ #include "scene/resources/packed_scene.h" #include "editor_settings.h" #include "tools/editor/plugins/canvas_item_editor_plugin.h" - +#include "script_editor_debugger.h" +#include "tools/editor/plugins/script_editor_plugin.h" void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { @@ -105,6 +106,13 @@ Node* SceneTreeDock::instance(const String& p_file) { editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",instanced_scene); editor_data->get_undo_redo().add_do_reference(instanced_scene); editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene); + + + String new_name = parent->validate_child_name(instanced_scene->get_name()); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",edited_scene->get_path_to(parent),p_file,new_name); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name)); + editor_data->get_undo_redo().commit_action(); @@ -389,9 +397,14 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { editor_data->get_undo_redo().add_do_method(d,"set_owner",node->get_owner()); } editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",dup); - editor_data->get_undo_redo().add_undo_method(parent,"remove_child",dup); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",dup); editor_data->get_undo_redo().add_do_reference(dup); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + + editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),attempt); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+attempt)); + //parent->add_child(dup); //reselect.push_back(dup); } @@ -903,6 +916,13 @@ void SceneTreeDock::_node_reparent(NodePath p_path,bool p_node_only) { editor_data->get_undo_redo().add_do_method(node->get_parent(),"remove_child",node); editor_data->get_undo_redo().add_do_method(new_parent,"add_child",node); + + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + String new_name = new_parent->validate_child_name(node->get_name()); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_reparent_node",edited_scene->get_path_to(node),edited_scene->get_path_to(new_parent),new_name,-1); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_reparent_node",NodePath(String(edited_scene->get_path_to(new_parent))+"/"+new_name),edited_scene->get_path_to(node->get_parent()),node->get_name(),node->get_index()); + + editor_data->get_undo_redo().add_do_method(this,"_set_owners",edited_scene,owners); if (editor->get_animation_editor()->get_root()==node) @@ -1025,6 +1045,11 @@ void SceneTreeDock::_delete_confirm() { editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); //editor_data->get_undo_redo().add_undo_method(n,"set_owner",n->get_owner()); editor_data->get_undo_redo().add_undo_reference(n); + + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_remove_and_keep_node",edited_scene->get_path_to(n),n->get_instance_ID()); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_restore_node",n->get_instance_ID(),edited_scene->get_path_to(n->get_parent()),n->get_index()); + } @@ -1082,12 +1107,20 @@ void SceneTreeDock::_create() { editor_data->get_undo_redo().create_action("Create Node"); if (edited_scene) { + editor_data->get_undo_redo().add_do_method(parent,"add_child",child); editor_data->get_undo_redo().add_do_method(child,"set_owner",edited_scene); editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",child); editor_data->get_undo_redo().add_do_reference(child); editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child); + + + String new_name = parent->validate_child_name(child->get_type()); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",edited_scene->get_path_to(parent),child->get_type(),new_name); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name)); + } else { editor_data->get_undo_redo().add_do_method(editor,"set_edited_scene",child); diff --git a/tools/editor/script_editor_debugger.cpp b/tools/editor/script_editor_debugger.cpp index 13734f2c4b..2e1fa2814e 100644 --- a/tools/editor/script_editor_debugger.cpp +++ b/tools/editor/script_editor_debugger.cpp @@ -241,6 +241,8 @@ void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_dat lv[level]=it; } + le_clear->set_disabled(false); + le_set->set_disabled(false); } else if (p_msg=="stack_dump") { @@ -342,6 +344,63 @@ void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_dat perf_history.push_front(p); perf_draw->update(); + } else if (p_msg=="error") { + + Array err = p_data[0]; + + Array vals; + vals.push_back(err[0]); + vals.push_back(err[1]); + vals.push_back(err[2]); + vals.push_back(err[3]); + + bool warning = err[9]; + bool e; + String time = String("%d:%02d:%02d:%04d").sprintf(vals,&e); + String txt=time+" - "+String(err[8]); + + String tooltip="Type:"+String(warning?"Warning":"Error"); + tooltip+="\nDescription: "+String(err[8]); + tooltip+="\nTime: "+time; + tooltip+="\nC Error: "+String(err[7]); + tooltip+="\nC Source: "+String(err[5])+":"+String(err[6]); + tooltip+="\nC Function: "+String(err[4]); + + + + error_list->add_item(txt,EditorNode::get_singleton()->get_gui_base()->get_icon(warning?"Warning":"Error","EditorIcons")); + error_list->set_item_tooltip( error_list->get_item_count() -1,tooltip ); + + int scc = p_data[1]; + + Array stack; + stack.resize(scc); + for(int i=0;i<scc;i++) { + stack[i]=p_data[2+i]; + } + + error_list->set_item_metadata( error_list->get_item_count() -1,stack ); + + error_count++; + /* + int count = p_data[1]; + + Array cstack; + + OutputError oe = errors.front()->get(); + + packet_peer_stream->put_var(oe.hr); + packet_peer_stream->put_var(oe.min); + packet_peer_stream->put_var(oe.sec); + packet_peer_stream->put_var(oe.msec); + packet_peer_stream->put_var(oe.source_func); + packet_peer_stream->put_var(oe.source_file); + packet_peer_stream->put_var(oe.source_line); + packet_peer_stream->put_var(oe.error); + packet_peer_stream->put_var(oe.error_descr); + packet_peer_stream->put_var(oe.warning); + packet_peer_stream->put_var(oe.callstack); + */ } else if (p_msg=="kill_me") { editor->call_deferred("stop_child_process"); @@ -443,10 +502,23 @@ void ScriptEditorDebugger::_notification(int p_what) { tb->set_hover_texture( get_icon("CloseHover","EditorIcons")); tb->set_pressed_texture( get_icon("Close","EditorIcons")); scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons")); + le_set->connect("pressed",this,"_live_edit_set"); + le_clear->connect("pressed",this,"_live_edit_clear"); + error_list->connect("item_selected",this,"_error_selected"); + error_stack->connect("item_selected",this,"_error_stack_selected"); } break; case NOTIFICATION_PROCESS: { + if (error_count!=last_error_count) { + + if (error_count==0) { + error_split->set_name("Errors"); + } else { + error_split->set_name("Errors ("+itos(error_count)+")"); + } + last_error_count=error_count; + } if (connection.is_null()) { if (server->is_connection_available()) { @@ -468,6 +540,15 @@ void ScriptEditorDebugger::_notification(int p_what) { emit_signal("show_debugger",true); reason->set_text("Child Process Connected"); reason->set_tooltip("Child Process Connected"); + scene_tree->clear(); + le_set->set_disabled(true); + le_clear->set_disabled(false); + error_list->clear(); + error_stack->clear(); + error_count=0; + //live_edit_root->set_text("/root"); + + update_live_edit_root(); } else { @@ -613,6 +694,10 @@ void ScriptEditorDebugger::stop(){ log_forced_visible=false; } + node_path_cache.clear(); + res_path_cache.clear(); + le_clear->set_disabled(false); + le_set->set_disabled(true); hide(); @@ -664,6 +749,381 @@ String ScriptEditorDebugger::get_var_value(const String& p_var) const { return variables->get_var_value(p_var); } +int ScriptEditorDebugger::_get_node_path_cache(const NodePath& p_path) { + + const int *r = node_path_cache.getptr(p_path); + if (r) + return *r; + + last_path_id++; + + node_path_cache[p_path]=last_path_id; + Array msg; + msg.push_back("live_node_path"); + msg.push_back(p_path); + msg.push_back(last_path_id); + ppeer->put_var(msg); + + + return last_path_id; +} + +int ScriptEditorDebugger::_get_res_path_cache(const String& p_path) { + + Map<String,int>::Element *E=res_path_cache.find(p_path); + + if (E) + return E->get(); + + last_path_id++; + + res_path_cache[p_path]=last_path_id; + Array msg; + msg.push_back("live_res_path"); + msg.push_back(p_path); + msg.push_back(last_path_id); + ppeer->put_var(msg); + + + return last_path_id; +} + +void ScriptEditorDebugger::_method_changed(Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE) { + + if (!p_base || !live_debug || !connection.is_valid() || !editor->get_edited_scene()) + return; + + Node *node = p_base->cast_to<Node>(); + + VARIANT_ARGPTRS + + for(int i=0;i<VARIANT_ARG_MAX;i++) { + //no pointers, sorry + if (argptr[i] && (argptr[i]->get_type()==Variant::OBJECT || argptr[i]->get_type()==Variant::_RID)) + return; + } + + if (node) { + + NodePath path = editor->get_edited_scene()->get_path_to(node); + int pathid = _get_node_path_cache(path); + + + + Array msg; + msg.push_back("live_node_call"); + msg.push_back(pathid); + msg.push_back(p_name); + for(int i=0;i<VARIANT_ARG_MAX;i++) { + //no pointers, sorry + msg.push_back(*argptr[i]); + } + ppeer->put_var(msg); + + return; + + } + + Resource *res = p_base->cast_to<Resource>(); + + if (res && res->get_path()!=String()) { + + String respath = res->get_path(); + int pathid = _get_res_path_cache(respath); + + Array msg; + msg.push_back("live_res_call"); + msg.push_back(pathid); + msg.push_back(p_name); + for(int i=0;i<VARIANT_ARG_MAX;i++) { + //no pointers, sorry + msg.push_back(*argptr[i]); + } + ppeer->put_var(msg); + + return; + } + + //print_line("method"); +} + +void ScriptEditorDebugger::_property_changed(Object*p_base,const StringName& p_property,const Variant& p_value){ + + if (!p_base || !live_debug || !connection.is_valid() || !editor->get_edited_scene()) + return; + + Node *node = p_base->cast_to<Node>(); + + if (node) { + + NodePath path = editor->get_edited_scene()->get_path_to(node); + int pathid = _get_node_path_cache(path); + + + if (p_value.is_ref()) { + Ref<Resource> res = p_value; + if (res.is_valid() && res->get_path()!=String()) { + + Array msg; + msg.push_back("live_node_prop_res"); + msg.push_back(pathid); + msg.push_back(p_property); + msg.push_back(res->get_path()); + ppeer->put_var(msg); + } + } else { + + Array msg; + msg.push_back("live_node_prop"); + msg.push_back(pathid); + msg.push_back(p_property); + msg.push_back(p_value); + ppeer->put_var(msg); + } + + + return; + + } + + Resource *res = p_base->cast_to<Resource>(); + + if (res && res->get_path()!=String()) { + + String respath = res->get_path(); + int pathid = _get_res_path_cache(respath); + + + if (p_value.is_ref()) { + Ref<Resource> res = p_value; + if (res.is_valid() && res->get_path()!=String()) { + + Array msg; + msg.push_back("live_res_prop_res"); + msg.push_back(pathid); + msg.push_back(p_property); + msg.push_back(res->get_path()); + ppeer->put_var(msg); + } + } else { + + Array msg; + msg.push_back("live_res_prop"); + msg.push_back(pathid); + msg.push_back(p_property); + msg.push_back(p_value); + ppeer->put_var(msg); + } + + + return; + } + + + //print_line("prop"); +} + +void ScriptEditorDebugger::_method_changeds(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE) { + + ScriptEditorDebugger *sed = (ScriptEditorDebugger*)p_ud; + sed->_method_changed(p_base,p_name,VARIANT_ARG_PASS); + + +} + +void ScriptEditorDebugger::_property_changeds(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value){ + + ScriptEditorDebugger *sed = (ScriptEditorDebugger*)p_ud; + sed->_property_changed(p_base,p_property,p_value); + +} + +void ScriptEditorDebugger::set_live_debugging(bool p_enable) { + + live_debug=p_enable; +} + +void ScriptEditorDebugger::_live_edit_set() { + + if (!connection.is_valid()) + return; + + TreeItem* ti = scene_tree->get_selected(); + if (!ti) + return; + String path; + + while(ti) { + String lp=ti->get_text(0); + path="/"+lp+path; + ti=ti->get_parent(); + + } + + NodePath np = path; + + editor->get_editor_data().set_edited_scene_live_edit_root(np); + + update_live_edit_root(); + + +} + +void ScriptEditorDebugger::_live_edit_clear() { + + NodePath np = NodePath("/root"); + editor->get_editor_data().set_edited_scene_live_edit_root(np); + + update_live_edit_root(); + +} + +void ScriptEditorDebugger::update_live_edit_root() { + + NodePath np = editor->get_editor_data().get_edited_scene_live_edit_root(); + + if (connection.is_valid()) { + Array msg; + msg.push_back("live_set_root"); + msg.push_back(np); + if (editor->get_edited_scene()) + msg.push_back(editor->get_edited_scene()->get_filename()); + else + msg.push_back(""); + ppeer->put_var(msg); + } + live_edit_root->set_text(np); + +} + +void ScriptEditorDebugger::live_debug_create_node(const NodePath& p_parent,const String& p_type,const String& p_name) { + + if (live_debug && connection.is_valid()) { + Array msg; + msg.push_back("live_create_node"); + msg.push_back(p_parent); + msg.push_back(p_type); + msg.push_back(p_name); + ppeer->put_var(msg); + } +} + +void ScriptEditorDebugger::live_debug_instance_node(const NodePath& p_parent,const String& p_path,const String& p_name){ + + if (live_debug && connection.is_valid()) { + Array msg; + msg.push_back("live_instance_node"); + msg.push_back(p_parent); + msg.push_back(p_path); + msg.push_back(p_name); + ppeer->put_var(msg); + } + +} +void ScriptEditorDebugger::live_debug_remove_node(const NodePath& p_at){ + + if (live_debug && connection.is_valid()) { + Array msg; + msg.push_back("live_remove_node"); + msg.push_back(p_at); + ppeer->put_var(msg); + } + +} +void ScriptEditorDebugger::live_debug_remove_and_keep_node(const NodePath& p_at,ObjectID p_keep_id) { + + if (live_debug && connection.is_valid()) { + Array msg; + msg.push_back("live_remove_and_keep_node"); + msg.push_back(p_at); + msg.push_back(p_keep_id); + ppeer->put_var(msg); + } + +} +void ScriptEditorDebugger::live_debug_restore_node(ObjectID p_id, const NodePath& p_at, int p_at_pos){ + + if (live_debug && connection.is_valid()) { + Array msg; + msg.push_back("live_restore_node"); + msg.push_back(p_id); + msg.push_back(p_at); + msg.push_back(p_at_pos); + ppeer->put_var(msg); + } + +} +void ScriptEditorDebugger::live_debug_duplicate_node(const NodePath& p_at,const String& p_new_name){ + + if (live_debug && connection.is_valid()) { + Array msg; + msg.push_back("live_duplicate_node"); + msg.push_back(p_at); + msg.push_back(p_new_name); + ppeer->put_var(msg); + } + +} +void ScriptEditorDebugger::live_debug_reparent_node(const NodePath& p_at, const NodePath& p_new_place, const String &p_new_name, int p_at_pos){ + + if (live_debug && connection.is_valid()) { + Array msg; + msg.push_back("live_reparent_node"); + msg.push_back(p_at); + msg.push_back(p_new_place); + msg.push_back(p_new_name); + msg.push_back(p_at_pos); + ppeer->put_var(msg); + } + +} + +void ScriptEditorDebugger::set_breakpoint(const String& p_path,int p_line,bool p_enabled) { + + if (connection.is_valid()) { + Array msg; + msg.push_back("breakpoint"); + msg.push_back(p_path); + msg.push_back(p_line); + msg.push_back(p_enabled); + ppeer->put_var(msg); + } +} + + +void ScriptEditorDebugger::_error_selected(int p_idx) { + + error_stack->clear(); + Array st=error_list->get_item_metadata(p_idx); + for(int i=0;i<st.size();i+=2) { + + String script=st[i]; + int line=st[i+1]; + Array md; + md.push_back(st[i]); + md.push_back(st[i+1]); + + String str = script.get_file()+":"+itos(line); + + error_stack->add_item(str); + error_stack->set_item_metadata(error_stack->get_item_count()-1,md); + error_stack->set_item_tooltip(error_stack->get_item_count()-1,"File: "+String(st[i])+"\nLine: "+itos(line)); + } +} + +void ScriptEditorDebugger:: _error_stack_selected(int p_idx){ + + Array arr = error_stack->get_item_metadata(p_idx); + if (arr.size()!=2) + return; + + + Ref<Script> s = ResourceLoader::load(arr[0]); + emit_signal("goto_script_line",s,int(arr[1])-1); + +} + + void ScriptEditorDebugger::_bind_methods() { ObjectTypeDB::bind_method(_MD("_stack_dump_frame_selected"),&ScriptEditorDebugger::_stack_dump_frame_selected); @@ -676,6 +1136,19 @@ void ScriptEditorDebugger::_bind_methods() { ObjectTypeDB::bind_method(_MD("_performance_draw"),&ScriptEditorDebugger::_performance_draw); ObjectTypeDB::bind_method(_MD("_performance_select"),&ScriptEditorDebugger::_performance_select); ObjectTypeDB::bind_method(_MD("_scene_tree_request"),&ScriptEditorDebugger::_scene_tree_request); + ObjectTypeDB::bind_method(_MD("_live_edit_set"),&ScriptEditorDebugger::_live_edit_set); + ObjectTypeDB::bind_method(_MD("_live_edit_clear"),&ScriptEditorDebugger::_live_edit_clear); + + ObjectTypeDB::bind_method(_MD("_error_selected"),&ScriptEditorDebugger::_error_selected); + ObjectTypeDB::bind_method(_MD("_error_stack_selected"),&ScriptEditorDebugger::_error_stack_selected); + + ObjectTypeDB::bind_method(_MD("live_debug_create_node"),&ScriptEditorDebugger::live_debug_create_node); + ObjectTypeDB::bind_method(_MD("live_debug_instance_node"),&ScriptEditorDebugger::live_debug_instance_node); + ObjectTypeDB::bind_method(_MD("live_debug_remove_node"),&ScriptEditorDebugger::live_debug_remove_node); + ObjectTypeDB::bind_method(_MD("live_debug_remove_and_keep_node"),&ScriptEditorDebugger::live_debug_remove_and_keep_node); + ObjectTypeDB::bind_method(_MD("live_debug_restore_node"),&ScriptEditorDebugger::live_debug_restore_node); + ObjectTypeDB::bind_method(_MD("live_debug_duplicate_node"),&ScriptEditorDebugger::live_debug_duplicate_node); + ObjectTypeDB::bind_method(_MD("live_debug_reparent_node"),&ScriptEditorDebugger::live_debug_reparent_node); ADD_SIGNAL(MethodInfo("goto_script_line")); ADD_SIGNAL(MethodInfo("breaked",PropertyInfo(Variant::BOOL,"reallydid"))); @@ -789,6 +1262,23 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){ vbc->add_child(hbc); + error_split = memnew( HSplitContainer ); + VBoxContainer *errvb = memnew( VBoxContainer ); + errvb->set_h_size_flags(SIZE_EXPAND_FILL); + error_list = memnew( ItemList ); + errvb->add_margin_child("Errors:",error_list,true); + error_split->add_child(errvb); + + errvb = memnew( VBoxContainer ); + errvb->set_h_size_flags(SIZE_EXPAND_FILL); + error_stack = memnew( ItemList ); + errvb->add_margin_child("Stack Trace (if applies):",error_stack,true); + error_split->add_child(errvb); + + error_split->set_name("Errors"); + tabs->add_child(error_split); + + HSplitContainer *hsp = memnew( HSplitContainer ); perf_monitors = memnew(Tree); @@ -843,6 +1333,26 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){ info_left->add_margin_child("Clicked Control:",clicked_ctrl); clicked_ctrl_type = memnew( LineEdit ); info_left->add_margin_child("Clicked Control Type:",clicked_ctrl_type); + + live_edit_root = memnew( LineEdit ); + + { + HBoxContainer *lehb = memnew( HBoxContainer ); + Label *l = memnew( Label("Live Edit Root:") ); + lehb->add_child(l); + l->set_h_size_flags(SIZE_EXPAND_FILL); + le_set = memnew( Button("Set From Tree") ); + lehb->add_child(le_set); + le_clear = memnew( Button("Clear") ); + lehb->add_child(le_clear); + info_left->add_child(lehb); + MarginContainer *mc = memnew( MarginContainer ); + mc->add_child(live_edit_root); + info_left->add_child(mc); + le_set->set_disabled(true); + le_clear->set_disabled(true); + } + VBoxContainer *info_right = memnew(VBoxContainer); info_right->set_h_size_flags(SIZE_EXPAND_FILL); info->add_child(info_right); @@ -868,6 +1378,14 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor){ hide(); log_forced_visible=false; + p_editor->get_undo_redo()->set_method_notify_callback(_method_changeds,this); + p_editor->get_undo_redo()->set_property_notify_callback(_property_changeds,this); + live_debug=false; + last_path_id=false; + error_count=0; + last_error_count=0; + + } ScriptEditorDebugger::~ScriptEditorDebugger() { diff --git a/tools/editor/script_editor_debugger.h b/tools/editor/script_editor_debugger.h index c59cc1cf9d..3c66dde340 100644 --- a/tools/editor/script_editor_debugger.h +++ b/tools/editor/script_editor_debugger.h @@ -45,6 +45,7 @@ class TextureButton; class AcceptDialog; class TreeItem; class HSplitContainer; +class ItemList; class ScriptEditorDebugger : public Control { @@ -56,9 +57,21 @@ class ScriptEditorDebugger : public Control { LineEdit *clicked_ctrl; LineEdit *clicked_ctrl_type; + LineEdit *live_edit_root; Tree *scene_tree; HSplitContainer *info; Button *scene_tree_refresh; + Button *le_set; + Button *le_clear; + + HSplitContainer *error_split; + ItemList *error_list; + ItemList *error_stack; + + int error_count; + int last_error_count; + + TextureButton *tb; @@ -94,11 +107,17 @@ class ScriptEditorDebugger : public Control { Array message; int pending_in_queue; + HashMap<NodePath,int> node_path_cache; + int last_path_id; + Map<String,int> res_path_cache; + EditorNode *editor; bool breaked; + bool live_debug; + void _performance_draw(); void _performance_select(Object *, int, bool); void _stack_dump_frame_selected(); @@ -108,6 +127,23 @@ class ScriptEditorDebugger : public Control { void _scene_tree_request(); void _parse_message(const String& p_msg,const Array& p_data); + + int _get_node_path_cache(const NodePath& p_path); + + int _get_res_path_cache(const String& p_path); + + void _live_edit_set(); + void _live_edit_clear(); + + void _method_changed(Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE); + void _property_changed(Object*p_base,const StringName& p_property,const Variant& p_value); + + static void _method_changeds(void *p_ud,Object*p_base,const StringName& p_name,VARIANT_ARG_DECLARE); + static void _property_changeds(void *p_ud,Object*p_base,const StringName& p_property,const Variant& p_value); + + void _error_selected(int p_idx); + void _error_stack_selected(int p_idx); + protected: void _notification(int p_what); @@ -127,6 +163,21 @@ public: String get_var_value(const String& p_var) const; + void set_live_debugging(bool p_enable); + + void live_debug_create_node(const NodePath& p_parent,const String& p_type,const String& p_name); + void live_debug_instance_node(const NodePath& p_parent,const String& p_path,const String& p_name); + void live_debug_remove_node(const NodePath& p_at); + void live_debug_remove_and_keep_node(const NodePath& p_at,ObjectID p_keep_id); + void live_debug_restore_node(ObjectID p_id,const NodePath& p_at,int p_at_pos); + 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); + + void set_breakpoint(const String& p_path,int p_line,bool p_enabled); + + void update_live_edit_root(); + + virtual Size2 get_minimum_size() const; ScriptEditorDebugger(EditorNode *p_editor=NULL); ~ScriptEditorDebugger(); |