154 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Diagnostics;
 | |
| using UnityEngine.Playables;
 | |
| 
 | |
| #if UNITY_EDITOR
 | |
| using UnityEditor;
 | |
| #endif
 | |
| 
 | |
| namespace UnityEngine.Timeline
 | |
| {
 | |
|     static class TimelineUndo
 | |
|     {
 | |
|         internal static bool undoEnabled
 | |
|         {
 | |
|             get
 | |
|             {
 | |
| #if UNITY_EDITOR
 | |
|                 return DisableUndoGuard.enableUndo && DisableUndoScope.enableUndo;
 | |
| #else
 | |
|                 return false;
 | |
| #endif
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static void PushDestroyUndo(TimelineAsset timeline, Object thingToDirty, Object objectToDestroy)
 | |
|         {
 | |
| #if UNITY_EDITOR
 | |
|             if (objectToDestroy == null || !undoEnabled)
 | |
|                 return;
 | |
| 
 | |
|             if (thingToDirty != null)
 | |
|                 EditorUtility.SetDirty(thingToDirty);
 | |
| 
 | |
|             if (timeline != null)
 | |
|                 EditorUtility.SetDirty(timeline);
 | |
| 
 | |
|             Undo.DestroyObjectImmediate(objectToDestroy);
 | |
| #else
 | |
|             if (objectToDestroy != null)
 | |
|                 Object.Destroy(objectToDestroy);
 | |
| #endif
 | |
|         }
 | |
| 
 | |
|         [Conditional("UNITY_EDITOR")]
 | |
|         public static void PushUndo(Object[] thingsToDirty, string operation)
 | |
|         {
 | |
| #if UNITY_EDITOR
 | |
|             if (thingsToDirty == null || !undoEnabled)
 | |
|                 return;
 | |
| 
 | |
|             for (var i = 0; i < thingsToDirty.Length; i++)
 | |
|             {
 | |
|                 if (thingsToDirty[i] is TrackAsset track)
 | |
|                     track.MarkDirtyTrackAndClips();
 | |
|                 EditorUtility.SetDirty(thingsToDirty[i]);
 | |
|             }
 | |
|             Undo.RegisterCompleteObjectUndo(thingsToDirty, UndoName(operation));
 | |
| #endif
 | |
|         }
 | |
| 
 | |
|         [Conditional("UNITY_EDITOR")]
 | |
|         public static void PushUndo(Object thingToDirty, string operation)
 | |
|         {
 | |
| #if UNITY_EDITOR
 | |
|             if (thingToDirty != null && undoEnabled)
 | |
|             {
 | |
|                 var track = thingToDirty as TrackAsset;
 | |
|                 if (track != null)
 | |
|                     track.MarkDirtyTrackAndClips();
 | |
| 
 | |
|                 EditorUtility.SetDirty(thingToDirty);
 | |
|                 Undo.RegisterCompleteObjectUndo(thingToDirty, UndoName(operation));
 | |
|             }
 | |
| #endif
 | |
|         }
 | |
| 
 | |
|         [Conditional("UNITY_EDITOR")]
 | |
|         public static void RegisterCreatedObjectUndo(Object thingCreated, string operation)
 | |
|         {
 | |
| #if UNITY_EDITOR
 | |
|             if (undoEnabled)
 | |
|             {
 | |
|                 Undo.RegisterCreatedObjectUndo(thingCreated, UndoName(operation));
 | |
|             }
 | |
| #endif
 | |
|         }
 | |
| 
 | |
|         internal static string UndoName(string name) => "Timeline " + name;
 | |
| 
 | |
| #if UNITY_EDITOR
 | |
|         /// <summary>
 | |
|         /// Provides stack management of the undo state.
 | |
|         /// </summary>
 | |
|         internal struct DisableUndoGuard : IDisposable
 | |
|         {
 | |
|             internal static bool enableUndo = true;
 | |
|             static readonly Stack<bool> m_UndoStateStack = new Stack<bool>();
 | |
|             bool m_MustDispose;
 | |
|             public DisableUndoGuard(bool disable)
 | |
|             {
 | |
|                 m_MustDispose = true;
 | |
|                 m_UndoStateStack.Push(enableUndo);
 | |
|                 enableUndo = !disable;
 | |
|             }
 | |
| 
 | |
|             public void Dispose()
 | |
|             {
 | |
|                 if (m_MustDispose)
 | |
|                 {
 | |
|                     if (m_UndoStateStack.Count == 0)
 | |
|                     {
 | |
|                         Debug.LogError("UnMatched DisableUndoGuard calls");
 | |
|                         enableUndo = true;
 | |
|                         return;
 | |
|                     }
 | |
|                     enableUndo = m_UndoStateStack.Pop();
 | |
|                     m_MustDispose = false;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Provides an undo state switch.
 | |
|         /// </summary>
 | |
|         internal class DisableUndoScope : IDisposable
 | |
|         {
 | |
|             internal static bool enableUndo => m_Depth == 0;
 | |
|             static int m_Depth;
 | |
|             bool m_MustDispose;
 | |
|             public DisableUndoScope()
 | |
|             {
 | |
|                 m_MustDispose = true;
 | |
|                 m_Depth++;
 | |
|             }
 | |
| 
 | |
|             public void Dispose()
 | |
|             {
 | |
|                 if (m_MustDispose)
 | |
|                 {
 | |
|                     if (m_Depth == 0)
 | |
|                     {
 | |
|                         Debug.LogError("UnMatched DisableUndoScope calls");
 | |
|                         return;
 | |
|                     }
 | |
|                     m_Depth--;
 | |
|                     m_MustDispose = false;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| #endif
 | |
|     }
 | |
| }
 |