internal static void OnUnload() { // Call unload on all managed objects until there are no objects left to process // Find which types implement OnAssemblyUnload or OnAssemblyReload Dictionary <Type, bool> typesRequiringUnloadOrReload = new Dictionary <Type, bool>(); List <IntPtr> allUnloadOrReloadReferences = new List <IntPtr>(); #if ARRAY_GC Dictionary <IntPtr, UObjectRef> references = new Dictionary <IntPtr, UObjectRef>(); foreach (UObjectRef objRef in References) { if (objRef != null) { references.Add(objRef.Native, objRef); } } #else Dictionary <IntPtr, UObjectRef> references = new Dictionary <IntPtr, UObjectRef>(References); #endif Dictionary <IntPtr, UObjectRef> newReferences = new Dictionary <IntPtr, UObjectRef>(references); while (newReferences.Count > 0) { foreach (KeyValuePair <IntPtr, UObjectRef> reference in newReferences) { UObject obj = reference.Value.Managed; if (obj != null && !obj.IsDestroyed) { bool requiresUnloadOrReload; Type type = obj.GetType(); if (!typesRequiringUnloadOrReload.TryGetValue(type, out requiresUnloadOrReload)) { MethodInfo unloadMethod = type.GetMethod("OnAssemblyUnload"); if (unloadMethod.DeclaringType != typeof(UObject)) { requiresUnloadOrReload = true; } else { MethodInfo reloadMethod = type.GetMethod("OnAssemblyReload"); if (reloadMethod.DeclaringType != typeof(UObject)) { requiresUnloadOrReload = true; } } typesRequiringUnloadOrReload.Add(type, requiresUnloadOrReload); } if (requiresUnloadOrReload) { reference.Value.Managed.OnAssemblyUnload(); allUnloadOrReloadReferences.Add(reference.Key); } } } newReferences.Clear(); #if ARRAY_GC foreach (UObjectRef objRef in References) { if (objRef != null && !references.ContainsKey(objRef.Native)) { references.Add(objRef.Native, objRef); newReferences.Add(objRef.Native, objRef); } } #else foreach (KeyValuePair <IntPtr, UObjectRef> reference in References) { if (!references.ContainsKey(reference.Key)) { references.Add(reference.Key, reference.Value); newReferences.Add(reference.Key, reference.Value); } } #endif } // Save all of the objects which we called OnAssemblyUnload on so that we can call // OnAssemblyReload when hotreload reloads. GCHelperHotReloadData hotReloadData = HotReload.Data.Create <GCHelperHotReloadData>(); foreach (IntPtr address in allUnloadOrReloadReferences) { hotReloadData.Objects.Add(new FWeakObjectPtr(address)); } Native_GCHelper.Clear(); }