Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Fixes for the ModPrefabCache #469

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions Nautilus/Assets/ModPrefabCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Nautilus.Assets;
public static class ModPrefabCache
{
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 All @@ -29,10 +30,7 @@ public static void AddPrefab(GameObject prefab)
/// <returns>True if a prefab by the given <paramref name="classId"/> exists in the cache, otherwise false.</returns>
public static bool IsPrefabCached(string classId)
{
if (_cacheInstance == null)
return false;

return _cacheInstance.Entries.ContainsKey(classId);
return _cacheInstance != null && _cacheInstance.Entries.ContainsKey(classId);
}

/// <summary>
Expand All @@ -41,7 +39,7 @@ public static bool IsPrefabCached(string classId)
/// <param name="classId">The class id of the prefab that will be removed.</param>
public static void RemovePrefabFromCache(string classId)
{
if (_cacheInstance == null)
if(_cacheInstance == null)
return;

_cacheInstance.RemoveCachedPrefab(classId);
Expand All @@ -55,7 +53,7 @@ public static void RemovePrefabFromCache(string classId)
/// <returns>True if the prefab was found in the cache, otherwise false.</returns>
public static bool TryGetPrefabFromCache(string classId, out GameObject prefab)
{
if (_cacheInstance == null)
if(_cacheInstance == null)
{
prefab = null;
return false;
Expand All @@ -66,12 +64,13 @@ public static bool TryGetPrefabFromCache(string classId, out GameObject prefab)

private static void EnsureCacheExists()
{
if (_cacheInstance != null)
if(_cacheInstance != null)
return;
_cacheInstance = new GameObject("Nautilus.PrefabCache").AddComponent<ModPrefabCacheInstance>();
}
}
internal class ModPrefabCacheInstance : MonoBehaviour

internal class ModPrefabCacheInstance: MonoBehaviour
{
public Dictionary<string, GameObject> Entries { get; } = new Dictionary<string, GameObject>();

Expand All @@ -90,7 +89,7 @@ private void Awake()
public void EnterPrefabIntoCache(GameObject prefab)
{
// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
if (prefab.IsPrefab())
if(prefab.IsPrefab())
{
InternalLogger.Debug($"Game Object: {prefab} is a proper prefab. Skipping parenting for cache.");
}
Expand All @@ -102,13 +101,14 @@ public void EnterPrefabIntoCache(GameObject prefab)

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

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

if (!Entries.ContainsKey(prefabIdentifier.classId))
// Proper prefabs can never exist in the scene, so parenting them is dangerous and pointless.
if(!Entries.ContainsKey(prefabIdentifier.classId))
{
Entries.Add(prefabIdentifier.classId, prefab);
InternalLogger.Debug($"ModPrefabCache: adding prefab {prefab}");
Expand All @@ -121,9 +121,10 @@ public void EnterPrefabIntoCache(GameObject prefab)

public void RemoveCachedPrefab(string classId)
{
if (Entries.TryGetValue(classId, out var prefab))
if(Entries.TryGetValue(classId, out var prefab))
{
Destroy(prefab);
if(!prefab.IsPrefab())
Destroy(prefab);
Entries.Remove(classId);
}
}
Expand Down
1 change: 1 addition & 0 deletions Nautilus/Assets/ModPrefabRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ internal class ModPrefabRequest: IPrefabRequest, IEnumerator
public ModPrefabRequest(PrefabInfo prefabInfo)
{
this.prefabInfo = prefabInfo;
ModPrefabCache.Requests[prefabInfo.ClassID] = this;
}

private void Init()
Expand Down
13 changes: 11 additions & 2 deletions Nautilus/Handlers/PrefabHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,18 @@ internal static IEnumerator GetPrefabAsync(TaskResult<GameObject> gameObject, Pr

yield return prefabFactory(gameObject);

yield return ProcessPrefabAsync(gameObject.Get(), info, prefabFactory);
yield return ProcessPrefabAsync(gameObject, info, prefabFactory);
}

private static IEnumerator ProcessPrefabAsync(GameObject obj, PrefabInfo info, PrefabFactoryAsync prefabFactory)
private static IEnumerator ProcessPrefabAsync(TaskResult<GameObject> gameObject, PrefabInfo info, PrefabFactoryAsync prefabFactory)
{
var obj = gameObject.Get();
if(obj == null)
{
InternalLogger.Error($"PrefabHandler: Tried to process a null prefab.");
yield break;
}

var techType = info.TechType;
var classId = info.ClassID;

Expand Down Expand Up @@ -69,6 +76,8 @@ private static IEnumerator ProcessPrefabAsync(GameObject obj, PrefabInfo info, P
if (Prefabs.TryGetPostProcessorForInfo(info, out var postProcessor))
yield return postProcessor?.Invoke(obj);


gameObject.Set(obj);
ModPrefabCache.AddPrefab(obj);
}
}
Expand Down
29 changes: 13 additions & 16 deletions Nautilus/Patchers/PrefabDatabasePatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,11 @@ internal static bool DeferredSpawner_AddressablesTask_Spawn_Prefix(DeferredSpawn

internal static IEnumerator SpawnAsyncReplacement(DeferredSpawner.AddressablesTask task, PrefabInfo prefabInfo)
{
TaskResult<GameObject> prefabResult = new();
if (!PrefabHandler.Prefabs.TryGetPrefabForInfo(prefabInfo, out var prefabFactory))
{
InternalLogger.Error($"Couldn't find a prefab factory for the following prefab info: {prefabInfo}");
yield break;
}
var request = GetModPrefabAsync(prefabInfo.ClassID);

yield return PrefabHandler.GetPrefabAsync(prefabResult, prefabInfo, prefabFactory);
GameObject prefab = prefabResult.Get();
yield return request;

if(prefab != null)
if(request.TryGetPrefab(out var prefab))
{
task.spawnedObject = EditorModifications.Instantiate(prefab, task.parent, task.position, task.rotation, task.instantiateActivated);
}
Expand All @@ -80,11 +74,14 @@ internal static IEnumerator SpawnAsyncReplacement(DeferredSpawner.AddressablesTa

private static IPrefabRequest GetModPrefabAsync(string classId)
{
if (!PrefabHandler.Prefabs.TryGetInfoForClassId(classId, out PrefabInfo prefabInfo))
if(!PrefabHandler.Prefabs.TryGetInfoForClassId(classId, out PrefabInfo prefabInfo))
{
return null;
}

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

return new ModPrefabRequest(prefabInfo);
}

Expand Down Expand Up @@ -114,16 +111,16 @@ internal static bool InstantiateAsync_Prefix(ref IEnumerator __result,string key

internal static IEnumerator InstantiateAsync(PrefabInfo prefabInfo, IOut<GameObject> result, Transform parent, Vector3 position, Quaternion rotation, bool awake)
{
TaskResult<GameObject> task = new();
if (!PrefabHandler.Prefabs.TryGetPrefabForInfo(prefabInfo, out var prefabFactory))
var request = GetModPrefabAsync(prefabInfo.ClassID);

yield return request;

if(!request.TryGetPrefab(out var prefab))
{
InternalLogger.Error($"Couldn't find a prefab factory for the following prefab info: {prefabInfo}");
result.Set(null);
yield break;
}

yield return PrefabHandler.GetPrefabAsync(task, prefabInfo, prefabFactory);

GameObject prefab = task.Get();
result.Set(EditorModifications.Instantiate(prefab, parent, position, rotation, awake));
}

Expand Down