Skip to content

Commit 2124c5c

Browse files
authored
Merge pull request #69 from brunomikoski/feature/setttings-revamp
Feature/setttings revamp
2 parents 1443813 + 9e7f1fa commit 2124c5c

17 files changed

Lines changed: 406 additions & 432 deletions

CHANGELOG.MD

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [1.5.4]
8+
### Changed
9+
- Removed the automatically reload of CollectionRegistry using the `DidReloadScripts` callback, this caused multiple issues on batch mode and on clear libraries
10+
- Converted the `Collection` reference on the `CollectionItem` to be a Lazy reference, since this was causing some dependency when using `CollectionItem` as addressables
11+
- Refactored the `ScriptableObjectSettings` this used to be a Resources object that was auto loaded, but this could also create unwanted dependencies between items. The settings for code generated are not stored inside the Collection itself. Make sure you delete the `ScriptableObjectsSettings` ScriptableObject inside your resources folder.
12+
- Added a bunch of validation and verification for the Generation of the static access, making sure it only allows partial classes when is possible and other small checks.
13+
- The settings are now on the Project Preferences where you can define the default folder for the Scriptable Objects and default namespace.
14+
715
## [1.5.3]
816
### Changed
917
- Disabled the reload of the collection after script reloading on batch mode.
@@ -218,8 +226,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
218226
### Added
219227
- First initial working version
220228

221-
### [Unreleased]
229+
### Unreleased
230+
231+
222232

233+
[1.5.4]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v1.5.4
223234
[1.5.3]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v1.5.3
224235
[1.5.2]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v1.5.2
225236
[1.5.1]: https://github.com/badawe/ScriptableObjectCollection/releases/tag/v1.5.1

Scripts/Editor/Core/CollectionCustomEditor.cs

Lines changed: 162 additions & 133 deletions
Large diffs are not rendered by default.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using UnityEditor;
2+
using UnityEngine;
3+
4+
namespace BrunoMikoski.ScriptableObjectCollections
5+
{
6+
public class ScriptableObjectCollectionSettings : ScriptableObjectForPreferences<ScriptableObjectCollectionSettings>
7+
{
8+
[SerializeField]
9+
private string defaultGeneratedScriptsPath;
10+
public string DefaultGeneratedScriptsPath => defaultGeneratedScriptsPath;
11+
12+
[SerializeField]
13+
private string defaultNamespace;
14+
public string DefaultNamespace => defaultNamespace;
15+
16+
[SettingsProvider]
17+
private static SettingsProvider SettingsProvider()
18+
{
19+
return CreateSettingsProvider("ScriptableObject Collection/Settings", OnSettingsGUI);
20+
}
21+
22+
private static void OnSettingsGUI(SerializedObject serializedObject)
23+
{
24+
SerializedProperty defaultGeneratedScriptsFolder = serializedObject.FindProperty("defaultGeneratedScriptsPath");
25+
SerializedProperty defaultNamespaceSerializedProperty = serializedObject.FindProperty("defaultNamespace");
26+
DefaultAsset defaultAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(defaultGeneratedScriptsFolder
27+
.stringValue);
28+
29+
using (EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope())
30+
{
31+
DefaultAsset newFolder = EditorGUILayout.ObjectField("Default Generated Scripts Folder", defaultAsset, typeof(DefaultAsset), false) as DefaultAsset;
32+
if (changeCheck.changed)
33+
{
34+
defaultGeneratedScriptsFolder.stringValue = AssetDatabase.GetAssetPath(newFolder);
35+
defaultGeneratedScriptsFolder.serializedObject.ApplyModifiedProperties();
36+
}
37+
}
38+
39+
using (EditorGUI.ChangeCheckScope changeCheck = new EditorGUI.ChangeCheckScope())
40+
{
41+
string newNamespace = EditorGUILayout.DelayedTextField("Default Namespace", defaultNamespaceSerializedProperty.stringValue);
42+
if (changeCheck.changed)
43+
{
44+
defaultNamespaceSerializedProperty.stringValue = newNamespace;
45+
defaultNamespaceSerializedProperty.serializedObject.ApplyModifiedProperties();
46+
}
47+
}
48+
}
49+
}
50+
}

Scripts/Editor/Core/ScriptableObjectCollectionSettings.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.

Scripts/Editor/Utils/CodeGenerationUtility.cs

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,15 @@ public static void GenerateStaticCollectionScript(ScriptableObjectCollection col
182182
return;
183183
}
184184

