Skip to content

Commit 70c04ad

Browse files
fix: FINALLY fix prefab request & caching issues (#525)
* 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]>
1 parent d27d803 commit 70c04ad

File tree

4 files changed

+33
-23
lines changed

4 files changed

+33
-23
lines changed

Nautilus/Assets/ModPrefabCache.cs

+17-17
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ namespace Nautilus.Assets;
1111
/// </summary>
1212
public static class ModPrefabCache
1313
{
14+
internal static HashSet<string> RunningPrefabs = new();
15+
1416
private static ModPrefabCacheInstance _cacheInstance;
15-
internal static Dictionary<string, ModPrefabRequest> Requests { get; } = new Dictionary<string, ModPrefabRequest>();
1617

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

8586
gameObject.AddComponent<SceneCleanerPreserve>();
8687
DontDestroyOnLoad(gameObject);
88+
SaveUtils.RegisterOnQuitEvent(ModPrefabCache.RunningPrefabs.Clear);
8789
}
8890

8991
public void EnterPrefabIntoCache(GameObject prefab)
9092
{
91-
// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
92-
if(prefab.IsPrefab())
93-
{
94-
InternalLogger.Debug($"Game Object: {prefab} is a proper prefab. Skipping parenting for cache.");
95-
}
96-
else
97-
{
98-
prefab.transform.parent = _prefabRoot;
99-
prefab.SetActive(true);
100-
}
101-
10293
var prefabIdentifier = prefab.GetComponent<PrefabIdentifier>();
10394

104-
if(prefabIdentifier == null)
95+
if (prefabIdentifier == null)
10596
{
10697
InternalLogger.Warn($"ModPrefabCache: prefab {prefab.name} is missing a PrefabIdentifier component! Unable to add to cache.");
10798
return;
10899
}
109100

110-
// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
111-
if(!Entries.ContainsKey(prefabIdentifier.classId))
101+
if (!Entries.ContainsKey(prefabIdentifier.classId))
112102
{
113103
Entries.Add(prefabIdentifier.classId, prefab);
114104
InternalLogger.Debug($"ModPrefabCache: added prefab {prefab}");
105+
// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
106+
if (prefab.IsPrefab())
107+
{
108+
InternalLogger.Debug($"Game Object: {prefab} is a proper prefab. Skipping parenting for cache.");
109+
}
110+
else
111+
{
112+
prefab.transform.parent = _prefabRoot;
113+
prefab.SetActive(true);
114+
}
115115
}
116-
else // this should never happen
116+
else // This should never happen
117117
{
118118
InternalLogger.Warn($"ModPrefabCache: prefab {prefabIdentifier.classId} already existed in cache!");
119-
}
119+
}
120120
}
121121

122122
public void RemoveCachedPrefab(string classId)

Nautilus/Assets/ModPrefabRequest.cs

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ internal class ModPrefabRequest: IPrefabRequest
2020
public ModPrefabRequest(PrefabInfo prefabInfo)
2121
{
2222
this.prefabInfo = prefabInfo;
23-
ModPrefabCache.Requests[prefabInfo.ClassID] = this;
2423
}
2524

2625
private void Init()

Nautilus/Handlers/PrefabHandler.cs

+16
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public static class PrefabHandler
2020

2121
internal static IEnumerator GetPrefabAsync(TaskResult<GameObject> gameObject, PrefabInfo info, PrefabFactoryAsync prefabFactory)
2222
{
23+
if (ModPrefabCache.RunningPrefabs.Contains(info.ClassID))
24+
{
25+
yield return new WaitUntil(() => ModPrefabCache.RunningPrefabs.Contains(info.ClassID) is false);
26+
}
27+
2328
if (ModPrefabCache.TryGetPrefabFromCache(info.ClassID, out var prefabInCache))
2429
{
2530
gameObject.Set(prefabInCache);
@@ -31,6 +36,16 @@ internal static IEnumerator GetPrefabAsync(TaskResult<GameObject> gameObject, Pr
3136

3237
private static IEnumerator InitPrefabAsync(TaskResult<GameObject> gameObject, PrefabInfo info, PrefabFactoryAsync prefabFactory)
3338
{
39+
if (!ModPrefabCache.RunningPrefabs.Add(info.ClassID))
40+
{
41+
yield return new WaitUntil(() => ModPrefabCache.RunningPrefabs.Contains(info.ClassID) is false);
42+
if (ModPrefabCache.TryGetPrefabFromCache(info.ClassID, out var prefabInCache))
43+
{
44+
gameObject.Set(prefabInCache);
45+
yield break;
46+
}
47+
}
48+
3449
if (prefabFactory == null)
3550
{
3651
InternalLogger.Error($"PrefabHandler: Prefab Factory for {info.ClassID} is null!");
@@ -85,6 +100,7 @@ private static IEnumerator InitPrefabAsync(TaskResult<GameObject> gameObject, Pr
85100

86101
gameObject.Set(obj);
87102
ModPrefabCache.AddPrefab(obj);
103+
ModPrefabCache.RunningPrefabs.Remove(info.ClassID);
88104
}
89105
}
90106

Nautilus/Patchers/PrefabDatabasePatcher.cs

-5
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ private static IPrefabRequest GetModPrefabAsync(string classId)
7979
return null;
8080
}
8181

82-
if(ModPrefabCache.Requests.TryGetValue(prefabInfo.ClassID, out var request))
83-
{
84-
return request;
85-
}
86-
8782
return new ModPrefabRequest(prefabInfo);
8883
}
8984

0 commit comments

Comments
 (0)