Skip to content

Commit

Permalink
fix: Prefab cache now resets (#544)
Browse files Browse the repository at this point in the history
* Prefab cache now resets on world quit

* Fixed `GameObjectExtensions.IsPrefab` sometimes failing

* Fixed null check
  • Loading branch information
Metious authored Apr 25, 2024
1 parent 8a37c29 commit 9464432
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
43 changes: 39 additions & 4 deletions Nautilus/Assets/ModPrefabCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public static bool IsPrefabCached(string classId)
/// Any prefab with the matching <paramref name="classId"/> will be removed from the cache.
/// </summary>
/// <param name="classId">The class id of the prefab that will be removed.</param>
/// <remarks>This operation is extremely dangerous on custom prefabs that are directly registering an asset bundle prefab as it may make the prefab unusable in the current session.<br/>Avoid using this method unless you know what you're doing.</remarks>
public static void RemovePrefabFromCache(string classId)
{
if(_cacheInstance == null)
Expand Down Expand Up @@ -85,7 +86,9 @@ private void Awake()

gameObject.AddComponent<SceneCleanerPreserve>();
DontDestroyOnLoad(gameObject);

SaveUtils.RegisterOnQuitEvent(ModPrefabCache.RunningPrefabs.Clear);
SaveUtils.RegisterOnQuitEvent(RemoveFakePrefabs);
}

public void EnterPrefabIntoCache(GameObject prefab)
Expand Down Expand Up @@ -122,12 +125,44 @@ public void EnterPrefabIntoCache(GameObject prefab)

public void RemoveCachedPrefab(string classId)
{
if (Entries.TryGetValue(classId, out var prefab))
if (!Entries.TryGetValue(classId, out var prefab))
{
if(!prefab.IsPrefab())
Destroy(prefab);
InternalLogger.Debug($"ModPrefabCache: removed prefab {classId}");
return;
}

if (!prefab)
{
InternalLogger.Debug($"ModPrefabCache: Prefab for '{classId}' is null; removing entry.");
Entries.Remove(classId);
return;
}

if (!prefab.IsPrefab())
{
Destroy(prefab);
}

InternalLogger.Debug($"ModPrefabCache: removing prefab '{classId}'");
Entries.Remove(classId);
}

private void RemoveFakePrefabs()
{
foreach (var prefab in new Dictionary<string, GameObject>(Entries))
{
if (prefab.Value.Exists() is null)
{
Entries.Remove(prefab.Key);
continue;
}

if (prefab.Value.IsPrefab())
{
continue;
}

Destroy(prefab.Value);
Entries.Remove(prefab.Key);
}
}

Expand Down
4 changes: 3 additions & 1 deletion Nautilus/Extensions/GameObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Nautilus.Utility;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;

namespace Nautilus.Extensions;
Expand Down Expand Up @@ -136,9 +137,10 @@ public static Transform SearchChild(this Transform transform, string name)
/// </summary>
/// <param name="gameObject">The game object to check.</param>
/// <returns>True if this game object is a proper prefab, otherwise false.</returns>
/// <exception cref="System.NullReferenceException"><paramref name="gameObject"/> is null.</exception>
public static bool IsPrefab(this GameObject gameObject)
{
return gameObject.transform.parent == null && !gameObject.activeInHierarchy && gameObject.activeSelf;
return gameObject.scene.name is null && gameObject.scene.loadingState is Scene.LoadingState.NotLoaded;
}

/// <summary>
Expand Down

0 comments on commit 9464432

Please sign in to comment.