185-
string fileName = GetFileName(collection);
186-
string nameSpace = GetNamespace(collection);
185+
SerializedObject collectionSerializedObject = new SerializedObject(collection);
186+
187+
188+
string fileName = collectionSerializedObject.FindProperty("generatedStaticClassFileName").stringValue;
189+
string nameSpace = collectionSerializedObject.FindProperty("generateStaticFileNamespace").stringValue;
187190

188-
string finalFolder = ScriptableObjectCollectionSettings.Instance.GetStaticFileFolderForCollection(collection);
191+
string finalFolder = collectionSerializedObject.FindProperty("generatedFileLocationPath").stringValue;
192+
bool writeAsPartial = collectionSerializedObject.FindProperty("generateAsPartialClass").boolValue;
193+
189194

190195
AssetDatabaseUtils.CreatePathIfDontExist(finalFolder);
191196
using (StreamWriter writer = new StreamWriter(Path.Combine(finalFolder, $"{fileName}.cs")))
@@ -198,17 +203,14 @@ public static void GenerateStaticCollectionScript(ScriptableObjectCollection col
198203
directives.Add(typeof(List<>).Namespace);
199204
directives.Add("System.Linq");
200205
directives.AddRange(GetCollectionDirectives(collection));
201-
202-
if (!ScriptableObjectCollectionSettings.Instance.IsGeneratingCustomStaticFile(collection))
203-
{
204-
AppendHeader(writer, ref indentation, nameSpace,"",
205-
collection.GetItemType().Name, true, false, directives.Distinct().ToArray());
206-
}
207-
else
208-
{
209-
AppendHeader(writer, ref indentation, nameSpace,"",
210-
fileName, false, false, directives.Distinct().ToArray());
211-
}
206+
string className = collection.GetItemType().Name;
207+
if (!writeAsPartial)
208+
className = fileName;
209+
210+
AppendHeader(writer, ref indentation, nameSpace, "", className,
211+
writeAsPartial,
212+
false, directives.Distinct().ToArray()
213+
);
212214

213215
WriteDirectAccessCollectionStatic(collection, writer, ref indentation);
214216

@@ -222,34 +224,26 @@ public static void GenerateStaticCollectionScript(ScriptableObjectCollection col
222224

223225
private static bool CanGenerateStaticFile(ScriptableObjectCollection collection, out string errorMessage)
224226
{
225-
string finalFolder = ScriptableObjectCollectionSettings.Instance.GetStaticFileFolderForCollection(collection);
226-
227-
if (string.IsNullOrEmpty(finalFolder))
228-
{
229-
errorMessage = "Static Code Generation folder not assigned, please assign it on the ScriptableObjectCollectionSettings";
230-
EditorGUIUtility.PingObject(ScriptableObjectCollectionSettings.Instance);
231-
Selection.objects = new Object[] {ScriptableObjectCollectionSettings.Instance};
232-
return false;
233-
}
234-
235227
List<ScriptableObjectCollection> collectionsOfSameType = CollectionsRegistry.Instance.GetCollectionsByItemType(collection.GetItemType());
236228
if (collectionsOfSameType.Count > 1)
237229
{
238230
for (int i = 0; i < collectionsOfSameType.Count; i++)
239231
{
240232
ScriptableObjectCollection collectionA = collectionsOfSameType[i];
233+
SerializedObject collectionASerializedObject = new SerializedObject(collectionA);
241234
for (int j = 0; j < collectionsOfSameType.Count; j++)
242235
{
243236
if (i == j)
244237
continue;
245238

246239
ScriptableObjectCollection collectionB = collectionsOfSameType[j];
240+
SerializedObject collectionBSerializedObject = new SerializedObject(collectionB);
247241

248-
if (GetFileName(collectionA).Equals(GetFileName(collectionB))
249-
&& GetNamespace(collectionA).Equals(GetNamespace(collectionB)))
242+
if (collectionASerializedObject.FindProperty("generatedStaticClassFileName").stringValue.Equals(collectionBSerializedObject.FindProperty("generatedStaticClassFileName").stringValue)
243+
&& collectionASerializedObject.FindProperty("generateStaticFileNamespace").stringValue.Equals(collectionASerializedObject.FindProperty("generateStaticFileNamespace").stringValue))
250244
{
251245
errorMessage =
252-
"Two collections with the same name and namespace already exist, please use custom ones";
246+
$"Two collections ({collectionA.name} and {collectionB.name}) with the same name and namespace already exist, please use custom ones";
253247
return false;
254248
}
255249
}
@@ -259,24 +253,7 @@ private static bool CanGenerateStaticFile(ScriptableObjectCollection collection,
259253
errorMessage = String.Empty;
260254
return true;
261255
}
262-
263-
private static string GetNamespace(ScriptableObjectCollection collection)
264-
{
265-
string targetNamespace = collection.GetItemType().Namespace;
266-
if (ScriptableObjectCollectionSettings.Instance.IsGeneratingCustomStaticFile(collection))
267-
targetNamespace = ScriptableObjectCollectionSettings.Instance.GetGeneratedStaticFileNamespace(collection);
268-
return targetNamespace;
269-
}
270-
271-
private static string GetFileName(ScriptableObjectCollection collection)
272-
{
273-
string fileName = $"{collection.GetItemType().Name}Static";
274-
if (ScriptableObjectCollectionSettings.Instance.IsGeneratingCustomStaticFile(collection))
275-
fileName = ScriptableObjectCollectionSettings.Instance.GetGeneratedStaticFileName(collection);
276-
277-
return fileName;
278-
}
279-
256+
280257
private static string[] GetCollectionDirectives(ScriptableObjectCollection collection)
281258
{
282259
HashSet<string> directives = new HashSet<string>();

Scripts/Editor/Utils/CollectionUtility.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ namespace BrunoMikoski.ScriptableObjectCollections
77
{
88
public static class CollectionUtility
99
{
10-
11-
1210
private static Dictionary<int, bool> objectToFoldOut = new Dictionary<int, bool>();
1311

1412
[MenuItem("Assets/Create/ScriptableObject Collection/New Collection", false, 100)]
@@ -20,18 +18,6 @@ private static void CreateNewItem()
2018

2119
CreateCollectionWizzard.Show(targetPath);
2220
}
23-
24-
[MenuItem("Assets/Create/ScriptableObject Collection/Create Settings", false, 200)]
25-
private static void CreateSettings()
26-
{
27-
ScriptableObjectCollectionSettings.LoadOrCreateInstance();
28-
}
29-
30-
[MenuItem("Assets/Create/ScriptableObject Collection/Create Settings", true, 200)]
31-
private static bool CreateSettings_Validation()
32-
{
33-
return !ScriptableObjectCollectionSettings.Exist();
34-
}
3521

3622
private static int GetHasCount(Object[] objects)
3723
{
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using UnityEditor;
4+
using UnityEngine;
5+
6+
namespace BrunoMikoski.ScriptableObjectCollections
7+
{
8+
//From https://github.com/baba-s/UniScriptableObjectForPreferences/blob/master/Editor/ScriptableObjectForPreferences.cs
9+
public abstract class ScriptableObjectForPreferences<T> : ScriptableObject
10+
where T : ScriptableObjectForPreferences<T>
11+
{
12+
private static string ConfigName => typeof(T).Name;
13+
private static T instance;
14+
15+
public static T GetInstance()
16+
{
17+
if (instance != null)
18+
{
19+
return instance;
20+
}
21+
22+
instance = CreateInstance<T>();
23+
string json = EditorUserSettings.GetConfigValue(ConfigName);
24+
EditorJsonUtility.FromJsonOverwrite(json, instance);
25+
if (instance == null)
26+
{
27+
instance = CreateInstance<T>();
28+
}
29+
30+
return instance;
31+
}
32+
33+
public static SettingsProvider CreateSettingsProvider(
34+
string settingsProviderPath = null,
35+
Action<SerializedObject> onGUI = null,
36+
Action<SerializedObject> onGUIExtra = null
37+
)
38+
{
39+
if (settingsProviderPath == null)
40+
{
41+
settingsProviderPath = $"{typeof(T).Name}";
42+
}
43+
44+
T foundInstance = GetInstance();
45+
SerializedObject serializedObject = new SerializedObject(foundInstance);
46+
IEnumerable<string> keywords = SettingsProvider.GetSearchKeywordsFromSerializedObject(serializedObject);
47+
SettingsProvider provider = new SettingsProvider(settingsProviderPath, SettingsScope.User, keywords);
48+
provider.guiHandler += _ => OnGuiHandler(onGUI, onGUIExtra);
49+
return provider;
50+
}
51+
52+
private static void OnGuiHandler(Action<SerializedObject> onGUI,
53+
Action<SerializedObject> onGUIExtra)
54+
{
55+
T foundInstance = GetInstance();
56+
Editor editor = Editor.CreateEditor(foundInstance);
57+
using (EditorGUI.ChangeCheckScope scope = new EditorGUI.ChangeCheckScope())
58+
{
59+
SerializedObject serializedObject = editor.serializedObject;
60+
serializedObject.Update();
61+
if (onGUI != null)
62+
{
63+
onGUI(serializedObject);
64+
}
65+
else
66+
{
67+
editor.DrawDefaultInspector();
68+
}
69+
70+
onGUIExtra?.Invoke(serializedObject);
71+
if (!scope.changed)
72+
{
73+
return;
74+
}
75+
76+
serializedObject.ApplyModifiedProperties();
77+
string json = EditorJsonUtility.ToJson(editor.target);
78+
EditorUserSettings.SetConfigValue(ConfigName, json);
79+
}
80+
}
81+
}
82+
}

Scripts/Editor/Utils/ScriptableObjectForPreferences.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.

Scripts/Editor/Wizzard/CreateCollectionWizzard.cs

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ public sealed class CreateCollectionWizzard : EditorWindow
1717
private const string LAST_GENERATED_COLLECTION_SCRIPT_PATH_KEY = "CollectionScriptPathKey";
1818
private const string LAST_TARGET_SCRIPTS_FOLDER_KEY = "LastTargetScriptsFolder";
1919

20-
private static CreateCollectionWizzard WINDOW_INSTANCE;
21-
private static string TARGET_FOLDER;
20+
private static CreateCollectionWizzard windowInstance;
21+
private static string targetFolder;
2222

2323

2424
private DefaultAsset cachedScriptableObjectFolder;
@@ -29,9 +29,9 @@ private DefaultAsset ScriptableObjectFolder
2929
if (cachedScriptableObjectFolder != null)
3030
return cachedScriptableObjectFolder;
3131

32-
if (!string.IsNullOrEmpty(TARGET_FOLDER))
32+
if (!string.IsNullOrEmpty(targetFolder))
3333
{
34-
cachedScriptableObjectFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(TARGET_FOLDER);
34+
cachedScriptableObjectFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(targetFolder);
3535
return cachedScriptableObjectFolder;
3636
}
3737

@@ -41,11 +41,6 @@ private DefaultAsset ScriptableObjectFolder
4141
return cachedScriptableObjectFolder;
4242
}
4343

44-
if (!string.IsNullOrEmpty(ScriptableObjectCollectionSettings.Instance.DefaultScriptableObjectsFolder))
45-
{
46-
cachedScriptableObjectFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(
47-
ScriptableObjectCollectionSettings.Instance.DefaultScriptableObjectsFolder);
48-
}
4944
return cachedScriptableObjectFolder;
5045
}
5146
set => cachedScriptableObjectFolder = value;
@@ -65,17 +60,12 @@ private DefaultAsset ScriptsFolder
6560
return cachedScriptsFolder;
6661
}
6762

68-
if (!string.IsNullOrEmpty(TARGET_FOLDER))
63+
if (!string.IsNullOrEmpty(targetFolder))
6964
{
70-
cachedScriptsFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(TARGET_FOLDER);
65+
cachedScriptsFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(targetFolder);
7166
return cachedScriptsFolder;
7267
}
7368

74-
if (!string.IsNullOrEmpty(ScriptableObjectCollectionSettings.Instance.DefaultScriptsFolder))
75-
{
76-
cachedScriptsFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(
77-
ScriptableObjectCollectionSettings.Instance.DefaultScriptsFolder);
78-
}
7969
return cachedScriptsFolder;
8070
}
8171
set => cachedScriptsFolder = value;
@@ -87,7 +77,7 @@ private string TargetNameSpace
8777
get
8878
{
8979
if (string.IsNullOrEmpty(cachedNameSpace))
90-
cachedNameSpace = ScriptableObjectCollectionSettings.Instance.DefaultNamespace;
80+
cachedNameSpace = ScriptableObjectCollectionSettings.GetInstance().DefaultNamespace;
9181
return cachedNameSpace;
9282
}
9383
set => cachedNameSpace = value;
@@ -134,18 +124,18 @@ private static string LastGeneratedCollectionScriptPath
134124

135125
private static CreateCollectionWizzard GetWindowInstance()
136126
{
137-
if (WINDOW_INSTANCE == null)
127+
if (windowInstance == null)
138128
{
139-
WINDOW_INSTANCE = CreateInstance<CreateCollectionWizzard>();
140-
WINDOW_INSTANCE.titleContent = new GUIContent("Create New Collection");
129+
windowInstance = CreateInstance<CreateCollectionWizzard>();
130+
windowInstance.titleContent = new GUIContent("Create New Collection");
141131
}
142132

143-
return WINDOW_INSTANCE;
133+
return windowInstance;
144134
}
145135

146136
public static void Show(string targetPath)
147137
{
148-
TARGET_FOLDER = targetPath;
138+
targetFolder = targetPath;
149139
GetWindowInstance().ShowUtility();
150140
}
151141

0 commit comments

Comments
 (0)