private static object WeakenSerializationDependencyReference(ISerializationDependency dependency) { /* * We need to use weak references to UnityEngine.Object dependencies, because otherwise * Unity will consider them to be always used, and never call OnDisable() on them when unloading, * which in turn will never unregister them from our available dependencies. * Using WeakReference is overkill and not actually helpful. We don't need to access the actual dependency * object later on, and anyway the only way we could immmutably compare for equality in the hash set is based on the * original hash code, which is not guaranteed to be unique... Except for UnityEngine.Objects, * in which case the hash code is the native instance ID, which is guaranteed to be unique within a given assembly session. * https://support.ludiq.io/communities/5/topics/4150-flowmachine-memory-leak#comment-11626 */ if (dependency is UnityObject uo) { return(uo.GetHashCode()); } else { // In this case, we can't actually weaken the reference. // But it shouldn't be a problem, because in non-UO cases, the // dependency should be able to unregister itself as it doesn't rely // on the native unload callbacks of unused assets. return(dependency); } }
public static void NotifyDependencyDeserialized(ISerializationDependency dependency) { availableDependencies.Add(dependency); #if DEBUG_DEPENDENCIES Debug.Log($"Dependency {dependency} is now available.\n".Colored(Color.yellow)); #endif foreach (var awaitingDepender in awaitingDependers.ToArray()) { if (!awaitingDependers.Contains(awaitingDepender)) { // In case the depender was already handled by a recursive // dependency via OnAfterDependenciesDeserialized, // we skip it. This is necessary because we duplicated // the set to safely iterate over it with removal. // // This should prevent OnAfterDependenciesDeserialized from // running twice on any given depender in a single deserialization // operation. continue; } CheckIfDependenciesMet(awaitingDepender); } }
public static void NotifyDependencyDeserializing(ISerializationDependency dependency) { if (availableDependencies.Remove(dependency)) { #if DEBUG_DEPENDENCIES Debug.Log($"Dependency {dependency} is no longer available.\n".Colored(Color.red)); #endif } }
public static void NotifyDependencyAvailable(ISerializationDependency dependency) { availableDependencies.Add(WeakenSerializationDependencyReference(dependency)); foreach (var awaitingDepender in awaitingDependers.ToArray()) { if (!awaitingDependers.Contains(awaitingDepender)) { // In case the depender was already handled by a recursive // dependency via OnAfterDependenciesDeserialized, // we skip it. This is necessary because we duplicated // the set to safely iterate over it with removal. // // This should prevent OnAfterDependenciesDeserialized from // running twice on any given depender in a single deserialization // operation. continue; } CheckIfDependenciesMet(awaitingDepender); } }
public static void NotifyDependencyUnavailable(ISerializationDependency dependency) { availableDependencies.Remove(WeakenSerializationDependencyReference(dependency)); }
public static void NotifyDependencyDeserialized(ISerializationDependency dependency) { NotifyDependencyAvailable(dependency); }
public static void NotifyDependencyDeserializing(ISerializationDependency dependency) { NotifyDependencyUnavailable(dependency); }