Skip to content

Commit d4eb432

Browse files
committed
Merge branch 'feature/small-fixes' into feature/new-guid-processor
# Conflicts: # Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs
2 parents e307c28 + 8540d54 commit d4eb432

10 files changed

+80
-37
lines changed

Scripts/Editor/Core/CodeGenerationUtility.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public static bool CreateNewScript(
6161
if (File.Exists(Path.GetFullPath(finalFilePath)))
6262
return false;
6363

64-
using StreamWriter writer = new StreamWriter(finalFilePath);
64+
using StreamWriter writer = new StreamWriter(finalFilePath, false, new UTF8Encoding(false));
6565
int indentation = 0;
6666

6767
// First write the directives.
@@ -144,7 +144,7 @@ public static bool CreateNewScript(
144144
}
145145

146146
// Now create the script.
147-
string[] lines = codeTemplateText.Split("\r\n");
147+
string[] lines = codeTemplateText.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
148148
return CreateNewScript(fileName, parentFolder, nameSpace, directives, lines);
149149
}
150150

@@ -377,12 +377,12 @@ public static void GenerateIndirectAccessForCollectionItemType(string collection
377377
}
378378

379379
targetFileName += ExtensionNew;
380-
using (StreamWriter writer = new StreamWriter(targetFileName))
380+
using (StreamWriter writer = new StreamWriter(targetFileName, false, new UTF8Encoding(false)))
381381
{
382382
int indentation = 0;
383383
List<string> directives = new List<string>();
384384
directives.Add(typeof(ScriptableObjectCollection).Namespace);
385-
385+
386386
directives.Add(collectionNamespace);
387387
directives.Add("System");
388388
directives.Add("UnityEngine");
@@ -441,10 +441,10 @@ public static void GenerateStaticCollectionScript(ScriptableObjectCollection col
441441
}
442442

443443
finalFileName += ExtensionNew;
444-
using (StreamWriter writer = new StreamWriter(finalFileName))
444+
using (StreamWriter writer = new StreamWriter(finalFileName, false, new UTF8Encoding(false)))
445445
{
446446
int indentation = 0;
447-
447+
448448
List<string> directives = new List<string>();
449449
directives.Add(typeof(CollectionsRegistry).Namespace);
450450
directives.Add(collection.GetType().Namespace);

Scripts/Editor/CustomEditors/CollectionCustomEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ protected virtual void OnEnable()
421421
collection.Clear();
422422
}
423423

424-
if (!CollectionsRegistry.Instance.IsKnowCollection(collection))
424+
if (!CollectionsRegistry.Instance.IsKnownCollection(collection))
425425
CollectionsRegistry.Instance.ReloadCollections();
426426

427427
// Need to cache this before the reorderable list is created, because it affects how the list is displayed.

Scripts/Editor/Processors/CollectionsAssetsPostProcessor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAsse
3939
Debug.LogWarning($"Collection {collection} GUID was not unique, generating a new one, and clearing the items");
4040
}
4141

