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.MarkDirty();
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.MarkDirty();
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
///
/// Provides stack management of the undo state.
///
internal struct DisableUndoGuard : IDisposable
{
internal static bool enableUndo = true;
static readonly Stack m_UndoStateStack = new Stack();
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;
}
}
}
///
/// Provides an undo state switch.
///
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
}
}