diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.h b/Source/Engine/Scripting/ManagedCLR/MCore.h index 88124a223..38b58403d 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.h +++ b/Source/Engine/Scripting/ManagedCLR/MCore.h @@ -45,6 +45,11 @@ public: /// static void UnloadEngine(); +#if USE_EDITOR + // Called by Scripting in a middle of hot-reload (after unloading modules but before loading them again). + static void OnMidHotReload(); +#endif + public: /// /// Utilities for C# object management. diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index 76f6dd89f..27515f956 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -299,6 +299,17 @@ void MCore::UnloadEngine() ShutdownHostfxr(); } +#if USE_EDITOR + +void MCore::OnMidHotReload() +{ + // Clear any cached class attributes (see https://github.com/FlaxEngine/FlaxEngine/issues/1108) + for (auto e : CachedClassHandles) + e.Value->_attributes.Clear(); +} + +#endif + MObject* MCore::Object::Box(void* value, const MClass* klass) { static void* BoxValuePtr = GetStaticMethodPointer(TEXT("BoxValue")); diff --git a/Source/Engine/Scripting/Runtime/Mono.cpp b/Source/Engine/Scripting/Runtime/Mono.cpp index 54892b11b..ca4ef367b 100644 --- a/Source/Engine/Scripting/Runtime/Mono.cpp +++ b/Source/Engine/Scripting/Runtime/Mono.cpp @@ -714,6 +714,14 @@ void MCore::UnloadEngine() #endif } +#if USE_EDITOR + +void MCore::OnMidHotReload() +{ +} + +#endif + MObject* MCore::Object::Box(void* value, const MClass* klass) { return mono_value_box(mono_domain_get(), klass->GetNative(), value); diff --git a/Source/Engine/Scripting/Runtime/None.cpp b/Source/Engine/Scripting/Runtime/None.cpp index 0c88c519d..c8f8926e5 100644 --- a/Source/Engine/Scripting/Runtime/None.cpp +++ b/Source/Engine/Scripting/Runtime/None.cpp @@ -59,6 +59,14 @@ void MCore::UnloadEngine() MRootDomain = nullptr; } +#if USE_EDITOR + +void MCore::OnMidHotReload() +{ +} + +#endif + MObject* MCore::Object::Box(void* value, const MClass* klass) { return nullptr; diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index bec0e6c20..d82a05fa9 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -665,6 +665,7 @@ void Scripting::Reload(bool canTriggerSceneReload) modules.Clear(); _nonNativeModules.ClearDelete(); _hasGameModulesLoaded = false; + MCore::OnMidHotReload(); // Give GC a try to cleanup old user objects and the other mess MCore::GC::Collect();