using System; using System.Collections.Generic; using System.Linq; using UnityEngine.Timeline; using Object = UnityEngine.Object; namespace UnityEditor.Timeline { /// /// Disposable scope object used to collect multiple items for Undo. /// Automatically filters out duplicates /// struct UndoScope : IDisposable { private static readonly HashSet s_ObjectsToUndo = new HashSet(); private string m_Name; public UndoScope(string name) { m_Name = name; } public void Dispose() { ApplyUndo(m_Name); } public void AddObject(UnityEngine.Object asset) { if (asset != null) s_ObjectsToUndo.Add(asset); } public void AddClip(TimelineClip clip, bool includeAsset) { if (clip != null && clip.GetParentTrack() != null) s_ObjectsToUndo.Add(clip.GetParentTrack()); if (includeAsset && clip != null && clip.asset != null) s_ObjectsToUndo.Add(clip.asset); } public void Add(IEnumerable tracks) { if (tracks == null) return; foreach (var track in tracks) AddObject(track); } public void Add(IEnumerable clips, bool includeAssets) { if (clips == null) return; foreach (var clip in clips) { AddClip(clip, includeAssets); } } public void Add(IEnumerable markers) { if (markers == null) return; foreach (var marker in markers) { if (marker is Object o) AddObject(o); else if (marker != null) AddObject(marker.parent); } } private static void ApplyUndo(string name) { if (s_ObjectsToUndo.Count == 1) TimelineUndo.PushUndo(s_ObjectsToUndo.First(), name); else if (s_ObjectsToUndo.Count > 1) TimelineUndo.PushUndo(s_ObjectsToUndo.ToArray(), name); s_ObjectsToUndo.Clear(); } } }