| 633 | } |
| 634 | |
| 635 | void CSharpLanguage::reload_assemblies(bool p_soft_reload) { |
| 636 | ERR_FAIL_NULL(gdmono); |
| 637 | if (!gdmono->is_runtime_initialized()) { |
| 638 | return; |
| 639 | } |
| 640 | |
| 641 | if (!Engine::get_singleton()->is_editor_hint()) { |
| 642 | // We disable collectible assemblies in the game player, because the limitations cause |
| 643 | // issues with mocking libraries. As such, we can only reload assemblies in the editor. |
| 644 | return; |
| 645 | } |
| 646 | |
| 647 | print_verbose(".NET: Reloading assemblies..."); |
| 648 | |
| 649 | // There is no soft reloading with Mono. It's always hard reloading. |
| 650 | |
| 651 | List<Ref<CSharpScript>> scripts; |
| 652 | |
| 653 | { |
| 654 | MutexLock lock(script_instances_mutex); |
| 655 | |
| 656 | for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) { |
| 657 | // Do not reload scripts with only non-collectible instances to avoid disrupting event subscriptions and such. |
| 658 | bool is_reloadable = elem->self()->instances.is_empty(); |
| 659 | for (Object *obj : elem->self()->instances) { |
| 660 | ERR_CONTINUE(!obj->get_script_instance()); |
| 661 | CSharpInstance *csi = static_cast<CSharpInstance *>(obj->get_script_instance()); |
| 662 | if (GDMonoCache::managed_callbacks.GCHandleBridge_GCHandleIsTargetCollectible(csi->get_gchandle_intptr())) { |
| 663 | is_reloadable = true; |
| 664 | break; |
| 665 | } |
| 666 | } |
| 667 | if (is_reloadable) { |
| 668 | // Cast to CSharpScript to avoid being erased by accident. |
| 669 | scripts.push_back(Ref<CSharpScript>(elem->self())); |
| 670 | } |
| 671 | } |
| 672 | } |
| 673 | |
| 674 | scripts.sort_custom<CSharpScriptDepSort>(); // Update in inheritance dependency order |
| 675 | |
| 676 | // Serialize managed callables |
| 677 | { |
| 678 | MutexLock lock(ManagedCallable::instances_mutex); |
| 679 | |
| 680 | for (SelfList<ManagedCallable> *elem = ManagedCallable::instances.first(); elem; elem = elem->next()) { |
| 681 | ManagedCallable *managed_callable = elem->self(); |
| 682 | |
| 683 | ERR_CONTINUE(managed_callable->delegate_handle.value == nullptr); |
| 684 | |
| 685 | if (!GDMonoCache::managed_callbacks.GCHandleBridge_GCHandleIsTargetCollectible(managed_callable->delegate_handle)) { |
| 686 | continue; |
| 687 | } |
| 688 | |
| 689 | Array serialized_data; |
| 690 | |
| 691 | bool success = GDMonoCache::managed_callbacks.DelegateUtils_TrySerializeDelegateWithGCHandle( |
| 692 | managed_callable->delegate_handle, &serialized_data); |
nothing calls this directly
no test coverage detected