From 9e745b920fec25f1088ae0377a8d87a87136a5f7 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 1 Jun 2016 20:22:02 -0300 Subject: Ability to reload scripts on running game --- modules/gdscript/gd_compiler.cpp | 76 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 7 deletions(-) (limited to 'modules/gdscript/gd_compiler.cpp') diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index 5a6299bcf8..7a2e9c9638 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1414,8 +1414,13 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode * -Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDParser::ClassNode *p_class) { +Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDParser::ClassNode *p_class, bool p_keep_state) { + Map > old_subclasses; + + if (p_keep_state) { + old_subclasses=p_script->subclasses; + } p_script->native=Ref(); p_script->base=Ref(); @@ -1429,6 +1434,7 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars p_script->member_indices.clear(); p_script->member_info.clear(); p_script->initializer=NULL; + p_script->subclasses.clear(); p_script->_owner=p_owner; p_script->tool=p_class->tool; @@ -1662,9 +1668,15 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars for(int i=0;isubclasses.size();i++) { StringName name = p_class->subclasses[i]->name; - Ref subclass = memnew( GDScript ); + Ref subclass; + + if (old_subclasses.has(name)) { + subclass=old_subclasses[name]; + } else { + subclass.instance(); + } - Error err = _parse_class(subclass.ptr(),p_script,p_class->subclasses[i]); + Error err = _parse_class(subclass.ptr(),p_script,p_class->subclasses[i],p_keep_state); if (err) return err; @@ -1755,13 +1767,65 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars } } + + //validate instances if keeping state + + if (p_keep_state) { + + print_line("RELOAD KEEP "+p_script->path); + for (Set::Element *E=p_script->instances.front();E;) { + + Set::Element *N = E->next(); + + ScriptInstance *si = E->get()->get_script_instance(); + if (si->is_placeholder()) { + PlaceHolderScriptInstance *psi = static_cast(si); + + if (p_script->is_tool()) { + //re-create as an instance + p_script->placeholders.erase(psi); //remove placeholder + + GDInstance* instance = memnew( GDInstance ); + instance->base_ref=E->get()->cast_to(); + instance->members.resize(p_script->member_indices.size()); + instance->script=Ref(p_script); + instance->owner=E->get(); + + //needed for hot reloading + for(Map::Element *E=p_script->member_indices.front();E;E=E->next()) { + instance->member_indices_cache[E->key()]=E->get().index; + } + instance->owner->set_script_instance(instance); + + + /* STEP 2, INITIALIZE AND CONSRTUCT */ + + Variant::CallError ce; + p_script->initializer->call(instance,NULL,0,ce); + + if (ce.error!=Variant::CallError::CALL_OK) { + //well, tough luck, not goinna do anything here + } + } + } else { + print_line("RELOAD MEMBERS"); + GDInstance *gi = static_cast(si); + gi->reload_members(); + } + + E=N; + + } + + + } #endif p_script->valid=true; return OK; } -Error GDCompiler::compile(const GDParser *p_parser,GDScript *p_script) { +Error GDCompiler::compile(const GDParser *p_parser,GDScript *p_script,bool p_keep_state) { err_line=-1; err_column=-1; @@ -1772,9 +1836,7 @@ Error GDCompiler::compile(const GDParser *p_parser,GDScript *p_script) { source=p_script->get_path(); - - - Error err = _parse_class(p_script,NULL,static_cast(root)); + Error err = _parse_class(p_script,NULL,static_cast(root),p_keep_state); if (err) return err; -- cgit v1.2.3 From cc0a7b24e760512c4a17e54371c3308cd082c266 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 1 Jun 2016 20:44:34 -0300 Subject: missed ifdef that broke android build --- modules/gdscript/gd_compiler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'modules/gdscript/gd_compiler.cpp') diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index 7a2e9c9638..d51f1a4ddc 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1779,6 +1779,7 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa ScriptInstance *si = E->get()->get_script_instance(); if (si->is_placeholder()) { +#ifdef TOOLS_ENABLED PlaceHolderScriptInstance *psi = static_cast(si); if (p_script->is_tool()) { @@ -1807,8 +1808,9 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa //well, tough luck, not goinna do anything here } } +#endif } else { - print_line("RELOAD MEMBERS"); + GDInstance *gi = static_cast(si); gi->reload_members(); } -- cgit v1.2.3