using System; using System.Collections.Generic; using UnityEngine; namespace UnityEditor.U2D.Animation { [Serializable] internal abstract class SerializableSelection : ISelection, ISerializationCallbackReceiver { internal readonly static int kInvalidID = -1; [SerializeField] private T[] m_Keys = new T[0]; private HashSet m_Selection = new HashSet(); private HashSet m_TemporalSelection = new HashSet(); private bool m_SelectionInProgress = false; public int Count { get { return m_Selection.Count + m_TemporalSelection.Count; } } public T activeElement { get { return First(); } set { Clear(); Select(value, true); } } public T[] elements { get { var set = m_Selection; if (m_SelectionInProgress) { var union = new HashSet(m_Selection); union.UnionWith(m_TemporalSelection); set = union; } return new List(set).ToArray(); } set { Clear(); foreach(var element in value) Select(element, true); } } protected abstract T GetInvalidElement(); public void Clear() { GetSelection().Clear(); } public void BeginSelection() { m_SelectionInProgress = true; Clear(); } public void EndSelection(bool select) { m_SelectionInProgress = false; if (select) m_Selection.UnionWith(m_TemporalSelection); else m_Selection.ExceptWith(m_TemporalSelection); m_TemporalSelection.Clear(); } public void Select(T element, bool select) { if(EqualityComparer.Default.Equals(element, GetInvalidElement())) return; if (select) GetSelection().Add(element); else if (Contains(element)) GetSelection().Remove(element); } public bool Contains(T element) { return m_Selection.Contains(element) || m_TemporalSelection.Contains(element); } private HashSet GetSelection() { if (m_SelectionInProgress) return m_TemporalSelection; return m_Selection; } private T First() { T element = First(m_Selection); if(EqualityComparer.Default.Equals(element, GetInvalidElement())) element = First(m_TemporalSelection); return element; } private T First(HashSet set) { if(set.Count == 0) return GetInvalidElement(); using (var enumerator = set.GetEnumerator()) { Debug.Assert(enumerator.MoveNext()); return enumerator.Current; } } void ISerializationCallbackReceiver.OnBeforeSerialize() { m_Keys = new List(m_Selection).ToArray(); } void ISerializationCallbackReceiver.OnAfterDeserialize() { elements = m_Keys; } } }