diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index b5c91a8585a3..06a5c65d3c32 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -867,6 +867,11 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { script->reload(p_soft_reload); script->update_exports(); + + if (!script->valid) { + script->pending_reload_instances.clear(); + continue; + } } else { const StringName &class_namespace = script->tied_class_namespace_for_reload; const StringName &class_name = script->tied_class_name_for_reload; @@ -897,12 +902,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { GDMonoClass *native = GDMonoUtils::get_class_native_base(script_class); - Ref new_script = CSharpScript::create_for_managed_type(script_class, native); - CRASH_COND(new_script.is_null()); - - new_script->pending_reload_instances = script->pending_reload_instances; - new_script->pending_reload_state = script->pending_reload_state; - script = new_script; + CSharpScript::initialize_for_managed_type(script, script_class, native); } String native_name = NATIVE_GDMONOCLASS_NAME(script->native); @@ -953,7 +953,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CRASH_COND(si != NULL); #endif // Re-create script instance - obj->set_script(script.get_ref_ptr()); // will create the script instance as well } } @@ -2673,35 +2672,46 @@ void CSharpScript::_bind_methods() { Ref CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) { - // This method should not fail + // This method should not fail, only assertions allowed CRASH_COND(p_class == NULL); // TODO OPTIMIZE: Cache the 'CSharpScript' associated with this 'p_class' instead of allocating a new one every time Ref script = memnew(CSharpScript); - script->name = p_class->get_name(); - script->script_class = p_class; - script->native = p_native; + initialize_for_managed_type(script, p_class, p_native); - CRASH_COND(script->native == NULL); + return script; +} - GDMonoClass *base = script->script_class->get_parent_class(); +void CSharpScript::initialize_for_managed_type(Ref p_script, GDMonoClass *p_class, GDMonoClass *p_native) { - if (base != script->native) - script->base = base; + // This method should not fail, only assertions allowed - script->valid = true; - script->tool = script->script_class->has_attribute(CACHED_CLASS(ToolAttribute)); + CRASH_COND(p_class == NULL); - if (!script->tool) { - GDMonoClass *nesting_class = script->script_class->get_nesting_class(); - script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); + p_script->name = p_class->get_name(); + p_script->script_class = p_class; + p_script->native = p_native; + + CRASH_COND(p_script->native == NULL); + + GDMonoClass *base = p_script->script_class->get_parent_class(); + + if (base != p_script->native) + p_script->base = base; + + p_script->valid = true; + p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute)); + + if (!p_script->tool) { + GDMonoClass *nesting_class = p_script->script_class->get_nesting_class(); + p_script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); } #if TOOLS_ENABLED - if (!script->tool) { - script->tool = script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); + if (!p_script->tool) { + p_script->tool = p_script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); } #endif @@ -2710,10 +2720,10 @@ Ref CSharpScript::create_for_managed_type(GDMonoClass *p_class, GD // Native base methods must be fetched before the current class. // Not needed if the script class itself is a native class. - if (script->script_class != script->native) { - GDMonoClass *native_top = script->native; + if (p_script->script_class != p_script->native) { + GDMonoClass *native_top = p_script->native; while (native_top) { - native_top->fetch_methods_with_godot_api_checks(script->native); + native_top->fetch_methods_with_godot_api_checks(p_script->native); if (native_top == CACHED_CLASS(GodotObject)) break; @@ -2723,19 +2733,17 @@ Ref CSharpScript::create_for_managed_type(GDMonoClass *p_class, GD } #endif - script->script_class->fetch_methods_with_godot_api_checks(script->native); + p_script->script_class->fetch_methods_with_godot_api_checks(p_script->native); // Need to fetch method from base classes as well - GDMonoClass *top = script->script_class; - while (top && top != script->native) { - top->fetch_methods_with_godot_api_checks(script->native); + GDMonoClass *top = p_script->script_class; + while (top && top != p_script->native) { + top->fetch_methods_with_godot_api_checks(p_script->native); top = top->get_parent_class(); } - script->load_script_signals(script->script_class, script->native); - script->_update_member_info_no_exports(); - - return script; + p_script->load_script_signals(p_script->script_class, p_script->native); + p_script->_update_member_info_no_exports(); } bool CSharpScript::can_instance() const { diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index d31a1c35d2d9..76c7976285d2 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -144,6 +144,7 @@ class CSharpScript : public Script { // Do not use unless you know what you are doing friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *); static Ref create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native); + static void initialize_for_managed_type(Ref p_script, GDMonoClass *p_class, GDMonoClass *p_native); protected: static void _bind_methods();