Skip to content
This repository was archived by the owner on Aug 15, 2024. It is now read-only.

Commit 8baf846

Browse files
committed
feat: link to datanodes runtime serialization
1 parent 99ee6d5 commit 8baf846

File tree

6 files changed

+119
-25
lines changed

6 files changed

+119
-25
lines changed

Packages/com.nuclearband.sodatabase/Editor/ScriptableObjectDatabaseEditorWindow.cs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Linq;
77
using System.Reflection;
88
using Newtonsoft.Json;
9-
using Newtonsoft.Json.Serialization;
109
using Sirenix.OdinInspector.Editor;
1110
using Sirenix.Utilities;
1211
using Sirenix.Utilities.Editor;
@@ -24,11 +23,6 @@ private static void Open()
2423
{
2524
var window = GetWindow<ScriptableObjectDatabaseEditorWindow>();
2625
window.position = GUIHelper.GetEditorWindowRect().AlignCenter(800, 500);
27-
window.OnClose += () =>
28-
{
29-
AssetDatabase.SaveAssets();
30-
AssetDatabase.Refresh();
31-
};
3226
}
3327

3428
[MenuItem("Tools/NuclearBand/ScriptableObjectDatabase-ClearSave")]
@@ -51,15 +45,39 @@ private static async void ClearSave()
5145

5246
EditorUtility.SetDirty(model);
5347
}
48+
5449
AssetDatabase.SaveAssets();
5550
}
56-
51+
5752
[MenuItem("Tools/NuclearBand/ScriptableObjectDatabase-OpenSaveFolder")]
5853
private static void OpenSaveFolder()
5954
{
6055
EditorUtility.RevealInFinder(Application.persistentDataPath);
6156
}
6257

58+
[InitializeOnEnterPlayMode]
59+
private static async void ResetOnPlay()
60+
{
61+
await SODatabase.InitAsync(null, null);
62+
await SODatabase.LoadAsync();
63+
var models = SODatabase.GetModels<DataNode>("", true);
64+
foreach (var model in models)
65+
{
66+
var typeInfo = model.GetType().GetTypeInfo();
67+
var fields = typeInfo.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
68+
foreach (var field in fields)
69+
{
70+
var attributes = field.GetCustomAttributes(typeof(ResetOnPlay), false);
71+
if (attributes.Length > 0)
72+
field.SetValue(model, default);
73+
}
74+
75+
EditorUtility.SetDirty(model);
76+
}
77+
78+
AssetDatabase.SaveAssets();
79+
}
80+
6381
protected override OdinMenuTree BuildMenuTree()
6482
{
6583
var tree = new OdinMenuTree(true)
@@ -98,7 +116,7 @@ private void SelectionChanged(SelectionChangedType obj)
98116
throw new ArgumentOutOfRangeException(nameof(obj), obj, null);
99117
}
100118
}
101-
119+
102120
void AddAllAssetsAtPath(
103121
OdinMenuTree tree,
104122
string assetFolderPath,
@@ -217,14 +235,45 @@ protected override void OnBeginDrawEditors()
217235
AssetDatabase.CreateFolder(path, uniqName);
218236
AssetDatabase.Refresh();
219237
}
238+
239+
if (SirenixEditorGUI.ToolbarButton(new GUIContent("Save")))
240+
Save();
220241
}
221242
SirenixEditorGUI.EndHorizontalToolbar();
222243
}
223244

245+
private void Save()
246+
{
247+
Flatten(MenuTree.MenuItems).ForEach(item =>
248+
{
249+
if (!(item.Value is DataNodeHolder dataNodeHolder))
250+
return;
251+
var fullPath = $"{(string.IsNullOrEmpty(dataNodeHolder.Path) ? string.Empty : $"{dataNodeHolder.Path}/")}{dataNodeHolder.DataNode.name}";
252+
if (dataNodeHolder.DataNode.FullPath == fullPath)
253+
return;
254+
dataNodeHolder.DataNode.SetFullPath(dataNodeHolder.Path);
255+
EditorUtility.SetDirty(dataNodeHolder.DataNode);
256+
});
257+
258+
AssetDatabase.SaveAssets();
259+
AssetDatabase.Refresh();
260+
}
261+
262+
static IEnumerable<OdinMenuItem> Flatten(List<OdinMenuItem> collection)
263+
{
264+
foreach (var o in collection)
265+
{
266+
foreach (var o1 in Flatten(o.ChildMenuItems))
267+
yield return o1;
268+
269+
yield return o;
270+
}
271+
}
272+
224273
private void AddDragHandles(OdinMenuItem menuItem)
225274
{
226275
menuItem.OnDrawItem += x => DragAndDropUtilities.DragZone(menuItem.Rect, (menuItem.Value as DataNodeHolder)!.DataNode, false, false);
227276
}
228277
}
229278
}
230-
#endif
279+
#endif
Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
#nullable enable
2-
using System.Reflection;
32
using Newtonsoft.Json;
43
using Sirenix.OdinInspector;
4+
using UnityEngine;
55

