C#: Fix custom event signals crash on hot-reload
Cleanup and re-initialization of event signals before and after hot-reload should be working correctly now.
This commit is contained in:
parent
d5073c6b4c
commit
34960cb936
|
@ -940,8 +940,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|||
|
||||
// Use a placeholder for now to avoid losing the state when saving a scene
|
||||
|
||||
obj->set_script(scr);
|
||||
|
||||
PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
|
||||
obj->set_script_instance(placeholder);
|
||||
|
||||
|
@ -968,12 +966,12 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|||
for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) {
|
||||
Ref<CSharpScript> script = E->get();
|
||||
|
||||
if (!script->get_path().empty()) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
script->exports_invalidated = true;
|
||||
script->exports_invalidated = true;
|
||||
#endif
|
||||
script->signals_invalidated = true;
|
||||
script->signals_invalidated = true;
|
||||
|
||||
if (!script->get_path().empty()) {
|
||||
script->reload(p_soft_reload);
|
||||
|
||||
if (!script->valid) {
|
||||
|
@ -1949,6 +1947,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
|
|||
}
|
||||
|
||||
void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
|
||||
// Must make sure event signals are not left dangling
|
||||
disconnect_event_signals();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
@ -1964,6 +1963,9 @@ void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_f
|
|||
CRASH_COND(gchandle.is_released());
|
||||
#endif
|
||||
|
||||
// Must make sure event signals are not left dangling
|
||||
disconnect_event_signals();
|
||||
|
||||
r_remove_script_instance = false;
|
||||
|
||||
if (_unreference_owner_unsafe()) {
|
||||
|
@ -2223,6 +2225,9 @@ CSharpInstance::~CSharpInstance() {
|
|||
|
||||
destructing_script_instance = true;
|
||||
|
||||
// Must make sure event signals are not left dangling
|
||||
disconnect_event_signals();
|
||||
|
||||
if (!gchandle.is_released()) {
|
||||
if (!predelete_notified && !ref_dying) {
|
||||
// This destructor is not called from the owners destructor.
|
||||
|
|
|
@ -288,7 +288,7 @@ public:
|
|||
void mono_object_disposed(MonoObject *p_obj);
|
||||
|
||||
/*
|
||||
* If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, ifevent_signal
|
||||
* If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, if
|
||||
* 'r_remove_script_instance' is set to true, the caller must destroy the script instance by removing it from its owner.
|
||||
*/
|
||||
void mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_delete_owner, bool &r_remove_script_instance);
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
#define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable"
|
||||
#define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info"
|
||||
|
||||
#define BINDINGS_GENERATOR_VERSION UINT32_C(11)
|
||||
#define BINDINGS_GENERATOR_VERSION UINT32_C(12)
|
||||
|
||||
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
|
||||
|
||||
|
@ -1368,7 +1368,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
|
|||
output.append(")\n" OPEN_BLOCK_L2 "if (" BINDINGS_PTR_FIELD " == IntPtr.Zero)\n" INDENT4 BINDINGS_PTR_FIELD " = ");
|
||||
output.append(itype.api_type == ClassDB::API_EDITOR ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS);
|
||||
output.append("." + ctor_method);
|
||||
output.append("(this);\n" CLOSE_BLOCK_L2);
|
||||
output.append("(this);\n" INDENT3 "_InitializeGodotScriptInstanceInternals();\n" CLOSE_BLOCK_L2);
|
||||
} else {
|
||||
// Hide the constructor
|
||||
output.append(MEMBER_BEGIN "internal ");
|
||||
|
|
|
@ -15,14 +15,13 @@ namespace Godot
|
|||
public Object() : this(false)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
ptr = godot_icall_Object_Ctor(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is called inside godot_icall_Object_Ctor, so we must call it as well in this case.
|
||||
godot_icall_Object_ConnectEventSignals(ptr);
|
||||
}
|
||||
_InitializeGodotScriptInstanceInternals();
|
||||
}
|
||||
|
||||
internal void _InitializeGodotScriptInstanceInternals()
|
||||
{
|
||||
godot_icall_Object_ConnectEventSignals(ptr);
|
||||
}
|
||||
|
||||
internal Object(bool memoryOwn)
|
||||
|
|
|
@ -109,8 +109,6 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
|
|||
CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
|
||||
|
||||
unmanaged->set_script_and_instance(script, csharp_instance);
|
||||
|
||||
csharp_instance->connect_event_signals();
|
||||
}
|
||||
|
||||
void unhandled_exception(MonoException *p_exc) {
|
||||
|
|
Loading…
Reference in New Issue