diff options
-rw-r--r-- | core/script_language.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gd_script.cpp | 107 | ||||
-rw-r--r-- | modules/gdscript/gd_script.h | 1 | ||||
-rw-r--r-- | tools/editor/plugins/script_editor_plugin.cpp | 13 | ||||
-rw-r--r-- | tools/editor/plugins/script_editor_plugin.h | 2 |
5 files changed, 124 insertions, 0 deletions
diff --git a/core/script_language.h b/core/script_language.h index d8b4c61b6c..cbf6d8e116 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -192,6 +192,7 @@ public: virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); } virtual void reload_all_scripts()=0; + virtual void reload_tool_script(const Ref<Script>& p_script,bool p_soft_reload)=0; /* LOADER FUNCTIONS */ virtual void get_recognized_extensions(List<String> *p_extensions) const=0; diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index dcd0641f76..359a9fe2d5 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -1558,6 +1558,113 @@ void GDScriptLanguage::reload_all_scripts() { #endif } + +void GDScriptLanguage::reload_tool_script(const Ref<Script>& p_script,bool p_soft_reload) { + + +#ifdef DEBUG_ENABLED + + if (lock) { + lock->lock(); + } + + List<Ref<GDScript> > scripts; + + SelfList<GDScript> *elem=script_list.first(); + while(elem) { + if (elem->self()->get_path().is_resource_file()) { + + scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident + } + elem=elem->next(); + } + + if (lock) { + lock->unlock(); + } + + //when someone asks you why dynamically typed languages are easier to write.... + + Map< Ref<GDScript>, Map<ObjectID,List<Pair<StringName,Variant> > > > to_reload; + + //as scripts are going to be reloaded, must proceed without locking here + + scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order + + for(List<Ref<GDScript> >::Element *E=scripts.front();E;E=E->next()) { + + bool reload = E->get()==p_script || to_reload.has(E->get()->get_base()); + + if (!reload) + continue; + + to_reload.insert(E->get(),Map<ObjectID,List<Pair<StringName,Variant> > >()); + + if (!p_soft_reload) { + + //save state and remove script from instances + Map<ObjectID,List<Pair<StringName,Variant> > >& map = to_reload[E->get()]; + + while(E->get()->instances.front()) { + Object *obj = E->get()->instances.front()->get(); + //save instance info + List<Pair<StringName,Variant> > state; + if (obj->get_script_instance()) { + + obj->get_script_instance()->get_property_state(state); + map[obj->get_instance_ID()]=state; + obj->set_script(RefPtr()); + } + } + + //same thing for placeholders +#ifdef TOOLS_ENABLED + + while(E->get()->placeholders.size()) { + + Object *obj = E->get()->placeholders.front()->get()->get_owner(); + //save instance info + List<Pair<StringName,Variant> > state; + if (obj->get_script_instance()) { + + obj->get_script_instance()->get_property_state(state); + map[obj->get_instance_ID()]=state; + obj->set_script(RefPtr()); + } + } +#endif + + } + } + + for(Map< Ref<GDScript>, Map<ObjectID,List<Pair<StringName,Variant> > > >::Element *E=to_reload.front();E;E=E->next()) { + + Ref<GDScript> scr = E->key(); + scr->reload(true); + + //restore state if saved + for (Map<ObjectID,List<Pair<StringName,Variant> > >::Element *F=E->get().front();F;F=F->next()) { + + Object *obj = ObjectDB::get_instance(F->key()); + if (!obj) + continue; + + obj->set_script(scr.get_ref_ptr()); + if (!obj->get_script_instance()) + continue; + + for (List<Pair<StringName,Variant> >::Element *G=F->get().front();G;G=G->next()) { + obj->get_script_instance()->set(G->get().first,G->get().second); + } + } + + //if instance states were saved, set them! + } + + +#endif +} + void GDScriptLanguage::frame() { // print_line("calls: "+itos(calls)); diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index f052d13685..166e29ad70 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -389,6 +389,7 @@ public: virtual String debug_parse_stack_level_expression(int p_level,const String& p_expression,int p_max_subitems=-1,int p_max_depth=-1); virtual void reload_all_scripts(); + virtual void reload_tool_script(const Ref<Script>& p_script,bool p_soft_reload); virtual void frame(); diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 1833e3844a..d2d1f9e625 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -1412,6 +1412,16 @@ void ScriptEditor::_menu_option(int p_option) { } break; + case FILE_TOOL_RELOAD: + case FILE_TOOL_RELOAD_SOFT: { + + TextEdit *te = current->get_text_edit(); + Ref<Script> scr = current->get_edited_script(); + if (scr.is_null()) + return; + scr->set_source_code(te->get_text()); + scr->get_language()->reload_tool_script(scr,p_option==FILE_TOOL_RELOAD_SOFT); + } break; case EDIT_TRIM_TRAILING_WHITESAPCE: { _trim_trailing_whitespace(current->get_text_edit()); } break; @@ -2602,6 +2612,9 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { edit_menu->get_popup()->add_item(TTR("Trim Trailing Whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE, KEY_MASK_CTRL|KEY_MASK_ALT|KEY_T); edit_menu->get_popup()->add_item(TTR("Auto Indent"),EDIT_AUTO_INDENT,KEY_MASK_CMD|KEY_I); edit_menu->get_popup()->connect("item_pressed", this,"_menu_option"); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_item(TTR("Reload Tool Script"),FILE_TOOL_RELOAD,KEY_MASK_CMD|KEY_R); + edit_menu->get_popup()->add_item(TTR("Reload Tool Script (Soft)"),FILE_TOOL_RELOAD_SOFT,KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_R); search_menu = memnew( MenuButton ); diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index 4eb3519059..5a9dce759e 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -142,6 +142,8 @@ class ScriptEditor : public VBoxContainer { EDIT_INDENT_RIGHT, EDIT_INDENT_LEFT, EDIT_CLONE_DOWN, + FILE_TOOL_RELOAD, + FILE_TOOL_RELOAD_SOFT, SEARCH_FIND, SEARCH_FIND_NEXT, SEARCH_FIND_PREV, |