Skip to content

Commit 38f79b8

Browse files
Merge remote-tracking branch 'upstream/main' into #22-Fix-DragAndDrop-ReferenceDrawer
2 parents b0aa931 + 648cd8d commit 38f79b8

File tree

9 files changed

+3567
-42
lines changed

9 files changed

+3567
-42
lines changed

.editorconfig

Lines changed: 3467 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
steps:
1111
- name: Checkout
12-
uses: actions/checkout@v2
12+
uses: actions/checkout@v3
1313
with:
1414
token: ${{ secrets.GH_TOKEN }}
1515
- name: Setup Node.js

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
### [1.7.3](https://github.com/Thundernerd/Unity3D-SerializableInterface/compare/v1.7.2...v1.7.3) (2022-07-22)
2+
3+
4+
### Refactors
5+
6+
* property drawer now reuses cached reference drawers ([f930d8e](https://github.com/Thundernerd/Unity3D-SerializableInterface/commit/f930d8ed92b8358e417d075f9a089f7161cadc50))
7+
8+
### [1.7.2](https://github.com/Thundernerd/Unity3D-SerializableInterface/compare/v1.7.1...v1.7.2) (2022-07-22)
9+
10+
11+
### Bug Fixes
12+
13+
* updated actions/checkout to version 3 ([ef748e1](https://github.com/Thundernerd/Unity3D-SerializableInterface/commit/ef748e176b864cd3dfc00f3b96e9cedb8783055d))
14+
115
### [1.7.1](https://github.com/Thundernerd/Unity3D-SerializableInterface/compare/v1.7.0...v1.7.1) (2022-06-18)
216

317

Editor/Drawers/RawReferenceDrawer.cs

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ namespace TNRD.Drawers
88
{
99
internal class RawReferenceDrawer : ReferenceDrawer, IReferenceDrawer
1010
{
11-
private readonly GUIContent label;
12-
private readonly FieldInfo fieldInfo;
11+
private GUIContent label;
12+
private FieldInfo fieldInfo;
13+
14+
private object previousReferenceValue;
15+
private string previousPropertyPath;
1316

1417
private object RawReferenceValue
1518
{
@@ -21,14 +24,22 @@ private object RawReferenceValue
2124
ISerializableInterface instance =
2225
(ISerializableInterface)fieldInfo.GetValue(Property.serializedObject.targetObject);
2326
return instance.GetRawReference();
27+
#endif
28+
}
29+
30+
set
31+
{
32+
#if UNITY_2021_1_OR_NEWER
33+
RawReferenceProperty.managedReferenceValue = value;
34+
#else
35+
fieldInfo.SetValue(Property.serializedObject.targetObject, value);
2436
#endif
2537
}
2638
}
2739

28-
/// <inheritdoc />
29-
public RawReferenceDrawer(SerializedProperty property, GUIContent label, Type genericType, FieldInfo fieldInfo)
30-
: base(property, genericType)
40+
public void Initialize(SerializedProperty property, Type genericType, GUIContent label, FieldInfo fieldInfo)
3141
{
42+
Initialize(property, genericType);
3243
this.label = label;
3344
this.fieldInfo = fieldInfo;
3445
}
@@ -47,6 +58,8 @@ public float GetHeight()
4758
/// <inheritdoc />
4859
public void OnGUI(Rect position)
4960
{
61+
AvoidDuplicateReferencesInArray();
62+
5063
Rect objectFieldRect = new Rect(position)
5164
{
5265
height = EditorGUIUtility.singleLineHeight
@@ -72,6 +85,8 @@ public void OnGUI(Rect position)
7285
RawReferenceProperty,
7386
new GUIContent(rawReferenceValue.GetType().Name),
7487
true);
88+
89+
previousPropertyPath = Property.propertyPath;
7590
}
7691

7792
/// <inheritdoc />
@@ -92,5 +107,41 @@ protected override void OnPropertiesClicked()
92107
}
93108
}
94109
}
110+
111+
private void AvoidDuplicateReferencesInArray()
112+
{
113+
if (!IsPropertyInArray(Property))
114+
return;
115+
if (previousPropertyPath == null)
116+
return;
117+
if (previousPropertyPath == Property.propertyPath)
118+
return;
119+
120+
SerializedProperty rawReferenceProperty = Property.FindPropertyRelative("rawReference");
121+
object currentReferenceValue = RawReferenceValue;
122+
123+
if (currentReferenceValue == null)
124+
return;
125+
126+
if (previousReferenceValue == currentReferenceValue)
127+
{
128+
RawReferenceValue = CreateInstance(currentReferenceValue);
129+
rawReferenceProperty.serializedObject.ApplyModifiedProperties();
130+
}
131+
132+
previousReferenceValue = currentReferenceValue;
133+
}
134+
135+
private static bool IsPropertyInArray(SerializedProperty prop)
136+
{
137+
return prop.propertyPath.Contains(".Array.data[");
138+
}
139+
140+
private static object CreateInstance(object source)
141+
{
142+
object instance = Activator.CreateInstance(source.GetType());
143+
EditorUtility.CopySerializedManagedFieldsOnly(source, instance);
144+
return instance;
145+
}
95146
}
96147
}

