You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
447 lines
12 KiB
C#
447 lines
12 KiB
C#
/******************************************************************************/
|
|
/*
|
|
Project - MudBun
|
|
Publisher - Long Bunny Labs
|
|
http://LongBunnyLabs.com
|
|
Author - Ming-Lun "Allen" Chou
|
|
http://AllenChou.net
|
|
*/
|
|
/******************************************************************************/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
using UnityEditor;
|
|
|
|
using UnityEngine;
|
|
|
|
namespace MudBun
|
|
{
|
|
public class ProjectPrefs : ScriptableObject
|
|
{
|
|
private static readonly string InstancePath = "Assets/MudBun/ProjectPrefs.asset";
|
|
|
|
[Serializable]
|
|
public class Record
|
|
{
|
|
public enum TypeEnum
|
|
{
|
|
Bool,
|
|
Int,
|
|
Float,
|
|
String,
|
|
Set,
|
|
}
|
|
|
|
public string Key = "";
|
|
public TypeEnum Type = TypeEnum.Bool;
|
|
public string Value = "";
|
|
|
|
public void Sort()
|
|
{
|
|
if (Type != TypeEnum.Set)
|
|
return;
|
|
|
|
var set = StringToSet(Value);
|
|
set = set.OrderBy(x => x).ToArray();
|
|
Value = SetToString(set);
|
|
}
|
|
}
|
|
|
|
[SerializeField] private List<Record> m_records = new List<Record>();
|
|
public List<Record> Records => m_records;
|
|
|
|
[SerializeField] private string m_version = "";
|
|
public string Version => m_version;
|
|
|
|
internal static void Init()
|
|
{
|
|
// poke
|
|
var instance = Instance;
|
|
//Debug.Log("MudBun: Project prefs version " + MudBun.Version);
|
|
}
|
|
|
|
private static ProjectPrefs Instance
|
|
{
|
|
get
|
|
{
|
|
var instance = AssetDatabase.LoadAssetAtPath<ProjectPrefs>(InstancePath);
|
|
if (instance != null
|
|
&& instance.m_version != MudBun.Version)
|
|
{
|
|
#if !MUDBUN_DEV
|
|
Debug.Log($"MudBun: Detected previous different version ({instance.m_version}); resettings compatibility records.");
|
|
//Debug.Log($"MudBun: New project prefs created for version {MudBun.Version}.");
|
|
CompatibilityManager.Reset();
|
|
#endif
|
|
instance.m_version = MudBun.Version;
|
|
}
|
|
|
|
if (instance == null)
|
|
{
|
|
instance = CreateInstance<ProjectPrefs>();
|
|
instance.m_version = MudBun.Version;
|
|
AssetDatabase.CreateAsset(instance, InstancePath);
|
|
AssetDatabase.Refresh();
|
|
|
|
instance = AssetDatabase.LoadAssetAtPath<ProjectPrefs>(InstancePath);
|
|
Assert.Unequal(instance, null);
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
}
|
|
|
|
private static string[] StringToSet(string value)
|
|
{
|
|
return value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
|
}
|
|
|
|
private static string SetToString(string[] set)
|
|
{
|
|
return string.Join(";", set);
|
|
}
|
|
|
|
private static string AddToSetString(string setStr, string value)
|
|
{
|
|
var set = StringToSet(setStr);
|
|
if (set.Contains(value))
|
|
return setStr;
|
|
|
|
set = set.Append(value).ToArray();
|
|
return SetToString(set);
|
|
}
|
|
|
|
private static string RemoveFromSetString(string setStr, string value)
|
|
{
|
|
var set = StringToSet(setStr);
|
|
set = set.Where(x => x != value).ToArray();
|
|
return SetToString(set);
|
|
}
|
|
|
|
public static bool GetRecord(string key, out Record record)
|
|
{
|
|
var list = Instance.Records.FindAll(x => x.Key.Equals(key));
|
|
if (list == null || list.Count == 0)
|
|
{
|
|
record = null;
|
|
return false;
|
|
}
|
|
|
|
record = list.First();
|
|
return true;
|
|
}
|
|
|
|
public static void SetRecord(string key, Record record)
|
|
{
|
|
if (GetRecord(key, out Record existingRecord))
|
|
{
|
|
if (existingRecord.Type == record.Type
|
|
&& existingRecord.Value.Equals(record.Value))
|
|
return;
|
|
|
|
existingRecord.Type = record.Type;
|
|
existingRecord.Value = record.Value;
|
|
}
|
|
else
|
|
{
|
|
record.Key = key;
|
|
Instance.Records.Add(record);
|
|
}
|
|
|
|
EditorUtility.SetDirty(Instance);
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
|
|
public static bool HasKey(string key)
|
|
{
|
|
return Instance.Records.Any(x => x.Key.Equals(key));
|
|
}
|
|
|
|
public static void DeleteKey(string key)
|
|
{
|
|
Instance.Records.RemoveAll(x => x.Key.Equals(key));
|
|
}
|
|
|
|
public static bool GetBool(string key, bool defaultValue)
|
|
{
|
|
if (!GetRecord(key, out Record record))
|
|
return defaultValue;
|
|
|
|
Assert.Equal(record.Type, Record.TypeEnum.Bool);
|
|
|
|
if (!bool.TryParse(record.Value, out bool result))
|
|
{
|
|
Debug.LogWarning($"MudBun ProjectPrefs: Cannot parse string \"{record.Value}\" into bool for project preference \"{record.Key}\".");
|
|
return defaultValue;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static void SetBool(string key, bool value)
|
|
{
|
|
SetRecord(key, new Record() { Type = Record.TypeEnum.Bool, Value = value.ToString() });
|
|
}
|
|
|
|
public static int GetInt(string key, int defaultValue)
|
|
{
|
|
if (!GetRecord(key, out Record record))
|
|
return defaultValue;
|
|
|
|
Assert.Equal(record.Type, Record.TypeEnum.Int);
|
|
|
|
if (!int.TryParse(record.Value, out int result))
|
|
{
|
|
Debug.LogWarning($"MudBun ProjectPrefs: Cannot parse string \"{record.Value}\" into int for project preference \"{record.Key}\".");
|
|
return defaultValue;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static void SetInt(string key, int value)
|
|
{
|
|
SetRecord(key, new Record() { Type = Record.TypeEnum.Int, Value = value.ToString() });
|
|
}
|
|
|
|
public static float GetFloat(string key, float defaultValue)
|
|
{
|
|
if (!GetRecord(key, out Record record))
|
|
return defaultValue;
|
|
|
|
Assert.Equal(record.Type, Record.TypeEnum.Float);
|
|
|
|
if (!float.TryParse(record.Value, out float result))
|
|
{
|
|
Debug.LogWarning($"MudBun ProjectPrefs: Cannot parse string \"{record.Value}\" into float for project preference \"{record.Key}\".");
|
|
return defaultValue;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static void SetFloat(string key, float value)
|
|
{
|
|
SetRecord(key, new Record() { Type = Record.TypeEnum.Float, Value = value.ToString() });
|
|
}
|
|
|
|
public static string GetString(string key, string defaultValue)
|
|
{
|
|
if (!GetRecord(key, out Record record))
|
|
return defaultValue;
|
|
|
|
Assert.Equal(record.Type, Record.TypeEnum.String);
|
|
|
|
return record.Value;
|
|
}
|
|
|
|
public static void SetString(string key, string value)
|
|
{
|
|
SetRecord(key, new Record() { Type = Record.TypeEnum.String, Value = value });
|
|
}
|
|
|
|
public static string[] GetSet(string key, string[] defaultValue)
|
|
{
|
|
if (!GetRecord(key, out Record record))
|
|
return defaultValue;
|
|
|
|
Assert.Equal(record.Type, Record.TypeEnum.Set);
|
|
|
|
return record.Value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
|
}
|
|
|
|
public static bool SetContains(string key, string value)
|
|
{
|
|
var set = GetSet(key, null);
|
|
if (set == null)
|
|
return false;
|
|
|
|
return set.Contains(value);
|
|
}
|
|
|
|
public static void AddToSet(string key, string value)
|
|
{
|
|
if (!GetRecord(key, out Record record))
|
|
{
|
|
SetRecord(key, new Record() { Type = Record.TypeEnum.Set, Value = value });
|
|
return;
|
|
}
|
|
|
|
Assert.Equal(record.Type, Record.TypeEnum.Set);
|
|
|
|
record.Value = AddToSetString(record.Value, value);
|
|
}
|
|
|
|
public static void RemoveFromSet(string key, string value)
|
|
{
|
|
if (!GetRecord(key, out Record record))
|
|
return;
|
|
|
|
Assert.Equal(record.Type, Record.TypeEnum.Set);
|
|
|
|
record.Value = RemoveFromSetString(record.Value, value);
|
|
}
|
|
}
|
|
|
|
[CustomEditor(typeof(ProjectPrefs))]
|
|
public class ProjectPrefsEditor : MudEditorBase
|
|
{
|
|
private static readonly int TypeWidth = 80;
|
|
private static readonly int SmallButtonWidth = 24;
|
|
private static readonly int SortButtonWidth = 80;
|
|
|
|
private static readonly float SaveDelay = 2.0f;
|
|
private float m_lastDirtyTime = -1.0f;
|
|
|
|
private void MarkDirty()
|
|
{
|
|
EditorUtility.SetDirty(serializedObject.targetObject);
|
|
m_lastDirtyTime = Time.realtimeSinceStartup;
|
|
}
|
|
|
|
private void Save()
|
|
{
|
|
AssetDatabase.SaveAssets();
|
|
m_lastDirtyTime = -1.0f;
|
|
}
|
|
|
|
private void TrySave()
|
|
{
|
|
if (m_lastDirtyTime < 0.0f)
|
|
return;
|
|
|
|
if (Time.realtimeSinceStartup - m_lastDirtyTime < SaveDelay)
|
|
return;
|
|
|
|
Save();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
EditorApplication.update += TrySave;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
EditorApplication.update -= TrySave;
|
|
Save();
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
|
|
var prefs = (ProjectPrefs) serializedObject.targetObject;
|
|
var records = prefs.Records;
|
|
|
|
if (records == null)
|
|
return;
|
|
|
|
Undo.RecordObject(prefs, "Modify ProjectPrefs");
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
ProjectPrefs.Record recordToMoveUp = null;
|
|
ProjectPrefs.Record recordToMoveDown = null;
|
|
ProjectPrefs.Record recordToDelete = null;
|
|
foreach (var record in records)
|
|
{
|
|
EditorGUILayout.BeginHorizontal();
|
|
record.Key = EditorGUILayout.TextField(record.Key);
|
|
if (GUILayout.Button("↑", GUILayout.Width(SmallButtonWidth)))
|
|
recordToMoveUp = record;
|
|
if (GUILayout.Button("↓", GUILayout.Width(SmallButtonWidth)))
|
|
recordToMoveDown = record;
|
|
if (GUILayout.Button("-", GUILayout.Width(SmallButtonWidth)))
|
|
recordToDelete = record;
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
EditorGUILayout.BeginHorizontal();
|
|
record.Type = (ProjectPrefs.Record.TypeEnum) Convert.ToInt32(EditorGUILayout.EnumPopup(record.Type, GUILayout.MinWidth(TypeWidth), GUILayout.MaxWidth(TypeWidth)));
|
|
switch (record.Type)
|
|
{
|
|
case ProjectPrefs.Record.TypeEnum.Bool:
|
|
bool boolValue;
|
|
if (!bool.TryParse(record.Value, out boolValue))
|
|
boolValue = false;
|
|
record.Value = EditorGUILayout.Toggle(boolValue).ToString();
|
|
break;
|
|
case ProjectPrefs.Record.TypeEnum.Int:
|
|
int intValue;
|
|
if (!int.TryParse(record.Value, out intValue))
|
|
intValue = 0;
|
|
record.Value = EditorGUILayout.IntField(intValue).ToString();
|
|
break;
|
|
case ProjectPrefs.Record.TypeEnum.Float:
|
|
float floatValue;
|
|
if (!float.TryParse(record.Value, out floatValue))
|
|
floatValue = 0.0f;
|
|
record.Value = EditorGUILayout.FloatField(floatValue).ToString();
|
|
break;
|
|
case ProjectPrefs.Record.TypeEnum.Set:
|
|
case ProjectPrefs.Record.TypeEnum.String:
|
|
record.Value = EditorGUILayout.TextField(record.Value);
|
|
break;
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
EditorGUILayout.Space();
|
|
}
|
|
|
|
if (recordToMoveUp != null)
|
|
{
|
|
int i = records.FindIndex(x => x == recordToMoveUp);
|
|
if (i > 0)
|
|
{
|
|
var recordToSwap = records[i - 1];
|
|
records[i - 1] = recordToMoveUp;
|
|
records[i] = recordToSwap;
|
|
}
|
|
}
|
|
|
|
if (recordToMoveDown != null)
|
|
{
|
|
int i = records.FindIndex(x => x == recordToMoveDown);
|
|
if (i >= 0 && i < records.Count - 1)
|
|
{
|
|
var recordToSwap = records[i + 1];
|
|
records[i + 1] = recordToMoveDown;
|
|
records[i] = recordToSwap;
|
|
}
|
|
}
|
|
|
|
if (recordToDelete != null)
|
|
records.Remove(recordToDelete);
|
|
|
|
GUILayout.Label($"Version: {prefs.Version}");
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.FlexibleSpace();
|
|
if (GUILayout.Button("Sort", GUILayout.Width(SortButtonWidth)))
|
|
{
|
|
records.Sort((a, b) => a.Key.CompareTo(b.Key));
|
|
records.ForEach(x => x.Sort());
|
|
}
|
|
if (GUILayout.Button("+", GUILayout.Width(SmallButtonWidth)))
|
|
{
|
|
string newRecordKey = "NewRecord";
|
|
while (records.Any(x => x.Key.Equals(newRecordKey)))
|
|
newRecordKey += "+";
|
|
records.Add(new ProjectPrefs.Record() { Key = newRecordKey });
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
serializedObject.Update();
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
MarkDirty();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|