Skip to content

Commit

Permalink
Change order of operation for C# types reloading
Browse files Browse the repository at this point in the history
We now deserialize callables before reloading property states, in case a property is doing anything with the callable in its getter and/or setter.
  • Loading branch information
paulloz committed Apr 18, 2024
1 parent 3b18061 commit 1627287
Showing 1 changed file with 26 additions and 25 deletions.
51 changes: 26 additions & 25 deletions modules/mono/csharp_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,31 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
to_reload_state.push_back(scr);
}

// Deserialize managed callables.
// This is done before reloading script's internal state, so potential callables invoked in properties work.
{
MutexLock lock(ManagedCallable::instances_mutex);

for (const KeyValue<ManagedCallable *, Array> &elem : ManagedCallable::instances_pending_reload) {
ManagedCallable *managed_callable = elem.key;
const Array &serialized_data = elem.value;

GCHandleIntPtr delegate = { nullptr };

bool success = GDMonoCache::managed_callbacks.DelegateUtils_TryDeserializeDelegateWithGCHandle(
&serialized_data, &delegate);

if (success) {
ERR_CONTINUE(delegate.value == nullptr);
managed_callable->delegate_handle = delegate;
} else if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print("Failed to deserialize delegate\n");
}
}

ManagedCallable::instances_pending_reload.clear();
}

for (Ref<CSharpScript> &scr : to_reload_state) {
for (const ObjectID &obj_id : scr->pending_reload_instances) {
Object *obj = ObjectDB::get_instance(obj_id);
Expand All @@ -963,7 +988,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
properties[G.first] = G.second;
}

// Restore serialized state and call OnAfterDeserialization
// Restore serialized state and call OnAfterDeserialize.
GDMonoCache::managed_callbacks.CSharpInstanceBridge_DeserializeState(
csi->get_gchandle_intptr(), &properties, &state_backup.event_signals);
}
Expand All @@ -973,30 +998,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
scr->pending_reload_state.clear();
}

// Deserialize managed callables
{
MutexLock lock(ManagedCallable::instances_mutex);

for (const KeyValue<ManagedCallable *, Array> &elem : ManagedCallable::instances_pending_reload) {
ManagedCallable *managed_callable = elem.key;
const Array &serialized_data = elem.value;

GCHandleIntPtr delegate = { nullptr };

bool success = GDMonoCache::managed_callbacks.DelegateUtils_TryDeserializeDelegateWithGCHandle(
&serialized_data, &delegate);

if (success) {
ERR_CONTINUE(delegate.value == nullptr);
managed_callable->delegate_handle = delegate;
} else if (OS::get_singleton()->is_stdout_verbose()) {
OS::get_singleton()->print("Failed to deserialize delegate\n");
}
}

ManagedCallable::instances_pending_reload.clear();
}

#ifdef TOOLS_ENABLED
// FIXME: Hack to refresh editor in order to display new properties and signals. See if there is a better alternative.
if (Engine::get_singleton()->is_editor_hint()) {
Expand Down

0 comments on commit 1627287

Please sign in to comment.