Editor/Drawers/ReferenceDrawer.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,30 @@ private enum DragAndDropMode
2121

2222
private DragAndDropMode dragAndDropMode;
2323

24-
protected readonly SerializedProperty Property;
25-
protected readonly Type GenericType;
2624
protected readonly CustomObjectDrawer CustomObjectDrawer;
2725

26+
protected SerializedProperty Property { get; private set; }
27+
protected Type GenericType { get; private set; }
28+
2829
protected SerializedProperty ReferenceModeProperty => Property.FindPropertyRelative("mode");
2930
protected SerializedProperty RawReferenceProperty => Property.FindPropertyRelative("rawReference");
3031
protected SerializedProperty UnityReferenceProperty => Property.FindPropertyRelative("unityReference");
3132

32-
protected ReferenceDrawer(SerializedProperty property, Type genericType)
33+
protected ReferenceDrawer()
3334
{
34-
Property = property;
35-
GenericType = genericType;
36-
3735
CustomObjectDrawer = new CustomObjectDrawer();
3836
CustomObjectDrawer.ButtonClicked += OnButtonClicked;
3937
CustomObjectDrawer.Clicked += OnClicked;
4038
CustomObjectDrawer.DeletePressed += OnDeletePressed;
4139
CustomObjectDrawer.PropertiesClicked += OnPropertiesClicked;
4240
}
4341

