diff options
Diffstat (limited to 'modules/gdscript/gd_script.cpp')
-rw-r--r-- | modules/gdscript/gd_script.cpp | 107 |
1 files changed, 107 insertions, 0 deletions
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)); |