mirror of
https://github.com/godotengine/godot.git
synced 2025-10-20 00:13:30 +00:00
C#: Fix editor integration breaking and causing error spam when reloading assemblies fails
- Do not reload scripts from non-collectible assemblies - Do not load GodotTools as collectible - Do not attempt to reload the same project assembly forever
This commit is contained in:
parent
58fae90ff3
commit
e0f644a48d
12 changed files with 142 additions and 43 deletions
|
@ -120,6 +120,7 @@ void CSharpLanguage::init() {
|
|||
GLOBAL_DEF("dotnet/project/assembly_name", "");
|
||||
#ifdef TOOLS_ENABLED
|
||||
GLOBAL_DEF("dotnet/project/solution_directory", "");
|
||||
GLOBAL_DEF(PropertyInfo(Variant::INT, "dotnet/project/assembly_reload_attempts", PROPERTY_HINT_RANGE, "1,16,1,or_greater"), 3);
|
||||
#endif
|
||||
|
||||
gdmono = memnew(GDMono);
|
||||
|
@ -770,10 +771,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// Currently, this reloads all scripts, including those whose class is not part of the
|
||||
// assembly load context being unloaded. As such, we unnecessarily reload GodotTools.
|
||||
|
||||
print_verbose(".NET: Reloading assemblies...");
|
||||
|
||||
// There is no soft reloading with Mono. It's always hard reloading.
|
||||
|
@ -784,8 +781,19 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|||
MutexLock lock(script_instances_mutex);
|
||||
|
||||
for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) {
|
||||
// Cast to CSharpScript to avoid being erased by accident
|
||||
scripts.push_back(Ref<CSharpScript>(elem->self()));
|
||||
bool is_reloadable = false;
|
||||
for (Object *obj : elem->self()->instances) {
|
||||
ERR_CONTINUE(!obj->get_script_instance());
|
||||
CSharpInstance *csi = static_cast<CSharpInstance *>(obj->get_script_instance());
|
||||
if (GDMonoCache::managed_callbacks.GCHandleBridge_GCHandleIsTargetCollectible(csi->get_gchandle_intptr())) {
|
||||
is_reloadable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_reloadable) {
|
||||
// Cast to CSharpScript to avoid being erased by accident.
|
||||
scripts.push_back(Ref<CSharpScript>(elem->self()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -800,6 +808,10 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|||
|
||||
ERR_CONTINUE(managed_callable->delegate_handle.value == nullptr);
|
||||
|
||||
if (!GDMonoCache::managed_callbacks.GCHandleBridge_GCHandleIsTargetCollectible(managed_callable->delegate_handle)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Array serialized_data;
|
||||
|
||||
bool success = GDMonoCache::managed_callbacks.DelegateUtils_TrySerializeDelegateWithGCHandle(
|
||||
|
@ -907,6 +919,15 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
|
|||
scr->_clear();
|
||||
}
|
||||
|
||||
// Release the delegates that were serialized earlier.
|
||||
{
|
||||
MutexLock lock(ManagedCallable::instances_mutex);
|
||||
|
||||
for (KeyValue<ManagedCallable *, Array> &kv : ManagedCallable::instances_pending_reload) {
|
||||
kv.key->release_delegate_handle();
|
||||
}
|
||||
}
|
||||
|
||||
// Do domain reload
|
||||
if (gdmono->reload_project_assemblies() != OK) {
|
||||
// Failed to reload the scripts domain
|
||||
|
@ -1158,19 +1179,6 @@ bool CSharpLanguage::debug_break(const String &p_error, bool p_allow_continue) {
|
|||
}
|
||||
}
|
||||
|
||||
void CSharpLanguage::_on_scripts_domain_about_to_unload() {
|
||||
#ifdef GD_MONO_HOT_RELOAD
|
||||
{
|
||||
MutexLock lock(ManagedCallable::instances_mutex);
|
||||
|
||||
for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) {
|
||||
ManagedCallable *managed_callable = elem->self();
|
||||
managed_callable->release_delegate_handle();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void CSharpLanguage::_editor_init_callback() {
|
||||
// Load GodotTools and initialize GodotSharpEditor
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue