diff options
Diffstat (limited to 'modules/gdscript/gd_compiler.cpp')
-rw-r--r-- | modules/gdscript/gd_compiler.cpp | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index 5a6299bcf8..d51f1a4ddc 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<StringName,Ref<GDScript> > old_subclasses; + + if (p_keep_state) { + old_subclasses=p_script->subclasses; + } p_script->native=Ref<GDNativeClass>(); p_script->base=Ref<GDScript>(); @@ -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;i<p_class->subclasses.size();i++) { StringName name = p_class->subclasses[i]->name; - Ref<GDScript> subclass = memnew( GDScript ); + Ref<GDScript> subclass; - Error err = _parse_class(subclass.ptr(),p_script,p_class->subclasses[i]); + if (old_subclasses.has(name)) { + subclass=old_subclasses[name]; + } else { + subclass.instance(); + } + + Error err = _parse_class(subclass.ptr(),p_script,p_class->subclasses[i],p_keep_state); if (err) return err; @@ -1755,13 +1767,67 @@ 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<Object*>::Element *E=p_script->instances.front();E;) { + + Set<Object*>::Element *N = E->next(); + + ScriptInstance *si = E->get()->get_script_instance(); + if (si->is_placeholder()) { +#ifdef TOOLS_ENABLED + PlaceHolderScriptInstance *psi = static_cast<PlaceHolderScriptInstance*>(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<Reference>(); + instance->members.resize(p_script->member_indices.size()); + instance->script=Ref<GDScript>(p_script); + instance->owner=E->get(); + + //needed for hot reloading + for(Map<StringName,GDScript::MemberInfo>::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 + } + } +#endif + } else { + + GDInstance *gi = static_cast<GDInstance*>(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 +1838,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<const GDParser::ClassNode*>(root)); + Error err = _parse_class(p_script,NULL,static_cast<const GDParser::ClassNode*>(root),p_keep_state); if (err) return err; |