Skip to content

Instantly share code, notes, and snippets.

@pinkas
Last active July 4, 2021 17:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pinkas/5379998d1c44784891e3064859039007 to your computer and use it in GitHub Desktop.
Save pinkas/5379998d1c44784891e3064859039007 to your computer and use it in GitHub Desktop.
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor;
public class DbBrowser : OdinMenuEditorWindow
{
[MenuItem("Db/Browser")]
public static void Open()
{
EditorWindow window = GetWindow<DbBrowser>();
window.position = GUIHelper.GetEditorWindowRect().AlignCenter(800, 500);
}
OdinMenuTree tree = null;
const string treeRoot = "";
protected override OdinMenuTree BuildMenuTree()
{
tree = new OdinMenuTree(true);
tree.Config.DrawSearchToolbar = true;
tree.Add("PersonTable", DbList<Person>.Load());
foreach(Person person in DbList<Person>.Instance.value)
{
if (person.nickName == string.Empty)
{
continue;
}
tree.Add("PersonTable/" + person.nickName, person);
}
return tree;
}
}
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEditor;
[Serializable]
public class DbItem
{
//TODO add validation
[ReadOnly, SerializeField, TableColumnWidth(10), Required]
protected int uid;
public int Uid => uid;
[Required("No pretty name means not easily accessible via code", InfoMessageType.Warning)]
[DelayedProperty, OnValueChanged("OnPrettyNameChanged")]
public string prettyName;
public void SetUid(int uid)
{
if (this.uid == 0)
{
this.uid = uid;
}
}
private void OnPrettyNameChanged(string prettyName)
{
Debug.Log( this.GetType().Name );
}
}
[Serializable, InlineProperty, HideReferenceObjectPicker]
public class DbItemReference<T> where T : DbItem
{
[HorizontalGroup("1")]
[VerticalGroup("1/2")]
[Button(18)]
public void Pick()
{
GenericSelector<T> selector = new GenericSelector<T>("",
false, item => item.prettyName, DbList<T>.Instance.rows);
var window = selector.ShowInPopup();
selector.SelectionConfirmed += selection => this.uid = selection.FirstOrDefault().Uid;
selector.SelectionChanged += OnBlah;
selector.EnableSingleClickToSelect();
// window.OnClose += selector.SelectionTree.Selection.ConfirmSelection;
}
[VerticalGroup("1/2")]
[Button(18)]
public void Select()
{
Debug.LogError("TODO");
}
private void OnBlah(IEnumerable<T> a)
{
UnityEngine.Debug.Log("Selection changed");
}
[VerticalGroup("1/1")]
[SerializeField, ReadOnly]
private int uid;
[VerticalGroup("1/1")]
[ShowInInspector, ReadOnly]
//TODO really not performance friendly
private string prettyName { get {
return DbList<T>.Instance.rows.FirstOrDefault(p => p.Uid == uid).prettyName;
} }
public T Get => DbList<T>.Instance.rows.FirstOrDefault(p => p.Uid == uid);
}
[Serializable, InlineProperty, HideReferenceObjectPicker, HideDuplicateReferenceBox]
public class DbList <T> where T : DbItem
{
protected DbList()
{
rows = new List<T>();
}
public static DbList<T> Instance
{
get
{
if (instance == null)
{
instance = Load();
}
return instance;
}
}
static DbList<T> instance;
[ListDrawerSettings(CustomAddFunction = nameof(OnRowAdded))]
public List<T> rows = new List<T>();
public static string FilePath => Path.Combine(Directory.GetCurrentDirectory(), "Assets", typeof(T).ToString() + "_table.txt");
public static string KeysPath => Path.Combine(Directory.GetCurrentDirectory(), "Assets", typeof(T).ToString() + "_keys.cs");
public static DbList<T> Load()
{
if (instance != null)
{
return instance;
}
#if UNITY_EDITOR
AssemblyReloadEvents.beforeAssemblyReload += SaveAndExport;
#endif
Debug.Log("loading " + typeof(T).ToString() + " table");
if (!File.Exists(FilePath))
{
var stream = File.Create(FilePath);
stream.Dispose();
}
string serializedList = File.ReadAllText(FilePath);
instance = JsonUtility.FromJson<DbList<T>>(serializedList) ?? new DbList<T>();
return instance;
}
public static void Unload()
{
Debug.Log($"Unloading {typeof(T).ToString()} table");
instance = null;
}
public int NextId => nextId;
[SerializeField, ReadOnly]
private int nextId;
#if UNITY_EDITOR
private void OnRowAdded()
{
//T member = (T) Activator.CreateInstance(typeof(T), nextId);
T member = (T) Activator.CreateInstance(typeof(T));
member.SetUid(nextId);
rows.Add(member);
nextId++;
File.WriteAllText(FilePath, JsonUtility.ToJson(this, true));
}
[Button]
public static void SaveToDisk()
{
string serializedDb = JsonUtility.ToJson(instance, true);
File.WriteAllText(DbList<Person>.FilePath, serializedDb);
}
[Button]
public static void SaveAndExport()
{
SaveToDisk();
string className = typeof(T).ToString();
string classFile = "using System.Linq;\n";
classFile += $"public class {className}Table : DbList<{className}>\n";
classFile += "{\n";
foreach(DbItem item in instance.rows)
{
if ( string.IsNullOrEmpty(item.prettyName))
{
continue;
}
classFile += $"public static {className} {item.prettyName} => DbList<{className}>.{nameof(Instance)}.{nameof(rows)}.SingleOrDefault(p => p.prettyName == \"{item.prettyName}\");\n";
}
classFile += "}\n";
File.WriteAllText(DbList<Person>.KeysPath, classFile);
AssetDatabase.ImportAsset("Assets/" + typeof(T).ToString() + "_keys.cs");
Debug.Log(classFile);
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment