Tanoda
MultiTypedReference.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.Generic;
11using UnityEngine;
12#if UNITY_EDITOR
13using UnityEditor;
14#endif
15
16namespace Leap.Unity {
17
27 public abstract class MultiTypedReference<BaseType> where BaseType : class {
28 public abstract void Clear();
29 public abstract BaseType Value { get; set; }
30 }
31
32 public static class MultiTypedReferenceUtil {
33
34#if UNITY_EDITOR
35 public const string ID_NAME_TABLE = "abcdefghijklmnopqrstuvwxyz";
36
37 public static SerializedProperty GetReferenceProperty(SerializedProperty property) {
38 var indexProp = property.FindPropertyRelative("_index");
39 int indexValue = indexProp.intValue;
40 if (indexValue == -1) {
41 return null;
42 }
43
44 string listPropName = "_" + ID_NAME_TABLE[indexValue];
45 var listProp = property.FindPropertyRelative(listPropName);
46 return listProp.GetArrayElementAtIndex(0);
47 }
48#endif
49 }
50
51 public class MultiTypedReference<BaseType, A, B> : MultiTypedReference<BaseType>
52 where BaseType : class
53 where A : BaseType
54 where B : BaseType {
55
56 [SerializeField]
57 protected int _index = -1;
58
59 [SerializeField]
60 private List<A> _a = new List<A>();
61
62 [SerializeField]
63 private List<B> _b = new List<B>();
64
65 [NonSerialized]
66 protected BaseType _cachedValue;
67
68 public override void Clear() {
69 _cachedValue = null;
70
71 if (_index == 0) {
72 _a.Clear();
73 } else if (_index == 1) {
74 _b.Clear();
75 }
76
77 _index = -1;
78 }
79
80 public sealed override BaseType Value {
81 get {
82 if (_cachedValue != null) {
83 return _cachedValue;
84 }
85
87
88 return _cachedValue;
89 }
90 set {
91 Clear();
93 _cachedValue = value;
94 }
95 }
96
97 protected virtual BaseType internalGet() {
98 if (_index == -1) {
99 return null;
100 } else if (_index == 0) {
101 return _cachedValue = _a[0];
102 } else if (_index == 1) {
103 return _cachedValue = _b[0];
104 } else {
105 throw new Exception("Invalid index " + _index);
106 }
107 }
108
109 protected virtual void internalSetAfterClear(BaseType obj) {
110 if (obj == null) {
111 _index = -1;
112 } else if (obj is A) {
113 _a.Add((A)obj);
114 _index = 0;
115 } else if (obj is B) {
116 _b.Add((B)obj);
117 _index = 1;
118 } else {
119 throw new ArgumentException("The type " + obj.GetType().Name + " is not supported by this reference.");
120 }
121 }
122 }
123
124 public class MultiTypedReference<BaseType, A, B, C> : MultiTypedReference<BaseType, A, B>
125 where BaseType : class
126 where A : BaseType
127 where B : BaseType
128 where C : BaseType {
129
130 [SerializeField]
131 private List<C> _c = new List<C>();
132
133 public override void Clear() {
134 if (_index == 2) {
135 _c.Clear();
136 }
137
138 base.Clear();
139 }
140
141 protected override BaseType internalGet() {
142 if (_index == 2) {
143 return _c[0];
144 } else {
145 return base.internalGet();
146 }
147 }
148
149 protected override void internalSetAfterClear(BaseType obj) {
150 if (obj is C) {
151 _c.Add((C)obj);
152 _index = 2;
153 } else {
154 base.internalSetAfterClear(obj);
155 }
156 }
157 }
158
159 public class MultiTypedReference<BaseType, A, B, C, D> : MultiTypedReference<BaseType, A, B, C>
160 where BaseType : class
161 where A : BaseType
162 where B : BaseType
163 where C : BaseType
164 where D : BaseType {
165
166 [SerializeField]
167 private List<D> _d = new List<D>();
168
169 public override void Clear() {
170 if (_index == 3) {
171 _d.Clear();
172 }
173
174 base.Clear();
175 }
176
177 protected override BaseType internalGet() {
178 if (_index == 3) {
179 return _d[0];
180 } else {
181 return base.internalGet();
182 }
183 }
184
185 protected override void internalSetAfterClear(BaseType obj) {
186 if (obj is D) {
187 _d.Add((D)obj);
188 _index = 3;
189 } else {
190 base.internalSetAfterClear(obj);
191 }
192 }
193 }
194}
Represents a single reference to a value of type BaseType.
override void internalSetAfterClear(BaseType obj)
virtual void internalSetAfterClear(BaseType obj)