182 lines
4.0 KiB
C#
182 lines
4.0 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
public static class ResetStaticUtility
|
|
{
|
|
private const string AutoRunOnPlayPrefsKey = "ResetStaticUtility.AutoRunOnPlay";
|
|
|
|
public static int ResetAll(bool logEach = false, Func<Assembly, bool> assemblyFilter = null)
|
|
{
|
|
int resetCount = 0;
|
|
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
|
|
foreach (var assembly in assemblies)
|
|
{
|
|
if (assembly.IsDynamic)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (assemblyFilter == null)
|
|
{
|
|
string name = assembly.GetName().Name;
|
|
if (!(name == "Assembly-CSharp" || name == "Assembly-CSharp-firstpass" || name.StartsWith("Assembly-CSharp-")))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
else if (!assemblyFilter(assembly))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Type[] types;
|
|
try
|
|
{
|
|
types = assembly.GetTypes();
|
|
}
|
|
catch (ReflectionTypeLoadException ex)
|
|
{
|
|
types = ex.Types.Where(t => t != null).ToArray();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"[ResetStatic] Failed to enumerate types for assembly {assembly.FullName}: {ex}");
|
|
continue;
|
|
}
|
|
|
|
foreach (var type in types)
|
|
{
|
|
if (type == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
|
|
foreach (var field in fields)
|
|
{
|
|
if (field.IsLiteral || field.IsInitOnly)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var attr = field.GetCustomAttribute<ResetStaticAttribute>(false);
|
|
if (attr == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
try
|
|
{
|
|
object newValue = null;
|
|
object currentValue = field.GetValue(null);
|
|
|
|
if (field.FieldType.IsValueType)
|
|
{
|
|
newValue = Activator.CreateInstance(field.FieldType);
|
|
field.SetValue(null, newValue);
|
|
resetCount++;
|
|
if (logEach)
|
|
{
|
|
Debug.Log($"[ResetStatic] {type.FullName}.{field.Name} set to default({field.FieldType.Name}).");
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (attr.ClearCollection && currentValue != null)
|
|
{
|
|
bool cleared = TryClearCollection(currentValue);
|
|
if (cleared)
|
|
{
|
|
resetCount++;
|
|
if (logEach)
|
|
{
|
|
Debug.Log($"[ResetStatic] {type.FullName}.{field.Name} collection cleared.");
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
field.SetValue(null, null);
|
|
resetCount++;
|
|
if (logEach)
|
|
{
|
|
Debug.Log($"[ResetStatic] {type.FullName}.{field.Name} set to null.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"[ResetStatic] Failed to reset {type.FullName}.{field.Name}: {ex}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return resetCount;
|
|
}
|
|
|
|
private static bool TryClearCollection(object instance)
|
|
{
|
|
try
|
|
{
|
|
if (instance is System.Collections.IDictionary dictionary)
|
|
{
|
|
dictionary.Clear();
|
|
return true;
|
|
}
|
|
|
|
if (instance is System.Collections.IList list)
|
|
{
|
|
list.Clear();
|
|
return true;
|
|
}
|
|
|
|
// Try generic ICollection<T>.Clear()
|
|
var clearMethod = instance.GetType().GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
|
|
if (clearMethod != null)
|
|
{
|
|
clearMethod.Invoke(instance, null);
|
|
return true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"[ResetStatic] Failed to clear collection of type {instance.GetType().FullName}: {ex}");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
private static void AutoResetOnPlay()
|
|
{
|
|
#if UNITY_EDITOR
|
|
bool enabled = UnityEditor.EditorPrefs.GetBool(AutoRunOnPlayPrefsKey, true);
|
|
if (!enabled)
|
|
{
|
|
return;
|
|
}
|
|
#endif
|
|
ResetAll(logEach: false);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
public static bool GetAutoRunOnPlay()
|
|
{
|
|
return UnityEditor.EditorPrefs.GetBool(AutoRunOnPlayPrefsKey, true);
|
|
}
|
|
|
|
public static void SetAutoRunOnPlay(bool enabled)
|
|
{
|
|
UnityEditor.EditorPrefs.SetBool(AutoRunOnPlayPrefsKey, enabled);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|