12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- 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)
- .Cast<FilePathAttribute>()
- .FirstOrDefault(v => v != null)
- ?.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;
- }
- }
- }
|