Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Editor/Drawers/RawReferenceDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ internal class RawReferenceDrawer : ReferenceDrawer, IReferenceDrawer
private readonly GUIContent label;
private readonly FieldInfo fieldInfo;

private static object previousReferenceValue;
private static string previousPropertyPath;
Comment on lines +14 to +15
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain the reason for making this static?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It used to be a local variable in SerializableInterfacePropertyDrawer.cs. The goal was to store the last element and check if the new element's rawReference object points to the same instance as the previous one. If it does AND this isn't actually the same variable (we know that using the propertyPath, see line 115 in RawReferenceDrawer.cs), then we need to create a new instance and reassign the values (line 124 - 125 in RawReferenceDrawer.cs). I've moved the code to RawReferenceDrawer.cs since it made more sense because it only applies to rawReferences, but since we always create a new instance for that drawer, we either need to pass the values of the previous object to its constructor, or save it in a static variable.

Passing it using the constructor would also add unnecessary code in SerializableInterfacePropertyDrawer.cs. So the static way made sense in that regard. I hope it clears up things a bit. Also, it wouldn't need to be static if the instance of ReferenceDrawers where reused :)


private object RawReferenceValue
{
get
Expand All @@ -21,6 +24,15 @@ private object RawReferenceValue
ISerializableInterface instance =
(ISerializableInterface)fieldInfo.GetValue(Property.serializedObject.targetObject);
return instance.GetRawReference();
#endif
}

set
{
#if UNITY_2021_1_OR_NEWER
RawReferenceProperty.managedReferenceValue = value;
#else
fieldInfo.SetValue(Property.serializedObject.targetObject, value);
#endif
}
}
Expand All @@ -47,6 +59,8 @@ public float GetHeight()
/// <inheritdoc />
public void OnGUI(Rect position)
{
AvoidDuplicateReferencesInArray();

Rect objectFieldRect = new Rect(position)
{
height = EditorGUIUtility.singleLineHeight
Expand All @@ -71,6 +85,8 @@ public void OnGUI(Rect position)
true);

HandleDragAndDrop(objectFieldRect);

previousPropertyPath = Property.propertyPath;
}

/// <inheritdoc />
Expand All @@ -91,5 +107,41 @@ protected override void OnPropertiesClicked()
}
}
}

private void AvoidDuplicateReferencesInArray()
{
if (!IsPropertyInArray(Property))
return;
if (previousPropertyPath == null)
return;
if (previousPropertyPath == Property.propertyPath)
return;

SerializedProperty rawReferenceProperty = Property.FindPropertyRelative("rawReference");
object currentReferenceValue = RawReferenceValue;

if (currentReferenceValue == null)
return;

if (previousReferenceValue == currentReferenceValue)
{
RawReferenceValue = CreateInstance(currentReferenceValue);
rawReferenceProperty.serializedObject.ApplyModifiedProperties();
}

previousReferenceValue = currentReferenceValue;
}

private static bool IsPropertyInArray(SerializedProperty prop)
{
return prop.propertyPath.Contains(".Array.data[");
}

private static object CreateInstance(object source)
{
object instance = Activator.CreateInstance(source.GetType());
EditorUtility.CopySerializedManagedFieldsOnly(source, instance);
return instance;
}
}
}
5 changes: 1 addition & 4 deletions Editor/SerializableInterfacePropertyDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ internal sealed class SerializableInterfacePropertyDrawer : PropertyDrawer
private IReferenceDrawer activeDrawer;

/// <inheritdoc />
public override bool CanCacheInspectorGUI(SerializedProperty property)
{
return false;
}
public override bool CanCacheInspectorGUI(SerializedProperty property) => false;

private void Initialize(SerializedProperty property)
{
Expand Down