using System; using System.Collections; using System.Collections.Generic; namespace Unity.VisualScripting { public sealed class GraphSelection : ISet { public GraphSelection() : base() { set = new HashSet(); } public event Action changed; private readonly HashSet set; public int Count => set.Count; public bool IsReadOnly => false; private void OnChange() { changed?.Invoke(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public HashSet.Enumerator GetEnumerator() { return set.GetEnumerator(); } public void Select(IGraphElement item) { Clear(); Add(item); } public void Select(IEnumerable items) { Clear(); UnionWith(items); } public bool Contains(IGraphElement item) { Ensure.That(nameof(item)).IsNotNull(item); return set.Contains(item); } public bool Add(IGraphElement item) { Ensure.That(nameof(item)).IsNotNull(item); if (set.Add(item)) { OnChange(); return true; } else { return false; } } public bool Remove(IGraphElement item) { Ensure.That(nameof(item)).IsNotNull(item); if (set.Remove(item)) { OnChange(); return true; } else { return false; } } public void Clear() { if (set.Count == 0) { return; } set.Clear(); OnChange(); } #region Set Logic public void ExceptWith(IEnumerable other) { var countBefore = set.Count; set.ExceptWith(other); if (countBefore != set.Count) { OnChange(); } } public void IntersectWith(IEnumerable other) { var countBefore = set.Count; set.IntersectWith(other); if (countBefore != set.Count) { OnChange(); } } public void SymmetricExceptWith(IEnumerable other) { var countBefore = set.Count; set.SymmetricExceptWith(other); if (countBefore != set.Count) { OnChange(); } } public void UnionWith(IEnumerable other) { var countBefore = set.Count; set.UnionWith(other); if (countBefore != set.Count) { OnChange(); } } public bool IsProperSubsetOf(IEnumerable other) { return set.IsProperSubsetOf(other); } public bool IsProperSupersetOf(IEnumerable other) { return set.IsProperSupersetOf(other); } public bool IsSubsetOf(IEnumerable other) { return set.IsSubsetOf(other); } public bool IsSupersetOf(IEnumerable other) { return set.IsSupersetOf(other); } public bool Overlaps(IEnumerable other) { return set.Overlaps(other); } public bool SetEquals(IEnumerable other) { return set.SetEquals(other); } public int RemoveWhere(Predicate match) { return set.RemoveWhere(match); } #endregion #region ICollection void ICollection.Add(IGraphElement item) { if (set.Add(item)) { OnChange(); } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void CopyTo(IGraphElement[] array, int arrayIndex) { if (array == null) { throw new ArgumentNullException(nameof(array)); } if (arrayIndex < 0) { throw new ArgumentOutOfRangeException(nameof(arrayIndex)); } if (array.Length - arrayIndex < Count) { throw new ArgumentException(); } var i = 0; foreach (var item in this) { array[i + arrayIndex] = item; i++; } } #endregion } }