Skip to content

Commit

Permalink
fix: FINALLY fix prefab request & caching issues (#525)
Browse files Browse the repository at this point in the history
* Remove requests array and lock cache dictionary

Freddy 5 bear or or or or or

* Change duplicate cache entries log level to debug

* Removed unnecessary lock statement

The game is single threaded, so the lock does nothing.

* Attempt to make Nautilus construct prefabs once

* Make sure to clear the running prefabs on quit

* Add back warning log

---------

Co-authored-by: Metious <[email protected]>
  • Loading branch information
LeeTwentyThree and Metious committed Jan 2, 2024
1 parent d27d803 commit 70c04ad
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 23 deletions.
34 changes: 17 additions & 17 deletions Nautilus/Assets/ModPrefabCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace Nautilus.Assets;
/// </summary>
public static class ModPrefabCache
{
internal static HashSet<string> RunningPrefabs = new();

private static ModPrefabCacheInstance _cacheInstance;
internal static Dictionary<string, ModPrefabRequest> Requests { get; } = new Dictionary<string, ModPrefabRequest>();

/// <summary> Adds the given prefab to the cache. </summary>
/// <param name="prefab"> The prefab object that is disabled and cached. </param>
Expand Down Expand Up @@ -84,39 +85,38 @@ private void Awake()

gameObject.AddComponent<SceneCleanerPreserve>();
DontDestroyOnLoad(gameObject);
SaveUtils.RegisterOnQuitEvent(ModPrefabCache.RunningPrefabs.Clear);
}

public void EnterPrefabIntoCache(GameObject prefab)
{
// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
if(prefab.IsPrefab())
{
InternalLogger.Debug($"Game Object: {prefab} is a proper prefab. Skipping parenting for cache.");
}
else
{
prefab.transform.parent = _prefabRoot;
prefab.SetActive(true);
}

var prefabIdentifier = prefab.GetComponent<PrefabIdentifier>();

if(prefabIdentifier == null)
if (prefabIdentifier == null)
{
InternalLogger.Warn($"ModPrefabCache: prefab {prefab.name} is missing a PrefabIdentifier component! Unable to add to cache.");
return;
}

// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
if(!Entries.ContainsKey(prefabIdentifier.classId))
if (!Entries.ContainsKey(prefabIdentifier.classId))
{
Entries.Add(prefabIdentifier.classId, prefab);
InternalLogger.Debug($"ModPrefabCache: added prefab {prefab}");
// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
if (prefab.IsPrefab())
{
InternalLogger.Debug($"Game Object: {prefab} is a proper prefab. Skipping parenting for cache.");
}
else
{
prefab.transform.parent = _prefabRoot;
prefab.SetActive(true);
}
}
else // this should never happen
else // This should never happen
{
InternalLogger.Warn($"ModPrefabCache: prefab {prefabIdentifier.classId} already existed in cache!");
}
}
}

public void RemoveCachedPrefab(string classId)
Expand Down
1 change: 0 additions & 1 deletion Nautilus/Assets/ModPrefabRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ internal class ModPrefabRequest: IPrefabRequest
public ModPrefabRequest(PrefabInfo prefabInfo)
{
this.prefabInfo = prefabInfo;
ModPrefabCache.Requests[prefabInfo.ClassID] = this;
}

private void Init()
Expand Down
16 changes: 16 additions & 0 deletions Nautilus/Handlers/PrefabHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public static class PrefabHandler

internal static IEnumerator GetPrefabAsync(TaskResult<GameObject> gameObject, PrefabInfo info, PrefabFactoryAsync prefabFactory)
{
if (ModPrefabCache.RunningPrefabs.Contains(info.ClassID))
{
yield return new WaitUntil(() => ModPrefabCache.RunningPrefabs.Contains(info.ClassID) is false);
}

if (ModPrefabCache.TryGetPrefabFromCache(info.ClassID, out var prefabInCache))
{
gameObject.Set(prefabInCache);
Expand All @@ -31,6 +36,16 @@ internal static IEnumerator GetPrefabAsync(TaskResult<GameObject> gameObject, Pr

private static IEnumerator InitPrefabAsync(TaskResult<GameObject> gameObject, PrefabInfo info, PrefabFactoryAsync prefabFactory)
{
if (!ModPrefabCache.RunningPrefabs.Add(info.ClassID))
{
yield return new WaitUntil(() => ModPrefabCache.RunningPrefabs.Contains(info.ClassID) is false);
if (ModPrefabCache.TryGetPrefabFromCache(info.ClassID, out var prefabInCache))
{
gameObject.Set(prefabInCache);
yield break;
}
}

if (prefabFactory == null)
{
InternalLogger.Error($"PrefabHandler: Prefab Factory for {info.ClassID} is null!");
Expand Down Expand Up @@ -85,6 +100,7 @@ private static IEnumerator InitPrefabAsync(TaskResult<GameObject> gameObject, Pr

gameObject.Set(obj);
ModPrefabCache.AddPrefab(obj);
ModPrefabCache.RunningPrefabs.Remove(info.ClassID);
}
}

Expand Down
5 changes: 0 additions & 5 deletions Nautilus/Patchers/PrefabDatabasePatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ private static IPrefabRequest GetModPrefabAsync(string classId)
return null;
}

if(ModPrefabCache.Requests.TryGetValue(prefabInfo.ClassID, out var request))
{
return request;
}

return new ModPrefabRequest(prefabInfo);
}

Expand Down

0 comments on commit 70c04ad

Please sign in to comment.