| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- 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;
- }
- }
- }
|