A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections; 3using System.Collections.Generic; 4 5namespace Unity.VisualScripting 6{ 7 public class MergedCollection<T> : IMergedCollection<T> 8 { 9 public MergedCollection() 10 { 11 collections = new Dictionary<Type, ICollection<T>>(); 12 } 13 14 private readonly Dictionary<Type, ICollection<T>> collections; 15 16 public int Count 17 { 18 get 19 { 20 int count = 0; 21 22 foreach (var collection in collections.Values) 23 { 24 count += collection.Count; 25 } 26 27 return count; 28 } 29 } 30 31 public bool IsReadOnly => false; 32 33 public void Include<TI>(ICollection<TI> collection) where TI : T 34 { 35 collections.Add(typeof(TI), new VariantCollection<T, TI>(collection)); 36 } 37 38 public bool Includes<TI>() where TI : T 39 { 40 return Includes(typeof(TI)); 41 } 42 43 public bool Includes(Type implementationType) 44 { 45 return GetCollectionForType(implementationType, false) != null; 46 } 47 48 public ICollection<TI> ForType<TI>() where TI : T 49 { 50 return ((VariantCollection<T, TI>)GetCollectionForType(typeof(TI))).implementation; 51 } 52 53 IEnumerator IEnumerable.GetEnumerator() 54 { 55 return GetEnumerator(); 56 } 57 58 public IEnumerator<T> GetEnumerator() 59 { 60 foreach (var collection in collections.Values) 61 { 62 foreach (var item in collection) 63 { 64 yield return item; 65 } 66 } 67 } 68 69 private ICollection<T> GetCollectionForItem(T item) 70 { 71 Ensure.That(nameof(item)).IsNotNull(item); 72 73 return GetCollectionForType(item.GetType()); 74 } 75 76 private ICollection<T> GetCollectionForType(Type type, bool throwOnFail = true) 77 { 78 if (collections.ContainsKey(type)) 79 { 80 return collections[type]; 81 } 82 83 foreach (var collectionByType in collections) 84 { 85 if (collectionByType.Key.IsAssignableFrom(type)) 86 { 87 return collectionByType.Value; 88 } 89 } 90 91 if (throwOnFail) 92 { 93 throw new InvalidOperationException($"No sub-collection available for type '{type}'."); 94 } 95 else 96 { 97 return null; 98 } 99 } 100 101 public bool Contains(T item) 102 { 103 return GetCollectionForItem(item).Contains(item); 104 } 105 106 public virtual void Add(T item) 107 { 108 GetCollectionForItem(item).Add(item); 109 } 110 111 public virtual void Clear() 112 { 113 foreach (var collection in collections.Values) 114 { 115 collection.Clear(); 116 } 117 } 118 119 public virtual bool Remove(T item) 120 { 121 return GetCollectionForItem(item).Remove(item); 122 } 123 124 public void CopyTo(T[] array, int arrayIndex) 125 { 126 if (array == null) 127 { 128 throw new ArgumentNullException(nameof(array)); 129 } 130 131 if (arrayIndex < 0) 132 { 133 throw new ArgumentOutOfRangeException(nameof(arrayIndex)); 134 } 135 136 if (array.Length - arrayIndex < Count) 137 { 138 throw new ArgumentException(); 139 } 140 141 var i = 0; 142 143 foreach (var collection in collections.Values) 144 { 145 collection.CopyTo(array, arrayIndex + i); 146 i += collection.Count; 147 } 148 } 149 } 150}