Merge branch 'alc_reload_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-alc_reload_fix
This commit is contained in:
@@ -903,11 +903,25 @@ namespace FlaxEngine.Interop
|
|||||||
|
|
||||||
AssemblyLocations.Remove(assembly.FullName);
|
AssemblyLocations.Remove(assembly.FullName);
|
||||||
|
|
||||||
// Clear all caches which might hold references to closing assembly
|
// Unload native library handles associated for this assembly
|
||||||
|
string nativeLibraryName = assemblyOwnedNativeLibraries.GetValueOrDefault(assembly);
|
||||||
|
if (nativeLibraryName != null && loadedNativeLibraries.TryGetValue(nativeLibraryName, out IntPtr nativeLibrary))
|
||||||
|
{
|
||||||
|
NativeLibrary.Free(nativeLibrary);
|
||||||
|
loadedNativeLibraries.Remove(nativeLibraryName);
|
||||||
|
}
|
||||||
|
if (nativeLibraryName != null)
|
||||||
|
nativeLibraryPaths.Remove(nativeLibraryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
internal static void ReloadScriptingAssemblyLoadContext()
|
||||||
|
{
|
||||||
|
#if FLAX_EDITOR
|
||||||
|
// Clear all caches which might hold references to assemblies in collectible ALC
|
||||||
typeCache.Clear();
|
typeCache.Clear();
|
||||||
|
|
||||||
// Release all references in collectible ALC
|
// Release all references in collectible ALC
|
||||||
#if FLAX_EDITOR
|
|
||||||
cachedDelegatesCollectible.Clear();
|
cachedDelegatesCollectible.Clear();
|
||||||
foreach (var pair in typeHandleCacheCollectible)
|
foreach (var pair in typeHandleCacheCollectible)
|
||||||
pair.Value.Free();
|
pair.Value.Free();
|
||||||
@@ -918,23 +932,13 @@ namespace FlaxEngine.Interop
|
|||||||
foreach (var handle in fieldHandleCacheCollectible)
|
foreach (var handle in fieldHandleCacheCollectible)
|
||||||
handle.Free();
|
handle.Free();
|
||||||
fieldHandleCacheCollectible.Clear();
|
fieldHandleCacheCollectible.Clear();
|
||||||
#endif
|
|
||||||
_typeSizeCache.Clear();
|
_typeSizeCache.Clear();
|
||||||
|
|
||||||
foreach (var pair in classAttributesCacheCollectible)
|
foreach (var pair in classAttributesCacheCollectible)
|
||||||
pair.Value.Free();
|
pair.Value.Free();
|
||||||
classAttributesCacheCollectible.Clear();
|
classAttributesCacheCollectible.Clear();
|
||||||
|
|
||||||
// Unload native library handles associated for this assembly
|
|
||||||
string nativeLibraryName = assemblyOwnedNativeLibraries.GetValueOrDefault(assembly);
|
|
||||||
if (nativeLibraryName != null && loadedNativeLibraries.TryGetValue(nativeLibraryName, out IntPtr nativeLibrary))
|
|
||||||
{
|
|
||||||
NativeLibrary.Free(nativeLibrary);
|
|
||||||
loadedNativeLibraries.Remove(nativeLibraryName);
|
|
||||||
}
|
|
||||||
if (nativeLibraryName != null)
|
|
||||||
nativeLibraryPaths.Remove(nativeLibraryName);
|
|
||||||
|
|
||||||
// Unload the ALC
|
// Unload the ALC
|
||||||
bool unloading = true;
|
bool unloading = true;
|
||||||
scriptingAssemblyLoadContext.Unloading += (alc) => { unloading = false; };
|
scriptingAssemblyLoadContext.Unloading += (alc) => { unloading = false; };
|
||||||
@@ -945,6 +949,7 @@ namespace FlaxEngine.Interop
|
|||||||
|
|
||||||
InitScriptingAssemblyLoadContext();
|
InitScriptingAssemblyLoadContext();
|
||||||
DelegateHelpers.InitMethods();
|
DelegateHelpers.InitMethods();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
// Called by Scripting in a middle of hot-reload (after unloading modules but before loading them again).
|
// Called by Scripting in a middle of hot-reload (after unloading modules but before loading them again).
|
||||||
static void OnMidHotReload();
|
static void ReloadScriptingAssemblyLoadContext();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ DECLARE_ENUM_OPERATORS(MTypeAttributes);
|
|||||||
DECLARE_ENUM_OPERATORS(MMethodAttributes);
|
DECLARE_ENUM_OPERATORS(MMethodAttributes);
|
||||||
DECLARE_ENUM_OPERATORS(MFieldAttributes);
|
DECLARE_ENUM_OPERATORS(MFieldAttributes);
|
||||||
|
|
||||||
|
// Multiple AppDomains are superseded by AssemblyLoadContext in .NET
|
||||||
extern MDomain* MRootDomain;
|
extern MDomain* MRootDomain;
|
||||||
extern MDomain* MActiveDomain;
|
extern MDomain* MActiveDomain;
|
||||||
extern Array<MDomain*, FixedAllocation<4>> MDomains;
|
extern Array<MDomain*, FixedAllocation<4>> MDomains;
|
||||||
@@ -301,11 +302,14 @@ void MCore::UnloadEngine()
|
|||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|
||||||
void MCore::OnMidHotReload()
|
void MCore::ReloadScriptingAssemblyLoadContext()
|
||||||
{
|
{
|
||||||
// Clear any cached class attributes (see https://github.com/FlaxEngine/FlaxEngine/issues/1108)
|
// Clear any cached class attributes (see https://github.com/FlaxEngine/FlaxEngine/issues/1108)
|
||||||
for (auto e : CachedClassHandles)
|
for (auto e : CachedClassHandles)
|
||||||
e.Value->_attributes.Clear();
|
e.Value->_attributes.Clear();
|
||||||
|
|
||||||
|
static void* ReloadScriptingAssemblyLoadContextPtr = GetStaticMethodPointer(TEXT("ReloadScriptingAssemblyLoadContext"));
|
||||||
|
CallStaticMethod<void>(ReloadScriptingAssemblyLoadContextPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -723,16 +727,12 @@ bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePa
|
|||||||
|
|
||||||
bool MAssembly::UnloadImage(bool isReloading)
|
bool MAssembly::UnloadImage(bool isReloading)
|
||||||
{
|
{
|
||||||
if (_handle)
|
if (_handle && isReloading)
|
||||||
{
|
|
||||||
// TODO: closing assembly on reload only is copy-paste from mono, do we need do this on .NET too?
|
|
||||||
if (isReloading)
|
|
||||||
{
|
{
|
||||||
LOG(Info, "Unloading managed assembly \'{0}\' (is reloading)", String(_name));
|
LOG(Info, "Unloading managed assembly \'{0}\' (is reloading)", String(_name));
|
||||||
|
|
||||||
static void* CloseAssemblyPtr = GetStaticMethodPointer(TEXT("CloseAssembly"));
|
static void* CloseAssemblyPtr = GetStaticMethodPointer(TEXT("CloseAssembly"));
|
||||||
CallStaticMethod<void, const void*>(CloseAssemblyPtr, _handle);
|
CallStaticMethod<void, const void*>(CloseAssemblyPtr, _handle);
|
||||||
}
|
|
||||||
|
|
||||||
CachedAssemblyHandles.Remove(_handle);
|
CachedAssemblyHandles.Remove(_handle);
|
||||||
_handle = nullptr;
|
_handle = nullptr;
|
||||||
|
|||||||
@@ -716,7 +716,7 @@ void MCore::UnloadEngine()
|
|||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|
||||||
void MCore::OnMidHotReload()
|
void MCore::ReloadScriptingAssemblyLoadContext()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ void MCore::UnloadEngine()
|
|||||||
|
|
||||||
#if USE_EDITOR
|
#if USE_EDITOR
|
||||||
|
|
||||||
void MCore::OnMidHotReload()
|
void MCore::ReloadScriptingAssemblyLoadContext()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -706,7 +706,9 @@ void Scripting::Reload(bool canTriggerSceneReload)
|
|||||||
modules.Clear();
|
modules.Clear();
|
||||||
_nonNativeModules.ClearDelete();
|
_nonNativeModules.ClearDelete();
|
||||||
_hasGameModulesLoaded = false;
|
_hasGameModulesLoaded = false;
|
||||||
MCore::OnMidHotReload();
|
|
||||||
|
// Release and create a new assembly load context for user assemblies
|
||||||
|
MCore::ReloadScriptingAssemblyLoadContext();
|
||||||
|
|
||||||
// Give GC a try to cleanup old user objects and the other mess
|
// Give GC a try to cleanup old user objects and the other mess
|
||||||
MCore::GC::Collect();
|
MCore::GC::Collect();
|
||||||
|
|||||||
Reference in New Issue
Block a user