42-
if (!CollectionsRegistry.Instance.IsKnowCollection(collection))
42+
if (!CollectionsRegistry.Instance.IsKnownCollection(collection))
4343
{
4444
RefreshRegistry();
4545
Debug.Log($"New collection found on the Project {collection.name}, refreshing the Registry");

Scripts/Editor/PropertyDrawers/CollectionItemIndirectReferencePropertyDrawer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public sealed class CollectionItemIndirectReferencePropertyDrawer : PropertyDraw
1313
private const string COLLECTION_ITEM_LAST_KNOW_NAME_PROPERTY_PATH = "itemLastKnownName";
1414
private const string COLLECTION_GUID_VALUE_A_PROPERTY_PATH = "collectionGUIDValueA";
1515
private const string COLLECTION_GUID_VALUE_B_PROPERTY_PATH = "collectionGUIDValueB";
16-
private const string COLLECTION_LAST_KNOW_NAME_PROPERTY_PATH = "collectionLastKnowName";
16+
private const string COLLECTION_LAST_KNOW_NAME_PROPERTY_PATH = "collectionLastKnownName";
1717

1818
private Type collectionItemType;
1919
private CollectionItemPropertyDrawer collectionItemPropertyDrawer;
@@ -23,7 +23,7 @@ public sealed class CollectionItemIndirectReferencePropertyDrawer : PropertyDraw
2323
private SerializedProperty itemLastKnowNameSerializedProperty;
2424
private SerializedProperty collectionGUIDValueASerializedProperty;
2525
private SerializedProperty collectionGUIDValueBSerializedProperty;
26-
private SerializedProperty collectionLastKnowNameSerializedProperty;
26+
private SerializedProperty collectionLastKnownNameSerializedProperty;
2727

2828

2929
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
@@ -47,7 +47,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
4747
itemLastKnowNameSerializedProperty = property.FindPropertyRelative(COLLECTION_ITEM_LAST_KNOW_NAME_PROPERTY_PATH);
4848
collectionGUIDValueASerializedProperty = property.FindPropertyRelative(COLLECTION_GUID_VALUE_A_PROPERTY_PATH);
4949
collectionGUIDValueBSerializedProperty = property.FindPropertyRelative(COLLECTION_GUID_VALUE_B_PROPERTY_PATH);
50-
collectionLastKnowNameSerializedProperty = property.FindPropertyRelative(COLLECTION_LAST_KNOW_NAME_PROPERTY_PATH);
50+
collectionLastKnownNameSerializedProperty = property.FindPropertyRelative(COLLECTION_LAST_KNOW_NAME_PROPERTY_PATH);
5151

5252
TryGetCollectionItem(out ScriptableObject collectionItem);
5353

Scripts/Editor/PropertyDrawers/CollectionItemPickerPropertyDrawer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using BrunoMikoski.ScriptableObjectCollections.Popup;
@@ -329,7 +329,7 @@ private void ValidateIndirectReferencesInProperty(SerializedProperty property)
329329
if (!validReference)
330330
{
331331
SerializedProperty lastKnownItemNameProperty = elementProperty.FindPropertyRelative("itemLastKnownName");
332-
SerializedProperty lastKnownCollectionNameProperty = elementProperty.FindPropertyRelative("collectionLastKnowName");
332+
SerializedProperty lastKnownCollectionNameProperty = elementProperty.FindPropertyRelative("collectionLastKnownName");
333333

334334
string lastKnownItemName = lastKnownItemNameProperty != null ? lastKnownItemNameProperty.stringValue : string.Empty;
335335
string lastKnownCollectionName = lastKnownCollectionNameProperty != null ? lastKnownCollectionNameProperty.stringValue : string.Empty;

Scripts/Runtime/Core/CollectionItemIndirectReference.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using UnityEngine;
3+
using UnityEngine.Serialization;
34

45
namespace BrunoMikoski.ScriptableObjectCollections
56
{
@@ -21,8 +22,8 @@ public abstract class CollectionItemIndirectReference: IEquatable<CollectionItem
2122

2223
[SerializeField]
2324
protected string itemLastKnownName;
24-
[SerializeField]
25-
protected string collectionLastKnowName;
25+
[SerializeField, FormerlySerializedAs("collectionLastKnowName")]
26+
protected string collectionLastKnownName;
2627

2728
public bool Equals(CollectionItemIndirectReference other)
2829
{
@@ -67,18 +68,20 @@ public bool IsValid()
6768
public class CollectionItemIndirectReference<TObject> : CollectionItemIndirectReference
6869
where TObject : ScriptableObject, ISOCItem
6970
{
71+
[NonSerialized]
72+
private bool hasCachedRef;
7073
[NonSerialized]
7174
private TObject cachedRef;
7275
public TObject Ref
7376
{
7477
get
7578
{
76-
if (cachedRef != null)
79+
if (hasCachedRef && cachedRef != null)
7780
return cachedRef;
7881

79-
if (TryResolveReference(out TObject resultObj))
80-
cachedRef = resultObj;
81-
82+
hasCachedRef = TryResolveReference(out TObject resultObj);
83+
cachedRef = resultObj;
84+
8285
return cachedRef;
8386
}
8487
}
@@ -110,9 +113,9 @@ private bool TryResolveReference(out TObject result)
110113
}
111114
else
112115
{
113-
if (!string.IsNullOrEmpty(collectionLastKnowName))
116+
if (!string.IsNullOrEmpty(collectionLastKnownName))
114117
{
115-
if (CollectionsRegistry.Instance.TryGetCollectionByName(collectionLastKnowName, out collection))
118+
if (CollectionsRegistry.Instance.TryGetCollectionByName(collectionLastKnownName, out collection))
116119
{
117120
SetCollection(collection);
118121

@@ -165,7 +168,7 @@ public void SetCollection(ScriptableObjectCollection targetCollection)
165168
(long,long) collectionGUIDValues = targetCollection.GUID.GetRawValues();
166169
collectionGUIDValueA = collectionGUIDValues.Item1;
167170
collectionGUIDValueB = collectionGUIDValues.Item2;
168-
collectionLastKnowName = targetCollection.name;
171+
collectionLastKnownName = targetCollection.name;
169172
}
170173
}
171174
}

Scripts/Runtime/Core/CollectionItemPicker.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public List<TItemType> Items
3131
{
3232
cachedItems.Clear();
3333

34-
for (int i = 0; i < indirectReferences.Count; i++)
34+
for (int i = indirectReferences.Count - 1; i >= 0; i--)
3535
{
3636
CollectionItemIndirectReference<TItemType> collectionItemIndirectReference = indirectReferences[i];
3737
if (!collectionItemIndirectReference.IsValid() || collectionItemIndirectReference.Ref == null)
@@ -43,6 +43,8 @@ public List<TItemType> Items
4343
cachedItems.Add(collectionItemIndirectReference.Ref);
4444
}
4545

46+
cachedItems.Reverse();
47+
4648
isDirty = false;
4749
}
4850

Scripts/Runtime/Core/CollectionsRegistry.cs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ public class CollectionsRegistry : ResourceScriptableObjectSingleton<Collections
2020
[SerializeField]
2121
private List<ScriptableObjectCollection> collections = new List<ScriptableObjectCollection>();
2222
public IReadOnlyList<ScriptableObjectCollection> Collections => collections;
23-
23+
24+
private Dictionary<LongGuid, ScriptableObjectCollection> collectionGuidLookup = new();
25+
2426
[SerializeField, HideInInspector]
2527
private bool autoSearchForCollections;
2628
public bool AutoSearchForCollections => autoSearchForCollections;
@@ -31,7 +33,7 @@ private static void Initialize()
3133
LoadOrCreateInstance<CollectionsRegistry>();
3234
}
3335

34-
public bool IsKnowCollection(ScriptableObjectCollection targetCollection)
36+
public bool IsKnownCollection(ScriptableObjectCollection targetCollection)
3537
{
3638
for (int i = 0; i < collections.Count; i++)
3739
{
@@ -47,9 +49,10 @@ public void RegisterCollection(ScriptableObjectCollection targetCollection)
4749
{
4850
if (collections.Contains(targetCollection))
4951
return;
50-
52+
5153
collections.Add(targetCollection);
52-
54+
RebuildGuidLookup();
55+
5356
ObjectUtility.SetDirty(this);
5457
}
5558

@@ -60,7 +63,8 @@ public void UnregisterCollection(ScriptableObjectCollection targetCollection)
6063

6164
if (!collections.Remove(targetCollection))
6265
return;
63-
66+
67+
RebuildGuidLookup();
6468
ObjectUtility.SetDirty(this);
6569
}
6670

@@ -243,14 +247,34 @@ public ScriptableObjectCollection GetCollectionByGUID(string guid)
243247

244248
public ScriptableObjectCollection GetCollectionByGUID(LongGuid guid)
245249
{
250+
if (collectionGuidLookup.Count == 0 && collections.Count > 0)
251+
RebuildGuidLookup();
252+
253+
if (collectionGuidLookup.TryGetValue(guid, out ScriptableObjectCollection cached) && cached != null)
254+
return cached;
255+
246256
for (int i = 0; i < collections.Count; i++)
247257
{
248258
if (collections[i] != null && collections[i].GUID == guid)
259+
{
260+
collectionGuidLookup[guid] = collections[i];
249261
return collections[i];
262+
}
250263
}
251264

252265
return null;
253266
}
267+
268+
private void RebuildGuidLookup()
269+
{
270+
collectionGuidLookup.Clear();
271+
for (int i = 0; i < collections.Count; i++)
272+
{
273+
ScriptableObjectCollection collection = collections[i];
274+
if (collection != null && collection.GUID.IsValid())
275+
collectionGuidLookup[collection.GUID] = collection;
276+
}
277+
}
254278

255279
public bool TryGetCollectionOfType(Type type, out ScriptableObjectCollection resultCollection)
256280
{
@@ -377,6 +401,7 @@ public void ReloadCollections()
377401
{
378402
ValidateCollections();
379403
collections = foundCollections;
404+
RebuildGuidLookup();
380405
ObjectUtility.SetDirty(this);
381406
}
382407
#endif

Scripts/Runtime/Core/ScriptableObjectCollection.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public LongGuid GUID
4646
public virtual bool ShouldProtectItemOrder => false;
4747

4848
private Dictionary<string,ScriptableObject> itemNameToScriptableObject = new();
49+
private Dictionary<LongGuid,ScriptableObject> itemGuidToScriptableObject = new();
4950

5051
public ScriptableObject this[int index]
5152
{
@@ -444,7 +445,7 @@ public void RefreshCollection()
444445
Clear();
445446
}
446447

447-
if (!CollectionsRegistry.Instance.IsKnowCollection(this))
448+
if (!CollectionsRegistry.Instance.IsKnownCollection(this))
448449
{
449450
CollectionsRegistry.Instance.RegisterCollection(this);
450451
}
@@ -468,10 +469,13 @@ public void RefreshCollection()
468469
public void CacheItemNames()
469470
{
470471
itemNameToScriptableObject.Clear();
472+
itemGuidToScriptableObject.Clear();
471473
for (int i = 0; i < items.Count; i++)
472474
{
473475
ScriptableObject item = items[i];
474476
itemNameToScriptableObject.TryAdd(item.name, item);
477+
if (item is ISOCItem socItem && socItem.GUID.IsValid())
478+
itemGuidToScriptableObject.TryAdd(socItem.GUID, item);
475479
}
476480
}
477481

@@ -499,16 +503,23 @@ public bool TryGetItemByGUID<T>(LongGuid itemGUID, out T scriptableObjectCollect
499503
{
500504
if (itemGUID.IsValid())
501505
{
506+
if (itemGuidToScriptableObject.TryGetValue(itemGUID, out ScriptableObject cached))
507+
{
508+
scriptableObjectCollectionItem = cached as T;
509+
return scriptableObjectCollectionItem != null;
510+
}
511+
502512
for (int i = 0; i < items.Count; i++)
503513
{
504514
ScriptableObject item = items[i];
505515
ISOCItem socItem = item as ISOCItem;
506516
if (socItem == null)
507517
continue;
508-
518+
509519
if (socItem.GUID == itemGUID)
510520
{
511521
scriptableObjectCollectionItem = item as T;
522+
itemGuidToScriptableObject[itemGUID] = item;
512523
return scriptableObjectCollectionItem != null;
513524
}
514525
}
@@ -524,6 +535,8 @@ public bool TryGetItemByGUID(LongGuid itemGUID, out ScriptableObject scriptableO
524535

525536
protected virtual void ClearCachedValues()
526537
{
538+
itemGuidToScriptableObject.Clear();
539+
itemNameToScriptableObject.Clear();
527540
}
528541
}
529542

@@ -546,8 +559,6 @@ public static IReadOnlyList<TObjectType> Values
546559
get => (TObjectType)base[index];
547560
set => base[index] = value;
548561
}
549-
550-
private readonly Dictionary<Type, List<TObjectType>> typeToItems = new();
551562

552563

553564
public new IEnumerator<TObjectType> GetEnumerator()

Scripts/Runtime/Core/ScriptableObjectCollectionItem.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public override bool Equals(object o)
9898
ScriptableObjectCollectionItem other = o as ScriptableObjectCollectionItem;
9999
if (other == null)
100100
return false;
101-
101+
102102
return guid.IsValid() && other.guid.IsValid() && guid == other.guid;
103103
}
104104

@@ -107,10 +107,12 @@ public override bool Equals(object o)
107107
if (ReferenceEquals(left, right))
108108
return true;
109109

110-
if (ReferenceEquals(left, null))
111-
return false;
112-
113-
if (ReferenceEquals(right, null))
110+
// Use Unity's implicit bool to detect destroyed objects
111+
bool leftNull = ReferenceEquals(left, null) || !(UnityEngine.Object)left;
112+
bool rightNull = ReferenceEquals(right, null) || !(UnityEngine.Object)right;
113+
if (leftNull && rightNull)
114+
return true;
115+
if (leftNull || rightNull)
114116
return false;
115117

116118
return left.Equals(right);

0 commit comments

Comments
 (0)