42+
protected void Initialize(SerializedProperty property, Type genericType)
43+
{
44+
Property = property;
45+
GenericType = genericType;
46+
}
47+
4448
private void OnButtonClicked(Rect position)
4549
{
4650
AdvancedDropdownState state = new AdvancedDropdownState();

Editor/Drawers/UnityReferenceDrawer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ namespace TNRD.Drawers
88
{
99
internal class UnityReferenceDrawer : ReferenceDrawer, IReferenceDrawer
1010
{
11-
private readonly GUIContent label;
11+
private GUIContent label;
1212

13-
public UnityReferenceDrawer(SerializedProperty property, GUIContent label, Type genericType)
14-
: base(property, genericType)
13+
public void Initialize(SerializedProperty property, Type genericType, GUIContent label)
1514
{
15+
Initialize(property, genericType);
1616
this.label = label;
1717
}
1818

Editor/SerializableInterfacePropertyDrawer.cs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,20 @@ namespace TNRD
1010
[CustomPropertyDrawer(typeof(SerializableInterface<>), true)]
1111
internal sealed class SerializableInterfacePropertyDrawer : PropertyDrawer
1212
{
13+
private readonly RawReferenceDrawer rawReferenceDrawer = new RawReferenceDrawer();
14+
private readonly UnityReferenceDrawer unityReferenceDrawer = new UnityReferenceDrawer();
15+
1316
private SerializedProperty serializedProperty;
1417
private Type genericType;
1518

16-
private IReferenceDrawer activeDrawer;
17-
1819
/// <inheritdoc />
19-
public override bool CanCacheInspectorGUI(SerializedProperty property)
20-
{
21-
return false;
22-
}
20+
public override bool CanCacheInspectorGUI(SerializedProperty property) => false;
2321

2422
private void Initialize(SerializedProperty property)
2523
{
2624
if (serializedProperty == property)
2725
return;
2826

29-
activeDrawer = null;
3027
serializedProperty = property;
3128
genericType = GetGenericArgument();
3229
Assert.IsNotNull(genericType, "Unable to find generic argument, are you doing some shady inheritance?");
@@ -36,16 +33,14 @@ private void Initialize(SerializedProperty property)
3633
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
3734
{
3835
Initialize(property);
39-
activeDrawer = GetReferenceDrawer(activeDrawer, property, label);
40-
return activeDrawer.GetHeight();
36+
return GetReferenceDrawer(property, label).GetHeight();
4137
}
4238

4339
/// <inheritdoc />
4440
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
4541
{
4642
Initialize(property);
47-
activeDrawer = GetReferenceDrawer(activeDrawer, property, label);
48-
activeDrawer.OnGUI(position);
43+
GetReferenceDrawer(property, label).OnGUI(position);
4944
}
5045

5146
private Type GetGenericArgument()
@@ -84,25 +79,19 @@ private Type GetGenericArgument()
8479
return null;
8580
}
8681

87-
private IReferenceDrawer GetReferenceDrawer(
88-
IReferenceDrawer original,
89-
SerializedProperty property,
90-
GUIContent label
91-
)
82+
private IReferenceDrawer GetReferenceDrawer(SerializedProperty property, GUIContent label)
9283
{
9384
SerializedProperty modeProperty = serializedProperty.FindPropertyRelative("mode");
9485
ReferenceMode referenceMode = (ReferenceMode)modeProperty.enumValueIndex;
9586

9687
switch (referenceMode)
9788
{
9889
case ReferenceMode.Raw:
99-
return original is RawReferenceDrawer
100-
? original
101-
: new RawReferenceDrawer(property, label, genericType, fieldInfo);
90+
rawReferenceDrawer.Initialize(property, genericType, label, fieldInfo);
91+
return rawReferenceDrawer;
10292
case ReferenceMode.Unity:
103-
return original is UnityReferenceDrawer
104-
? original
105-
: new UnityReferenceDrawer(property, label, genericType);
93+
unityReferenceDrawer.Initialize(property, genericType, label);
94+
return unityReferenceDrawer;
10695
default:
10796
throw new ArgumentOutOfRangeException();
10897
}

Runtime/SerializableInterface.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace TNRD
99
/// </summary>
1010
/// <typeparam name="TInterface">The type of the interface you want to serialize</typeparam>
1111
[Serializable]
12-
public class SerializableInterface<TInterface> : ISerializableInterface
12+
public class SerializableInterface<TInterface> : ISerializableInterface where TInterface : class
1313
{
1414
[HideInInspector, SerializeField] private ReferenceMode mode = ReferenceMode.Unity;
1515
[HideInInspector, SerializeField] private UnityEngine.Object unityReference;
@@ -21,8 +21,8 @@ public TInterface Value
2121
{
2222
return mode switch
2323
{
24-
ReferenceMode.Raw => (TInterface)rawReference,
25-
ReferenceMode.Unity => (TInterface)(object)unityReference,
24+
ReferenceMode.Raw => rawReference as TInterface,
25+
ReferenceMode.Unity => (object)unityReference as TInterface,
2626
_ => throw new ArgumentOutOfRangeException()
2727
};
2828
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "net.tnrd.serializableinterface",
3-
"version": "1.7.1",
3+
"version": "1.7.3",
44
"displayName": "Serializable Interface",
55
"unity": "2020.1",
66
"description": "A wrapper that allows serialization of interfaces that supports both UnityEngine.Object and regular object types",
@@ -28,7 +28,7 @@
2828
"@semantic-release/changelog": "^6.0.1",
2929
"@semantic-release/commit-analyzer": "^9.0.2",
3030
"@semantic-release/git": "^10.0.1",
31-
"@semantic-release/github": "^8.0.4",
31+
"@semantic-release/github": "^8.0.5",
3232
"@semantic-release/npm": "^9.0.1",
3333
"@semantic-release/release-notes-generator": "^10.0.3",
3434
"conventional-changelog-conventionalcommits": "^4.6.3",

0 commit comments

Comments
 (0)