Skip to content

Commit

Permalink
fix(MemberChange): allow undo operations but warn against using them
Browse files Browse the repository at this point in the history
Supporting the Undo stack in Unity is important as a lot of logic
depends on it, most importantly the dirty checks for the scene or a
prefab that was modified. To ensure the expected behavior is
followed this change allows any change to be added to the Undo stack
and instead warns users against running undo/redo operation of those
changes because they won't be handled by change handler methods.
  • Loading branch information
Christopher - Marcel Böddecker committed Mar 20, 2019
1 parent 311643d commit b29c017
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions Sources/FodyRunner.UnityIntegration/InspectorEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@
[CanEditMultipleObjects]
public class InspectorEditor : Editor
{
/// <summary>
/// The key to use to store and retrieve <see cref="UndoRedoWarningPropertyPath"/> into/from <see cref="SessionState"/>.
/// </summary>
protected static readonly string UndoRedoWarningSessionStateKey =
typeof(InspectorEditor).FullName + nameof(UndoRedoWarningPropertyPath);
/// <summary>
/// <see cref="SerializedProperty.propertyPath"/> of the property changed most recently, <see langword="null"/> if no property has been changed yet.
/// </summary>
protected static string UndoRedoWarningPropertyPath
{
get =>
SessionState.GetString(UndoRedoWarningSessionStateKey, null);
set =>
SessionState.SetString(UndoRedoWarningSessionStateKey, value);
}

/// <summary>
/// A reusable collection of methods on the current <see cref="SerializedProperty"/>'s declaring type that are annotated with at least one <see cref="HandlesMemberChangeAttribute"/>.
/// </summary>
Expand All @@ -32,6 +48,8 @@ public override void OnInspectorGUI()
return;
}

string undoRedoWarningPropertyPath = UndoRedoWarningPropertyPath;

do
{
string propertyPath = property.propertyPath;
Expand All @@ -40,8 +58,25 @@ public override void OnInspectorGUI()
using (EditorGUI.ChangeCheckScope changeCheckScope = new EditorGUI.ChangeCheckScope())
using (new EditorGUI.DisabledGroupScope(propertyPath == "m_Script"))
{
bool showUndoRedoWarning = propertyPath == undoRedoWarningPropertyPath;
if (showUndoRedoWarning)
{
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.HelpBox(
"Undo/redo is unsupported for this field at runtime:"
+ " The change won't be noticed by components depending on it.",
MessageType.Warning);
EditorGUI.indentLevel++;
}

DrawProperty(property);

if (showUndoRedoWarning)
{
EditorGUILayout.EndVertical();
EditorGUI.indentLevel--;
}

if (!changeCheckScope.changed
|| !Application.isPlaying
|| targetObject is Behaviour behaviour && !behaviour.isActiveAndEnabled)
Expand Down Expand Up @@ -81,13 +116,10 @@ protected virtual void ApplyModifiedProperty(SerializedProperty property, bool h
{
if (hasChangeHandlers)
{
// Change handlers can't be called for undo or redo operations, so don't register an undo operation.
property.serializedObject.ApplyModifiedPropertiesWithoutUndo();
}
else
{
property.serializedObject.ApplyModifiedProperties();
UndoRedoWarningPropertyPath = property.propertyPath;
}

property.serializedObject.ApplyModifiedProperties();
}

/// <summary>
Expand Down

0 comments on commit b29c017

Please sign in to comment.