/**************************************************************************** * * Copyright (c) 2023 CRI Middleware Co., Ltd. * ****************************************************************************/ #if UNITY_2019_3_OR_NEWER using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; using CriWare.Editor; internal class CriStaticFieldReloader { private Dictionary initialFieldValue; private bool isEnabled = false; private List reloadTargetTypes = new List(); public CriStaticFieldReloader(Assembly assembly) { foreach (Type type in assembly.GetTypes()) { reloadTargetTypes.Add(type); } } public void CacheInitialFieldValue() { if (EditorSettings.enterPlayModeOptionsEnabled && EditorSettings.enterPlayModeOptions == EnterPlayModeOptions.DisableDomainReload) { if(CriCommonEditorSettings.Instance.EnableStaticFieldReload) { isEnabled = true; } } if (isEnabled) { initialFieldValue = RegisterInitialFieldDict(); } } public void ResetStaticField() { if (EditorSettings.enterPlayModeOptionsEnabled) { if(!CriCommonEditorSettings.Instance.EnableStaticFieldReload) { Debug.LogWarning("[CRIWARE] CriStaticFieldReloader is not enabled, static fields will not be reloaded when re-entering playmode."); } } if (isEnabled) { CompareAndResetStaticFieldValue(initialFieldValue); } } private List GetReloadTargetFieldInfos() { List result = new List(); foreach (Type type in reloadTargetTypes) { List fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) .Where(field => !field.IsLiteral && !field.IsInitOnly) // IsLiteral = const; IsInitOnly = readOnly; .ToList(); result.AddRange(fields); } return result; } private Dictionary RegisterInitialFieldDict() { Dictionary result = new Dictionary() { }; List asmDefault = GetReloadTargetFieldInfos(); foreach (FieldInfo field in asmDefault) { result.Add(field, field.GetValue(null)); } return result; } private void CompareAndResetStaticFieldValue(Dictionary DefaultFieldInfo) { List asmCurrent = GetReloadTargetFieldInfos(); foreach (FieldInfo field in asmCurrent) { if (!DefaultFieldInfo.ContainsKey(field)) { Debug.LogWarning("[CRIWARE][Internal] CriStaticFieldReloader tried to reload uncached field: " + field.DeclaringType.ToString() + field.Name); continue; } object defaultValue = DefaultFieldInfo[field]; if(field.GetValue(null) != defaultValue) { field.SetValue(null, defaultValue); } } } } // End of class CriStaticFieldReloader #endif