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
|
// 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);
|
PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
|
||||||
obj->set_script_instance(placeholder);
|
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()) {
|
for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) {
|
||||||
Ref<CSharpScript> script = E->get();
|
Ref<CSharpScript> script = E->get();
|
||||||
|
|
||||||
if (!script->get_path().empty()) {
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
script->exports_invalidated = true;
|
script->exports_invalidated = true;
|
||||||
#endif
|
#endif
|
||||||
script->signals_invalidated = true;
|
script->signals_invalidated = true;
|
||||||
|
|
||||||
|
if (!script->get_path().empty()) {
|
||||||
script->reload(p_soft_reload);
|
script->reload(p_soft_reload);
|
||||||
|
|
||||||
if (!script->valid) {
|
if (!script->valid) {
|
||||||
|
@ -1949,6 +1947,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
|
void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
|
||||||
|
// Must make sure event signals are not left dangling
|
||||||
disconnect_event_signals();
|
disconnect_event_signals();
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#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());
|
CRASH_COND(gchandle.is_released());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Must make sure event signals are not left dangling
|
||||||
|
disconnect_event_signals();
|
||||||
|
|
||||||
r_remove_script_instance = false;
|
r_remove_script_instance = false;
|
||||||
|
|
||||||
if (_unreference_owner_unsafe()) {
|
if (_unreference_owner_unsafe()) {
|
||||||
|
@ -2223,6 +2225,9 @@ CSharpInstance::~CSharpInstance() {
|
||||||
|
|
||||||
destructing_script_instance = true;
|
destructing_script_instance = true;
|
||||||
|
|
||||||
|
// Must make sure event signals are not left dangling
|
||||||
|
disconnect_event_signals();
|
||||||
|
|
||||||
if (!gchandle.is_released()) {
|
if (!gchandle.is_released()) {
|
||||||
if (!predelete_notified && !ref_dying) {
|
if (!predelete_notified && !ref_dying) {
|
||||||
// This destructor is not called from the owners destructor.
|
// This destructor is not called from the owners destructor.
|
||||||
|
|
|
@ -288,7 +288,7 @@ public:
|
||||||
void mono_object_disposed(MonoObject *p_obj);
|
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.
|
* '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);
|
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_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable"
|
||||||
#define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info"
|
#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");
|
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(")\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(itype.api_type == ClassDB::API_EDITOR ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS);
|
||||||
output.append("." + ctor_method);
|
output.append("." + ctor_method);
|
||||||
output.append("(this);\n" CLOSE_BLOCK_L2);
|
output.append("(this);\n" INDENT3 "_InitializeGodotScriptInstanceInternals();\n" CLOSE_BLOCK_L2);
|
||||||
} else {
|
} else {
|
||||||
// Hide the constructor
|
// Hide the constructor
|
||||||
output.append(MEMBER_BEGIN "internal ");
|
output.append(MEMBER_BEGIN "internal ");
|
||||||
|
|
|
@ -15,14 +15,13 @@ namespace Godot
|
||||||
public Object() : this(false)
|
public Object() : this(false)
|
||||||
{
|
{
|
||||||
if (ptr == IntPtr.Zero)
|
if (ptr == IntPtr.Zero)
|
||||||
{
|
|
||||||
ptr = godot_icall_Object_Ctor(this);
|
ptr = godot_icall_Object_Ctor(this);
|
||||||
}
|
_InitializeGodotScriptInstanceInternals();
|
||||||
else
|
}
|
||||||
{
|
|
||||||
// This is called inside godot_icall_Object_Ctor, so we must call it as well in this case.
|
internal void _InitializeGodotScriptInstanceInternals()
|
||||||
godot_icall_Object_ConnectEventSignals(ptr);
|
{
|
||||||
}
|
godot_icall_Object_ConnectEventSignals(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Object(bool memoryOwn)
|
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);
|
CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
|
||||||
|
|
||||||
unmanaged->set_script_and_instance(script, csharp_instance);
|
unmanaged->set_script_and_instance(script, csharp_instance);
|
||||||
|
|
||||||
csharp_instance->connect_event_signals();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unhandled_exception(MonoException *p_exc) {
|
void unhandled_exception(MonoException *p_exc) {
|
||||||
|
|
Loading…
Reference in New Issue