-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
117 changed files
with
11,185 additions
and
11,295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,112 @@ | ||
namespace SMLHelper.Assets | ||
namespace SMLHelper.Assets; | ||
|
||
using SMLHelper.Utility; | ||
using System; | ||
using System.Collections.Generic; | ||
using UnityEngine; | ||
|
||
|
||
/// <summary> | ||
/// Class used by <see cref="PrefabInfo"/> to store game objects that used as prefabs. | ||
/// Game objects in cache are inactive and will not be on scene. | ||
/// </summary> | ||
public static class ModPrefabCache | ||
{ | ||
using SMLHelper.Utility; | ||
using System; | ||
using System.Collections.Generic; | ||
using UnityEngine; | ||
//Stored prefabs and their destruction timers. Keyed by ClassID. | ||
internal readonly static Dictionary<string, Tuple<bool, GameObject>> CachedPrefabs = new(); | ||
|
||
private static GameObject root; // active root object with CacheCleaner component | ||
private static GameObject prefabRoot; // inactive child object, parent for added prefabs | ||
|
||
/// <summary> | ||
/// Class used by <see cref="PrefabInfo"/> to store game objects that used as prefabs. | ||
/// Game objects in cache are inactive and will not be on scene. | ||
/// </summary> | ||
public static class ModPrefabCache | ||
private class CacheCleaner : MonoBehaviour | ||
{ | ||
//Stored prefabs and their destruction timers. Keyed by ClassID. | ||
internal readonly static Dictionary<string, Tuple<bool, GameObject>> CachedPrefabs = new(); | ||
|
||
private static GameObject root; // active root object with CacheCleaner component | ||
private static GameObject prefabRoot; // inactive child object, parent for added prefabs | ||
private float lastClean = 0f; | ||
|
||
private class CacheCleaner : MonoBehaviour | ||
public void Update() | ||
{ | ||
private float lastClean = 0f; | ||
lastClean += Time.deltaTime; | ||
|
||
public void Update() | ||
if(lastClean >= 5) | ||
{ | ||
lastClean += Time.deltaTime; | ||
|
||
if(lastClean >= 5) | ||
foreach(var pair in CachedPrefabs) | ||
{ | ||
foreach(var pair in CachedPrefabs) | ||
if(!pair.Value.Item1 || Builder.prefab == pair.Value.Item2) | ||
{ | ||
if(!pair.Value.Item1 || Builder.prefab == pair.Value.Item2) | ||
{ | ||
continue; | ||
} | ||
|
||
InternalLogger.Debug($"ModPrefabCache: removing prefab {pair.Value.Item2}"); | ||
Destroy(pair.Value.Item2); | ||
CachedPrefabs.Remove(pair.Key); | ||
lastClean = 0f; | ||
break; | ||
continue; | ||
} | ||
|
||
InternalLogger.Debug($"ModPrefabCache: removing prefab {pair.Value.Item2}"); | ||
Destroy(pair.Value.Item2); | ||
CachedPrefabs.Remove(pair.Key); | ||
lastClean = 0f; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static void Init() | ||
private static void Init() | ||
{ | ||
if (root != null) | ||
{ | ||
if (root != null) | ||
{ | ||
return; | ||
} | ||
return; | ||
} | ||
|
||
root = new GameObject("SMLHelper.PrefabCache", typeof(SceneCleanerPreserve), typeof(CacheCleaner)); | ||
UnityEngine.Object.DontDestroyOnLoad(root); | ||
root.EnsureComponent<SceneCleanerPreserve>(); | ||
root = new GameObject("SMLHelper.PrefabCache", typeof(SceneCleanerPreserve), typeof(CacheCleaner)); | ||
UnityEngine.Object.DontDestroyOnLoad(root); | ||
root.EnsureComponent<SceneCleanerPreserve>(); | ||
|
||
prefabRoot = new GameObject("PrefabRoot"); | ||
prefabRoot.transform.parent = root.transform; | ||
prefabRoot.SetActive(false); | ||
} | ||
prefabRoot = new GameObject("PrefabRoot"); | ||
prefabRoot.transform.parent = root.transform; | ||
prefabRoot.SetActive(false); | ||
} | ||
|
||
/// <summary> Add prefab to cache </summary> | ||
/// <param name="prefab"> Prefab to add. </param> | ||
/// <param name="autoremove"> | ||
/// Is prefab needed to be removed from cache after use. | ||
/// Prefabs without autoremove flag can be safely deleted by <see cref="UnityEngine.Object.Destroy(UnityEngine.Object)" /> | ||
/// </param> | ||
public static void AddPrefab(GameObject prefab, bool autoremove = true) | ||
{ | ||
Init(); | ||
prefab.transform.parent = prefabRoot.transform; | ||
/// <summary> Add prefab to cache </summary> | ||
/// <param name="prefab"> Prefab to add. </param> | ||
/// <param name="autoremove"> | ||
/// Is prefab needed to be removed from cache after use. | ||
/// Prefabs without autoremove flag can be safely deleted by <see cref="UnityEngine.Object.Destroy(UnityEngine.Object)" /> | ||
/// </param> | ||
public static void AddPrefab(GameObject prefab, bool autoremove = true) | ||
{ | ||
Init(); | ||
prefab.transform.parent = prefabRoot.transform; | ||
|
||
AddPrefabInternal(prefab, autoremove); | ||
} | ||
AddPrefabInternal(prefab, autoremove); | ||
} | ||
|
||
/// <summary> Add prefab copy to cache (instatiated copy will not run 'Awake') </summary> | ||
/// <param name="prefab"> Prefab to copy and add. </param> | ||
/// <param name="autoremove"> | ||
/// Is prefab copy needed to be removed from cache after use. | ||
/// Prefabs without autoremove flag can be safely deleted by <see cref="UnityEngine.Object.Destroy(UnityEngine.Object)" /> | ||
/// </param> | ||
/// <returns> Prefab copy </returns> | ||
public static GameObject AddPrefabCopy(GameObject prefab, bool autoremove = true) | ||
{ | ||
Init(); | ||
GameObject prefabCopy = UnityEngine.Object.Instantiate(prefab, prefabRoot.transform); | ||
/// <summary> Add prefab copy to cache (instatiated copy will not run 'Awake') </summary> | ||
/// <param name="prefab"> Prefab to copy and add. </param> | ||
/// <param name="autoremove"> | ||
/// Is prefab copy needed to be removed from cache after use. | ||
/// Prefabs without autoremove flag can be safely deleted by <see cref="UnityEngine.Object.Destroy(UnityEngine.Object)" /> | ||
/// </param> | ||
/// <returns> Prefab copy </returns> | ||
public static GameObject AddPrefabCopy(GameObject prefab, bool autoremove = true) | ||
{ | ||
Init(); | ||
GameObject prefabCopy = UnityEngine.Object.Instantiate(prefab, prefabRoot.transform); | ||
|
||
AddPrefabInternal(prefabCopy, autoremove); | ||
return prefabCopy; | ||
} | ||
AddPrefabInternal(prefabCopy, autoremove); | ||
return prefabCopy; | ||
} | ||
|
||
private static void AddPrefabInternal(GameObject prefab, bool autoremove) | ||
private static void AddPrefabInternal(GameObject prefab, bool autoremove) | ||
{ | ||
PrefabIdentifier identifier = prefab.GetComponent<PrefabIdentifier>(); | ||
if(identifier == null) | ||
{ | ||
PrefabIdentifier identifier = prefab.GetComponent<PrefabIdentifier>(); | ||
if(identifier == null) | ||
{ | ||
InternalLogger.Warn($"ModPrefabCache: prefab is missing a PrefabIdentifier! Unable to add to cache."); | ||
return; | ||
} | ||
if(!CachedPrefabs.ContainsKey(identifier.classId)) | ||
{ | ||
CachedPrefabs.Add(identifier.classId ,Tuple.Create(autoremove, prefab)); | ||
InternalLogger.Debug($"ModPrefabCache: adding prefab {prefab}"); | ||
} | ||
else | ||
{ | ||
InternalLogger.Warn($"ModPrefabCache: prefab {identifier.classId} already existed in cache!"); | ||
} | ||
InternalLogger.Warn($"ModPrefabCache: prefab is missing a PrefabIdentifier! Unable to add to cache."); | ||
return; | ||
} | ||
if(!CachedPrefabs.ContainsKey(identifier.classId)) | ||
{ | ||
CachedPrefabs.Add(identifier.classId ,Tuple.Create(autoremove, prefab)); | ||
InternalLogger.Debug($"ModPrefabCache: adding prefab {prefab}"); | ||
} | ||
else | ||
{ | ||
InternalLogger.Warn($"ModPrefabCache: prefab {identifier.classId} already existed in cache!"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,67 @@ | ||
using SMLHelper.Handlers; | ||
using SMLHelper.Utility; | ||
|
||
namespace SMLHelper.Assets | ||
{ | ||
using System.Collections; | ||
using UnityEngine; | ||
using UWE; | ||
|
||
// request for getting ModPrefab asynchronously | ||
internal class ModPrefabRequest: IPrefabRequest, IEnumerator | ||
{ | ||
private readonly PrefabInfo prefabInfo; | ||
namespace SMLHelper.Assets; | ||
|
||
private int state = 0; | ||
private CoroutineTask<GameObject> task; | ||
private TaskResult<GameObject> taskResult; | ||
using System.Collections; | ||
using UnityEngine; | ||
using UWE; | ||
|
||
public ModPrefabRequest(PrefabInfo prefabInfo) | ||
{ | ||
this.prefabInfo = prefabInfo; | ||
} | ||
// request for getting ModPrefab asynchronously | ||
internal class ModPrefabRequest: IPrefabRequest, IEnumerator | ||
{ | ||
private readonly PrefabInfo prefabInfo; | ||
|
||
private void Init() | ||
{ | ||
if (task != null) | ||
{ | ||
return; | ||
} | ||
private int state = 0; | ||
private CoroutineTask<GameObject> task; | ||
private TaskResult<GameObject> taskResult; | ||
|
||
taskResult = new TaskResult<GameObject>(); | ||
if (!PrefabHandler.Prefabs.TryGetPrefabForInfo(prefabInfo, out var factory)) | ||
{ | ||
InternalLogger.Error($"Couldn't find a prefab for the following prefab info: {prefabInfo}."); | ||
return; | ||
} | ||
|
||
task = new CoroutineTask<GameObject>(PrefabHandler.ProcessPrefabAsync(taskResult, prefabInfo, factory), taskResult); | ||
} | ||
public ModPrefabRequest(PrefabInfo prefabInfo) | ||
{ | ||
this.prefabInfo = prefabInfo; | ||
} | ||
|
||
public object Current | ||
private void Init() | ||
{ | ||
if (task != null) | ||
{ | ||
get | ||
{ | ||
Init(); | ||
return task; | ||
} | ||
return; | ||
} | ||
|
||
public bool TryGetPrefab(out GameObject result) | ||
taskResult = new TaskResult<GameObject>(); | ||
if (!PrefabHandler.Prefabs.TryGetPrefabForInfo(prefabInfo, out var factory)) | ||
{ | ||
result = taskResult.Get(); | ||
return result != null; | ||
InternalLogger.Error($"Couldn't find a prefab for the following prefab info: {prefabInfo}."); | ||
return; | ||
} | ||
|
||
task = new CoroutineTask<GameObject>(PrefabHandler.ProcessPrefabAsync(taskResult, prefabInfo, factory), taskResult); | ||
} | ||
|
||
public bool MoveNext() | ||
public object Current | ||
{ | ||
get | ||
{ | ||
Init(); | ||
return state++ == 0; | ||
return task; | ||
} | ||
} | ||
|
||
public void Reset() {} | ||
public bool TryGetPrefab(out GameObject result) | ||
{ | ||
result = taskResult.Get(); | ||
return result != null; | ||
} | ||
|
||
public void Release() | ||
{ | ||
} | ||
public bool MoveNext() | ||
{ | ||
Init(); | ||
return state++ == 0; | ||
} | ||
|
||
public void Reset() {} | ||
|
||
public void Release() | ||
{ | ||
} | ||
} | ||
} |
Oops, something went wrong.