66
namespace NuclearBand
77
{
8-
[JsonObject(MemberSerialization.OptIn)]
8+
[JsonObject(MemberSerialization.OptIn, IsReference = true)]
99
public class DataNode : SerializedScriptableObject
1010
{
11-
protected virtual void OnEnable()
12-
{
13-
var typeInfo = GetType().GetTypeInfo();
14-
var fields = typeInfo.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
15-
foreach (var field in fields)
16-
{
17-
var attributes = field.GetCustomAttributes(typeof(ResetOnPlay), false);
18-
if (attributes.Length > 0)
19-
field.SetValue(this, default);
20-
}
21-
}
11+
[SerializeField, HideInInspector]
12+
private string fullPath = string.Empty;
13+
14+
public string FullPath => $"{(string.IsNullOrEmpty(fullPath) ? string.Empty : $"{fullPath}/")}{name}";
15+
16+
#if UNITY_EDITOR
17+
public void SetFullPath(string fullPath) => this.fullPath = fullPath;
18+
#endif
2219
}
23-
}
20+
}

Packages/com.nuclearband.sodatabase/Runtime/SODatabase.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ public static class SODatabase
1717

1818
private static FolderHolder root = null!;
1919

20+
private static JsonSerializerSettings jsonSerializerSettings => new JsonSerializerSettings
21+
{
22+
Formatting = Formatting.None,
23+
ReferenceResolverProvider = () => new DataNodeReferenceResolver()
24+
};
25+
2026
public static async void Init(Action<float>? onProgress, Action? onComplete)
2127
{
2228
await InitAsync(onProgress, onComplete);
@@ -127,7 +133,8 @@ static Dictionary<string, string> SaveFolderHolder(FolderHolder folderHolder, st
127133
var fullPath = dataNodePair.Key;
128134
if (!string.IsNullOrEmpty(path))
129135
fullPath = path + '/' + fullPath;
130-
var json = JsonConvert.SerializeObject(dataNodePair.Value);
136+
DataNodeReferenceResolver.CurrentDataNode = dataNodePair.Value;
137+
var json = JsonConvert.SerializeObject(dataNodePair.Value, jsonSerializerSettings);
131138
res.Add(fullPath, json);
132139
}
133140

@@ -136,6 +143,7 @@ static Dictionary<string, string> SaveFolderHolder(FolderHolder folderHolder, st
136143
var fullPath = folderHolderPair.Key;
137144
if (!string.IsNullOrEmpty(path))
138145
fullPath = path + '/' + fullPath;
146+
139147
var resAdd = SaveFolderHolder(folderHolderPair.Value, fullPath);
140148
resAdd.ForEach(x => res.Add(x.Key, x.Value));
141149
}
@@ -170,7 +178,8 @@ static void LoadFolderHolder(FolderHolder folderHolder, string path, Dictionary<
170178
var json = data.ContainsKey(fullPath) ? data[fullPath] : string.Empty;
171179
if (string.IsNullOrEmpty(json))
172180
continue;
173-
JsonConvert.PopulateObject(json, dataNodePair.Value);
181+
DataNodeReferenceResolver.CurrentDataNode = dataNodePair.Value;
182+
JsonConvert.PopulateObject(json, dataNodePair.Value, jsonSerializerSettings);
174183
}
175184

176185
foreach (var folderHolderPair in folderHolder.FolderHolders)

Packages/com.nuclearband.sodatabase/Runtime/SerializationUtilities.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#nullable enable
2+
using System;
3+
using Newtonsoft.Json.Serialization;
4+
using NuclearBand;
5+
6+
public class DataNodeReferenceResolver : IReferenceResolver
7+
{
8+
public static DataNode CurrentDataNode = null!;
9+
10+
public object ResolveReference(object context, string reference)
11+
{
12+
try
13+
{
14+
return SODatabase.GetModel<DataNode>(reference);
15+
}
16+
catch (Exception)
17+
{
18+
return null;
19+
}
20+
}
21+
22+
public string GetReference(object context, object value)
23+
{
24+
var dataNode = (DataNode) value;
25+
return dataNode.FullPath;
26+
}
27+
28+
public bool IsReferenced(object context, object value) => !ReferenceEquals(value, CurrentDataNode);
29+
30+
public void AddReference(object context, string reference, object value)
31+
{
32+
}
33+
}

Packages/com.nuclearband.sodatabase/Runtime/SerializationUtilities/DataNodeReferenceResolver.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)