From 361873803f5abd3174f31216c200780cf31515e2 Mon Sep 17 00:00:00 2001 From: walon Date: Mon, 28 Apr 2025 10:20:08 +0800 Subject: [PATCH] [refactor] refactor code of settings. --- Editor/Settings/EditorStatusWatcher.cs | 29 ---- Editor/Settings/EditorStatusWatcher.cs.meta | 11 -- Editor/Settings/HybridCLRSettingProvider.cs | 140 +++++------------- Editor/Settings/HybridCLRSettings.cs | 48 +++++- Editor/Settings/ScriptableSignleton.cs | 89 ----------- Editor/Settings/ScriptableSignleton.cs.meta | 11 -- Editor/Settings/SettingsPresetReceiver.cs | 39 ----- .../Settings/SettingsPresetReceiver.cs.meta | 11 -- 8 files changed, 80 insertions(+), 298 deletions(-) delete mode 100644 Editor/Settings/EditorStatusWatcher.cs delete mode 100644 Editor/Settings/EditorStatusWatcher.cs.meta delete mode 100644 Editor/Settings/ScriptableSignleton.cs delete mode 100644 Editor/Settings/ScriptableSignleton.cs.meta delete mode 100644 Editor/Settings/SettingsPresetReceiver.cs delete mode 100644 Editor/Settings/SettingsPresetReceiver.cs.meta diff --git a/Editor/Settings/EditorStatusWatcher.cs b/Editor/Settings/EditorStatusWatcher.cs deleted file mode 100644 index 986f026..0000000 --- a/Editor/Settings/EditorStatusWatcher.cs +++ /dev/null @@ -1,29 +0,0 @@ -using HybridCLR.Editor; -using System; -using UnityEditor; -using UnityEditorInternal; - -namespace HybridCLR.Editor.Settings -{ - - [InitializeOnLoad] - public static class EditorStatusWatcher - { - public static Action OnEditorFocused; - static bool isFocused; - static EditorStatusWatcher() => EditorApplication.update += Update; - static void Update() - { - if (isFocused != InternalEditorUtility.isApplicationActive) - { - isFocused = InternalEditorUtility.isApplicationActive; - if (isFocused) - { - HybridCLRSettings.LoadOrCreate(); - OnEditorFocused?.Invoke(); - } - } - } - } - -} \ No newline at end of file diff --git a/Editor/Settings/EditorStatusWatcher.cs.meta b/Editor/Settings/EditorStatusWatcher.cs.meta deleted file mode 100644 index 317bfd7..0000000 --- a/Editor/Settings/EditorStatusWatcher.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 093a9e6c1e7399244bbcd8983fdbfdee -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Settings/HybridCLRSettingProvider.cs b/Editor/Settings/HybridCLRSettingProvider.cs index 7695484..51ecb3b 100644 --- a/Editor/Settings/HybridCLRSettingProvider.cs +++ b/Editor/Settings/HybridCLRSettingProvider.cs @@ -18,7 +18,7 @@ namespace HybridCLR.Editor.Settings private SerializedProperty _hotUpdateAssemblies; private SerializedProperty _preserveHotUpdateAssemblies; private SerializedProperty _hotUpdateDllCompileOutputRootDir; - private SerializedProperty _externalHotUpdateAssembliyDirs; + private SerializedProperty _externalHotUpdateAssemblyDirs; private SerializedProperty _strippedAOTDllOutputRootDir; private SerializedProperty _patchAOTAssemblies; private SerializedProperty _outputLinkFile; @@ -26,13 +26,13 @@ namespace HybridCLR.Editor.Settings private SerializedProperty _maxGenericReferenceIteration; private SerializedProperty _maxMethodBridgeGenericIteration; - private GUIStyle buttonStyle; public HybridCLRSettingsProvider() : base("Project/HybridCLR Settings", SettingsScope.Project) { } + public override void OnActivate(string searchContext, VisualElement rootElement) { - EditorStatusWatcher.OnEditorFocused += OnEditorFocused; InitGUI(); } + private void InitGUI() { var setting = HybridCLRSettings.LoadOrCreate(); @@ -46,7 +46,7 @@ namespace HybridCLR.Editor.Settings _hotUpdateAssemblies = _serializedObject.FindProperty("hotUpdateAssemblies"); _preserveHotUpdateAssemblies = _serializedObject.FindProperty("preserveHotUpdateAssemblies"); _hotUpdateDllCompileOutputRootDir = _serializedObject.FindProperty("hotUpdateDllCompileOutputRootDir"); - _externalHotUpdateAssembliyDirs = _serializedObject.FindProperty("externalHotUpdateAssembliyDirs"); + _externalHotUpdateAssemblyDirs = _serializedObject.FindProperty("externalHotUpdateAssembliyDirs"); _strippedAOTDllOutputRootDir = _serializedObject.FindProperty("strippedAOTDllOutputRootDir"); _patchAOTAssemblies = _serializedObject.FindProperty("patchAOTAssemblies"); _outputLinkFile = _serializedObject.FindProperty("outputLinkFile"); @@ -54,125 +54,53 @@ namespace HybridCLR.Editor.Settings _maxGenericReferenceIteration = _serializedObject.FindProperty("maxGenericReferenceIteration"); _maxMethodBridgeGenericIteration = _serializedObject.FindProperty("maxMethodBridgeGenericIteration"); } - private void OnEditorFocused() - { - InitGUI(); - Repaint(); - } - public override void OnTitleBarGUI() - { - base.OnTitleBarGUI(); - var rect = GUILayoutUtility.GetLastRect(); - buttonStyle = buttonStyle ?? GUI.skin.GetStyle("IconButton"); - #region 绘制官方网站跳转按钮 - var w = rect.x + rect.width; - rect.x = w - 57; - rect.y += 6; - rect.width = rect.height = 18; - var content = EditorGUIUtility.IconContent("_Help"); - content.tooltip = "点击访问 HybridCLR 官方文档"; - if (GUI.Button(rect, content, buttonStyle)) - { - Application.OpenURL("https://hybridclr.doc.code-philosophy.com/"); - } - #endregion - #region 绘制 Preset - rect.x += 19; - content = EditorGUIUtility.IconContent("Preset.Context"); - content.tooltip = "点击存储或加载 Preset ."; - if (GUI.Button(rect, content, buttonStyle)) - { - var target = HybridCLRSettings.Instance; - var receiver = ScriptableObject.CreateInstance(); - receiver.Init(target, this); - PresetSelector.ShowSelector(target, null, true, receiver); - } - #endregion - #region 绘制 Reset - rect.x += 19; - content = EditorGUIUtility.IconContent( -#if UNITY_2021_3_OR_NEWER - "pane options" -#else - "_Popup" -#endif - ); - content.tooltip = "Reset"; - if (GUI.Button(rect, content, buttonStyle)) - { - GenericMenu menu = new GenericMenu(); - menu.AddItem(new GUIContent("Reset"), false, () => - { - Undo.RecordObject(HybridCLRSettings.Instance, "Capture Value for Reset"); - var dv = ScriptableObject.CreateInstance(); - var json = EditorJsonUtility.ToJson(dv); - UnityEngine.Object.DestroyImmediate(dv); - EditorJsonUtility.FromJsonOverwrite(json, HybridCLRSettings.Instance); - HybridCLRSettings.Save(); - }); - menu.ShowAsContext(); - } - #endregion - } public override void OnGUI(string searchContext) { - using (CreateSettingsWindowGUIScope()) + if (_serializedObject == null || !_serializedObject.targetObject) { - if (_serializedObject == null||!_serializedObject.targetObject) - { - InitGUI(); - } - _serializedObject.Update(); - EditorGUI.BeginChangeCheck(); - EditorGUILayout.PropertyField(_enable); - EditorGUILayout.PropertyField(_hybridclrRepoURL); - EditorGUILayout.PropertyField(_il2cppPlusRepoURL); - EditorGUILayout.PropertyField(_useGlobalIl2cpp); - EditorGUILayout.PropertyField(_hotUpdateAssemblyDefinitions); - EditorGUILayout.PropertyField(_hotUpdateAssemblies); - EditorGUILayout.PropertyField(_preserveHotUpdateAssemblies); - EditorGUILayout.PropertyField(_hotUpdateDllCompileOutputRootDir); - EditorGUILayout.PropertyField(_externalHotUpdateAssembliyDirs); - EditorGUILayout.PropertyField(_strippedAOTDllOutputRootDir); - EditorGUILayout.PropertyField(_patchAOTAssemblies); - EditorGUILayout.PropertyField(_outputLinkFile); - EditorGUILayout.PropertyField(_outputAOTGenericReferenceFile); - EditorGUILayout.PropertyField(_maxGenericReferenceIteration); - EditorGUILayout.PropertyField(_maxMethodBridgeGenericIteration); - if (EditorGUI.EndChangeCheck()) - { - _serializedObject.ApplyModifiedProperties(); - HybridCLRSettings.Save(); - } + InitGUI(); + } + _serializedObject.Update(); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(_enable); + EditorGUILayout.PropertyField(_hybridclrRepoURL); + EditorGUILayout.PropertyField(_il2cppPlusRepoURL); + EditorGUILayout.PropertyField(_useGlobalIl2cpp); + EditorGUILayout.PropertyField(_hotUpdateAssemblyDefinitions); + EditorGUILayout.PropertyField(_hotUpdateAssemblies); + EditorGUILayout.PropertyField(_preserveHotUpdateAssemblies); + EditorGUILayout.PropertyField(_hotUpdateDllCompileOutputRootDir); + EditorGUILayout.PropertyField(_externalHotUpdateAssemblyDirs); + EditorGUILayout.PropertyField(_strippedAOTDllOutputRootDir); + EditorGUILayout.PropertyField(_patchAOTAssemblies); + EditorGUILayout.PropertyField(_outputLinkFile); + EditorGUILayout.PropertyField(_outputAOTGenericReferenceFile); + EditorGUILayout.PropertyField(_maxGenericReferenceIteration); + EditorGUILayout.PropertyField(_maxMethodBridgeGenericIteration); + if (EditorGUI.EndChangeCheck()) + { + _serializedObject.ApplyModifiedProperties(); + HybridCLRSettings.Save(); } } - private IDisposable CreateSettingsWindowGUIScope() - { - var unityEditorAssembly = Assembly.GetAssembly(typeof(EditorWindow)); - var type = unityEditorAssembly.GetType("UnityEditor.SettingsWindow+GUIScope"); - return Activator.CreateInstance(type) as IDisposable; - } + public override void OnDeactivate() { base.OnDeactivate(); - EditorStatusWatcher.OnEditorFocused -= OnEditorFocused; HybridCLRSettings.Save(); } - static HybridCLRSettingsProvider provider; + static HybridCLRSettingsProvider s_provider; + [SettingsProvider] public static SettingsProvider CreateMyCustomSettingsProvider() { - if (HybridCLRSettings.Instance && provider == null) + if (s_provider == null) { - provider = new HybridCLRSettingsProvider(); - using (var so = new SerializedObject(HybridCLRSettings.Instance)) - { - provider.keywords = GetSearchKeywordsFromSerializedObject(so); - } + s_provider = new HybridCLRSettingsProvider(); } - return provider; + return s_provider; } } } \ No newline at end of file diff --git a/Editor/Settings/HybridCLRSettings.cs b/Editor/Settings/HybridCLRSettings.cs index b6ce977..f577a95 100644 --- a/Editor/Settings/HybridCLRSettings.cs +++ b/Editor/Settings/HybridCLRSettings.cs @@ -1,10 +1,11 @@ +using System.IO; using UnityEditorInternal; using UnityEngine; namespace HybridCLR.Editor.Settings { - [FilePath("ProjectSettings/HybridCLRSettings.asset")] - public class HybridCLRSettings : ScriptableSingleton + + public class HybridCLRSettings : ScriptableObject { [Tooltip("enable HybridCLR")] public bool enable = true; @@ -50,5 +51,48 @@ namespace HybridCLR.Editor.Settings [Tooltip("max iteration count of searching method bridge generic methods in AOT assemblies")] public int maxMethodBridgeGenericIteration = 10; + + + + private static HybridCLRSettings s_Instance; + + public static HybridCLRSettings Instance + { + get + { + if (!s_Instance) + { + LoadOrCreate(); + } + return s_Instance; + } + } + + private static string GetFilePath() + { + return "ProjectSettings/HybridCLRSettings.asset"; + } + + public static HybridCLRSettings LoadOrCreate() + { + string filePath = GetFilePath(); + Object[] objs = InternalEditorUtility.LoadSerializedFileAndForget(filePath); + s_Instance = objs.Length > 0 ? (HybridCLRSettings)objs[0] : (s_Instance ?? CreateInstance()); + return s_Instance; + } + + public static void Save() + { + if (!s_Instance) + { + return; + } + + string filePath = GetFilePath(); + string directoryName = Path.GetDirectoryName(filePath); + Directory.CreateDirectory(directoryName); + var obj = new Object[1] { s_Instance }; + InternalEditorUtility.SaveToSerializedFileAndForget(obj, filePath, true); + } } } diff --git a/Editor/Settings/ScriptableSignleton.cs b/Editor/Settings/ScriptableSignleton.cs deleted file mode 100644 index 903f802..0000000 --- a/Editor/Settings/ScriptableSignleton.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using UnityEditor; -using UnityEditorInternal; -using UnityEngine; - -namespace HybridCLR.Editor.Settings -{ - public class ScriptableSingleton : ScriptableObject where T : ScriptableObject - { - private static T s_Instance; - public static T Instance - { - get - { - if (!s_Instance) - { - LoadOrCreate(); - } - return s_Instance; - } - } - public static T LoadOrCreate() - { - string filePath = GetFilePath(); - if (!string.IsNullOrEmpty(filePath)) - { - var arr = InternalEditorUtility.LoadSerializedFileAndForget(filePath); - s_Instance = arr.Length > 0 ? arr[0] as T : s_Instance??CreateInstance(); - } - else - { - Debug.LogError($"save location of {nameof(ScriptableSingleton)} is invalid"); - } - return s_Instance; - } - - public static void Save(bool saveAsText = true) - { - if (!s_Instance) - { - Debug.LogError("Cannot save ScriptableSingleton: no instance!"); - return; - } - - string filePath = GetFilePath(); - if (!string.IsNullOrEmpty(filePath)) - { - string directoryName = Path.GetDirectoryName(filePath); - if (!Directory.Exists(directoryName)) - { - Directory.CreateDirectory(directoryName); - } - UnityEngine.Object[] obj = new T[1] { s_Instance }; - InternalEditorUtility.SaveToSerializedFileAndForget(obj, filePath, saveAsText); - } - } - protected static string GetFilePath() - { - return typeof(T).GetCustomAttributes(inherit: true) - .Where(v => v is FilePathAttribute) - .Cast() - .FirstOrDefault() - ?.filepath; - } - } - [AttributeUsage(AttributeTargets.Class)] - public class FilePathAttribute : Attribute - { - internal string filepath; - /// - /// 单例存放路径 - /// - /// 相对 Project 路径 - public FilePathAttribute(string path) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentException("Invalid relative path (it is empty)"); - } - if (path[0] == '/') - { - path = path.Substring(1); - } - filepath = path; - } - } -} \ No newline at end of file diff --git a/Editor/Settings/ScriptableSignleton.cs.meta b/Editor/Settings/ScriptableSignleton.cs.meta deleted file mode 100644 index fa1923b..0000000 --- a/Editor/Settings/ScriptableSignleton.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 851c44a8da67a9742a7ea68815383f27 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Settings/SettingsPresetReceiver.cs b/Editor/Settings/SettingsPresetReceiver.cs deleted file mode 100644 index e60f3aa..0000000 --- a/Editor/Settings/SettingsPresetReceiver.cs +++ /dev/null @@ -1,39 +0,0 @@ -using UnityEditor; -using UnityEditor.Presets; -using UnityEngine; - -namespace HybridCLR.Editor.Settings -{ - public class SettingsPresetReceiver : PresetSelectorReceiver - { - private Object m_Target; - private Preset m_InitialValue; - private SettingsProvider m_Provider; - - internal void Init(Object target, SettingsProvider provider) - { - m_Target = target; - m_InitialValue = new Preset(target); - m_Provider = provider; - } - public override void OnSelectionChanged(Preset selection) - { - if (selection != null) - { - Undo.RecordObject(m_Target, "Apply Preset " + selection.name); - selection.ApplyTo(m_Target); - } - else - { - Undo.RecordObject(m_Target, "Cancel Preset"); - m_InitialValue.ApplyTo(m_Target); - } - m_Provider.Repaint(); - } - public override void OnSelectionClosed(Preset selection) - { - OnSelectionChanged(selection); - Object.DestroyImmediate(this); - } - } -} \ No newline at end of file diff --git a/Editor/Settings/SettingsPresetReceiver.cs.meta b/Editor/Settings/SettingsPresetReceiver.cs.meta deleted file mode 100644 index 5047283..0000000 --- a/Editor/Settings/SettingsPresetReceiver.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d8373e0cb30c4894db7cd4d0b77a7a48 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: