using System; using System.Collections; using System.Collections.Generic; namespace Unity.VisualScripting { public class MergedCollection : IMergedCollection { public MergedCollection() { collections = new Dictionary>(); } private readonly Dictionary> collections; public int Count { get { int count = 0; foreach (var collection in collections.Values) { count += collection.Count; } return count; } } public bool IsReadOnly => false; public void Include(ICollection collection) where TI : T { collections.Add(typeof(TI), new VariantCollection(collection)); } public bool Includes() where TI : T { return Includes(typeof(TI)); } public bool Includes(Type implementationType) { return GetCollectionForType(implementationType, false) != null; } public ICollection ForType() where TI : T { return ((VariantCollection)GetCollectionForType(typeof(TI))).implementation; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { foreach (var collection in collections.Values) { foreach (var item in collection) { yield return item; } } } private ICollection GetCollectionForItem(T item) { Ensure.That(nameof(item)).IsNotNull(item); return GetCollectionForType(item.GetType()); } private ICollection GetCollectionForType(Type type, bool throwOnFail = true) { if (collections.ContainsKey(type)) { return collections[type]; } foreach (var collectionByType in collections) { if (collectionByType.Key.IsAssignableFrom(type)) { return collectionByType.Value; } } if (throwOnFail) { throw new InvalidOperationException($"No sub-collection available for type '{type}'."); } else { return null; } } public bool Contains(T item) { return GetCollectionForItem(item).Contains(item); } public virtual void Add(T item) { GetCollectionForItem(item).Add(item); } public virtual void Clear() { foreach (var collection in collections.Values) { collection.Clear(); } } public virtual bool Remove(T item) { return GetCollectionForItem(item).Remove(item); } public void CopyTo(T[] 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 collection in collections.Values) { collection.CopyTo(array, arrayIndex + i); i += collection.Count; } } } }