[refactor] refactor code of settings.
parent
46f308ed5e
commit
361873803f
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 093a9e6c1e7399244bbcd8983fdbfdee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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,72 +54,10 @@ 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<SettingsPresetReceiver>();
|
||||
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<HybridCLRSettings>();
|
||||
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();
|
||||
}
|
||||
|
|
@ -133,7 +71,7 @@ namespace HybridCLR.Editor.Settings
|
|||
EditorGUILayout.PropertyField(_hotUpdateAssemblies);
|
||||
EditorGUILayout.PropertyField(_preserveHotUpdateAssemblies);
|
||||
EditorGUILayout.PropertyField(_hotUpdateDllCompileOutputRootDir);
|
||||
EditorGUILayout.PropertyField(_externalHotUpdateAssembliyDirs);
|
||||
EditorGUILayout.PropertyField(_externalHotUpdateAssemblyDirs);
|
||||
EditorGUILayout.PropertyField(_strippedAOTDllOutputRootDir);
|
||||
EditorGUILayout.PropertyField(_patchAOTAssemblies);
|
||||
EditorGUILayout.PropertyField(_outputLinkFile);
|
||||
|
|
@ -146,33 +84,23 @@ namespace HybridCLR.Editor.Settings
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
using System.IO;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HybridCLR.Editor.Settings
|
||||
{
|
||||
[FilePath("ProjectSettings/HybridCLRSettings.asset")]
|
||||
public class HybridCLRSettings : ScriptableSingleton<HybridCLRSettings>
|
||||
|
||||
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<HybridCLRSettings>());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<T> : 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<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"save location of {nameof(ScriptableSingleton<T>)} 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<FilePathAttribute>()
|
||||
.FirstOrDefault()
|
||||
?.filepath;
|
||||
}
|
||||
}
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class FilePathAttribute : Attribute
|
||||
{
|
||||
internal string filepath;
|
||||
/// <summary>
|
||||
/// 单例存放路径
|
||||
/// </summary>
|
||||
/// <param name="path">相对 Project 路径</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 851c44a8da67a9742a7ea68815383f27
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d8373e0cb30c4894db7cd4d0b77a7a48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in New Issue