Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change order of operation for C# types reloading #90837

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading