Tanoda
MultiTypedList.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System;
10using System.Collections;
11using System.Collections.Generic;
12using UnityEngine;
13#if UNITY_EDITOR
14using UnityEditor;
15#endif
16
17namespace Leap.Unity {
18
19 public abstract class MultiTypedList {
20 [Serializable]
21 public struct Key {
22 public int id;
23 public int index;
24 }
25 }
26
36 public abstract class MultiTypedList<BaseType> : MultiTypedList, IList<BaseType> {
37 public abstract int Count { get; }
38
39 public bool IsReadOnly {
40 get {
41 return false;
42 }
43 }
44
45 public abstract BaseType this[int index] { get; set; }
46
47 public abstract void Add(BaseType obj);
48
49 public abstract void Clear();
50
51 public bool Contains(BaseType item) {
52 for (int i = 0; i < Count; i++) {
53 if (this[i].Equals(item)) {
54 return true;
55 }
56 }
57 return false;
58 }
59
60 public void CopyTo(BaseType[] array, int arrayIndex) {
61 for (int i = 0; i < Count; i++) {
62 array[i + arrayIndex] = this[i];
63 }
64 }
65
67 return new Enumerator(this);
68 }
69
70 public int IndexOf(BaseType item) {
71 for (int i = 0; i < Count; i++) {
72 if (this[i].Equals(item)) {
73 return i;
74 }
75 }
76 return -1;
77 }
78
79 public abstract void Insert(int index, BaseType item);
80
81 public bool Remove(BaseType item) {
82 int index = IndexOf(item);
83 if (index >= 0) {
84 RemoveAt(index);
85 return true;
86 } else {
87 return false;
88 }
89 }
90
91 public abstract void RemoveAt(int index);
92
93 public struct Enumerator : IEnumerator<BaseType> {
94 private MultiTypedList<BaseType> _list;
95 private int _index;
96 private BaseType _current;
97
99 _list = list;
100 _index = 0;
101 _current = default(BaseType);
102 }
103
104 public BaseType Current {
105 get {
106 return _current;
107 }
108 }
109
110 object IEnumerator.Current {
111 get {
112 throw new NotImplementedException();
113 }
114 }
115
116 public void Dispose() {
117 _list = null;
118 _current = default(BaseType);
119 }
120
121 public bool MoveNext() {
122 if (_index >= _list.Count) {
123 return false;
124 } else {
125 _current = _list[_index++];
126 return true;
127 }
128 }
129
130 public void Reset() {
131 _index = 0;
132 _current = default(BaseType);
133 }
134 }
135
136 IEnumerator IEnumerable.GetEnumerator() {
137 return new Enumerator(this);
138 }
139
140 IEnumerator<BaseType> IEnumerable<BaseType>.GetEnumerator() {
141 return new Enumerator(this);
142 }
143 }
144
145 public class MultiTypedListUtil {
146
147#if UNITY_EDITOR
148 public const string ID_NAME_TABLE = "abcdefghijklmnopqrstuvwxyz";
149 public static Dictionary<int, string> _nameCache = new Dictionary<int, string>();
150 private static string getName(int id) {
151 string name;
152 if (!_nameCache.TryGetValue(id, out name)) {
153 name = "_" + ID_NAME_TABLE[id];
154 _nameCache[id] = name;
155 }
156 return name;
157 }
158
159 public static SerializedProperty GetTableProperty(SerializedProperty list) {
160 return list.FindPropertyRelative("_table");
161 }
162
163 public static SerializedProperty GetArrayElementAtIndex(SerializedProperty list, int index) {
164 var tableProp = GetTableProperty(list);
165 var idIndexProp = tableProp.GetArrayElementAtIndex(index);
166
167 return GetReferenceProperty(list, idIndexProp);
168 }
169
170 public static SerializedProperty GetReferenceProperty(SerializedProperty list, SerializedProperty idIndexProp) {
171 var idProp = idIndexProp.FindPropertyRelative("id");
172 var indexProp = idIndexProp.FindPropertyRelative("index");
173
174 string listPropName = getName(idProp.intValue);
175 var listProp = list.FindPropertyRelative(listPropName);
176 return listProp.GetArrayElementAtIndex(indexProp.intValue);
177 }
178#endif
179 }
180
181 [Serializable]
182 public class MultiTypedList<BaseType, A, B> : MultiTypedList<BaseType>
183 where A : BaseType
184 where B : BaseType {
185
186 [SerializeField]
187 private List<Key> _table = new List<Key>();
188
189 [SerializeField]
190 private List<A> _a = new List<A>();
191
192 [SerializeField]
193 private List<B> _b = new List<B>();
194
195 public override int Count {
196 get {
197 return _table.Count;
198 }
199 }
200
201 public override void Add(BaseType obj) {
202 _table.Add(addInternal(obj));
203 }
204
205 public override void Clear() {
206 _table.Clear();
207 _a.Clear();
208 _b.Clear();
209 }
210
211 public override void Insert(int index, BaseType obj) {
212 _table.Insert(index, addInternal(obj));
213
214 }
215
216 public override void RemoveAt(int index) {
217 var removedKey = _table[index];
218 _table.RemoveAt(index);
219
220 getList(removedKey.id).RemoveAt(removedKey.index);
221
222 for (int i = 0; i < _table.Count; i++) {
223 var key = _table[i];
224 if (key.id == removedKey.id && key.index > removedKey.index) {
225 key.index--;
226 _table[i] = key;
227 }
228 }
229 }
230
231 public override BaseType this[int index] {
232 get {
233 Key key = _table[index];
234 return (BaseType)getList(key.id)[key.index];
235 }
236 set {
237 Key oldKey = _table[index];
238 getList(oldKey.id).RemoveAt(oldKey.index);
239
240 Key newKey = addInternal(value);
241 _table[index] = newKey;
242 }
243 }
244
245 protected Key addHelper(IList list, BaseType instance, int id) {
246 Key key = new Key() {
247 id = id,
248 index = list.Count
249 };
250 list.Add(instance);
251 return key;
252 }
253
254 protected virtual Key addInternal(BaseType obj) {
255 if (obj is A) {
256 return addHelper(_a, obj, 0);
257 } else if (obj is B) {
258 return addHelper(_b, obj, 1);
259 } else {
260 throw new ArgumentException("This multi typed list does not support type " + obj.GetType().Name);
261 }
262 }
263
264 protected virtual IList getList(int id) {
265 if (id == 0) {
266 return _a;
267 } else if (id == 1) {
268 return _b;
269 } else {
270 throw new Exception("This multi typed list does not have a list with id " + id);
271 }
272 }
273 }
274
275 public class MultiTypedList<BaseType, A, B, C> : MultiTypedList<BaseType, A, B>
276 where A : BaseType
277 where B : BaseType
278 where C : BaseType {
279
280 [SerializeField]
281 private List<C> _c = new List<C>();
282
283 protected override Key addInternal(BaseType obj) {
284 return obj is C ? addHelper(_c, obj, 2) : base.addInternal(obj);
285 }
286
287 protected override IList getList(int id) {
288 return id == 2 ? _c : base.getList(id);
289 }
290
291 public override void Clear() {
292 base.Clear();
293 _c.Clear();
294 }
295 }
296
297 public class MultiTypedList<BaseType, A, B, C, D> : MultiTypedList<BaseType, A, B, C>
298 where A : BaseType
299 where B : BaseType
300 where C : BaseType
301 where D : BaseType {
302
303 [SerializeField]
304 private List<D> _d = new List<D>();
305
306 protected override Key addInternal(BaseType obj) {
307 return obj is D ? addHelper(_d, obj, 3) : base.addInternal(obj);
308 }
309
310 protected override IList getList(int id) {
311 return id == 3 ? _d : base.getList(id);
312 }
313
314 public override void Clear() {
315 base.Clear();
316 _d.Clear();
317 }
318 }
319
320 public class MultiTypedList<BaseType, A, B, C, D, E> : MultiTypedList<BaseType, A, B, C, D>
321 where A : BaseType
322 where B : BaseType
323 where C : BaseType
324 where D : BaseType
325 where E : BaseType {
326
327 [SerializeField]
328 private List<E> _e = new List<E>();
329
330 protected override Key addInternal(BaseType obj) {
331 return obj is E ? addHelper(_e, obj, 4) : base.addInternal(obj);
332 }
333
334 protected override IList getList(int id) {
335 return id == 4 ? _e : base.getList(id);
336 }
337
338 public override void Clear() {
339 base.Clear();
340 _e.Clear();
341 }
342 }
343
344 public class MultiTypedList<BaseType, A, B, C, D, E, F> : MultiTypedList<BaseType, A, B, C, D, E>
345 where A : BaseType
346 where B : BaseType
347 where C : BaseType
348 where D : BaseType
349 where E : BaseType
350 where F : BaseType {
351
352 [SerializeField]
353 private List<F> _f = new List<F>();
354
355 protected override Key addInternal(BaseType obj) {
356 return obj is F ? addHelper(_f, obj, 5) : base.addInternal(obj);
357 }
358
359 protected override IList getList(int id) {
360 return id == 5 ? _f : base.getList(id);
361 }
362
363 public override void Clear() {
364 base.Clear();
365 _f.Clear();
366 }
367 }
368
369 public class MultiTypedList<BaseType, A, B, C, D, E, F, G> : MultiTypedList<BaseType, A, B, C, D, E, F>
370 where A : BaseType
371 where B : BaseType
372 where C : BaseType
373 where D : BaseType
374 where E : BaseType
375 where F : BaseType
376 where G : BaseType {
377
378 [SerializeField]
379 private List<G> _g = new List<G>();
380
381 protected override Key addInternal(BaseType obj) {
382 return obj is G ? addHelper(_g, obj, 6) : base.addInternal(obj);
383 }
384
385 protected override IList getList(int id) {
386 return id == 6 ? _g : base.getList(id);
387 }
388
389 public override void Clear() {
390 base.Clear();
391 _g.Clear();
392 }
393 }
394
395 public class MultiTypedList<BaseType, A, B, C, D, E, F, G, H> : MultiTypedList<BaseType, A, B, C, D, E, F, G>
396 where A : BaseType
397 where B : BaseType
398 where C : BaseType
399 where D : BaseType
400 where E : BaseType
401 where F : BaseType
402 where G : BaseType
403 where H : BaseType {
404
405 [SerializeField]
406 private List<H> _h = new List<H>();
407
408 protected override Key addInternal(BaseType obj) {
409 return obj is H ? addHelper(_h, obj, 7) : base.addInternal(obj);
410 }
411
412 protected override IList getList(int id) {
413 return id == 7 ? _h : base.getList(id);
414 }
415
416 public override void Clear() {
417 base.Clear();
418 _h.Clear();
419 }
420 }
421}
Represents an ordered collection of objects of type BaseType.
abstract void Add(BaseType obj)
bool Remove(BaseType item)
override void Insert(int index, BaseType obj)
int IndexOf(BaseType item)
virtual IList getList(int id)
Key addHelper(IList list, BaseType instance, int id)
abstract void Clear()
override IList getList(int id)
override void Add(BaseType obj)
bool Contains(BaseType item)
override Key addInternal(BaseType obj)
abstract void RemoveAt(int index)
void CopyTo(BaseType[] array, int arrayIndex)
virtual Key addInternal(BaseType obj)
override void RemoveAt(int index)
abstract void Insert(int index, BaseType item)
Enumerator(MultiTypedList< BaseType > list)