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}