-
Notifications
You must be signed in to change notification settings - Fork 0
/
ValEnum.cs
329 lines (277 loc) · 9.9 KB
/
ValEnum.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
// MIT License
//
// Copyright (c) 2021 Pixel Precision, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using UnityEngine;
namespace PxPre.Datum
{
/// <summary>
/// Information of possible values for a enum subtype.
/// </summary>
public class Selections
{
/// <summary>
/// The mapping from int values to string values.
///
/// The values should be synced with class member stoi, which is the inverse mapping.
/// </summary>
public Dictionary<int, string> itos = new Dictionary<int, string>();
/// <summary>
/// The mapping from string values to int values.
///
/// The values should be synced with class member itos, which is the inverse mapping.
/// </summary>
public Dictionary<string, int> stoi = new Dictionary<string, int>();
/// <summary>
/// Cached enum conversions for FromEnum<>(). That function takes C# enums and automates
/// turning them into Datum Selections. The first time a new enum subtype is encountered,
/// it is cached in CachedFromEnum in case that enum subtype is retrived again later.
/// </summary>
static Dictionary<System.Type, Selections> CachedFromEnums =
new Dictionary<System.Type, Selections>();
/// <summary>
/// Constructor. Given a list of string, set their int values to the index
/// they appeared in the list.
/// </summary>
/// <param name="sels">The string values for the possible values of the enum.</param>
public Selections(string [] sels)
{
for(int i = 0; i < sels.Length; ++i)
{
itos.Add(i, sels[i]);
stoi.Add(sels[i], i);
}
}
/// <summary>
/// Constructor, given an int=>string mapping.
/// </summary>
/// <param name="itos">The int=>string mapping of possible enum values.</param>
public Selections(Dictionary<int, string> itos)
{
this.itos = itos;
foreach(KeyValuePair<int, string> kvp in itos)
{
if(this.stoi.ContainsKey(kvp.Value) == true)
continue;
this.stoi.Add(kvp.Value, kvp.Key);
}
}
/// <summary>
/// Constructor, given a string=>int mapping.
/// </summary>
/// <param name="stoi">The string=>int mapping of possible enum values.</param>
public Selections(Dictionary<string, int> stoi)
{
this.stoi = stoi;
foreach (KeyValuePair<string, int> kvp in stoi)
{
if (this.itos.ContainsKey(kvp.Value) == true)
continue;
this.itos.Add(kvp.Value, kvp.Key);
}
}
/// <summary>
/// Template factory. Given an enum subtype, turn it into
/// a Selection.
/// </summary>
/// <typeparam name="k">The enum subtype.</typeparam>
/// <returns>The Selections that represents the enum subtype.</returns>
public static Selections FromEnum<k>() where k: System.Enum
{
Selections ret;
if(CachedFromEnums.TryGetValue(typeof(k), out ret) == true)
return ret;
// https://stackoverflow.com/a/6454988
Dictionary<string, int> stoi = new Dictionary<string, int>();
System.Array array = System.Enum.GetValues(typeof(k));
foreach(var v in array)
stoi.Add(v.ToString(), (int)v);
ret = new Selections(stoi);
CachedFromEnums.Add(typeof(k), ret);
return ret;
}
/// <summary>
/// Get the string value of a specified enum value.
/// </summary>
/// <param name="idx">The int value to retrieve the mapped string value for.</param>
/// <returns>The string value mapped to the int parameter value. If none is found, an
/// empty string is returned.</returns>
public string GetString(int idx)
{
if(this.itos.TryGetValue(idx, out string v) == true)
return v;
return idx.ToString();
}
/// <summary>
/// Get the int value of a specified string enum value.
/// </summary>
/// <param name="str">The string value to retrieve the mapped int value for.</param>
/// <returns>An optional returning the mapped int value, or null if the value was not found.</returns>
public int ? GetInt(string str)
{
if(this.stoi.TryGetValue(str, out int i) == true)
return i;
return null;
}
/// <summary>
/// Get an enumerable of all the string values of the enum.
/// </summary>
/// <returns>An enumerable of all the string values of the enum.</returns>
public IEnumerable<string> GetNames()
{
return this.stoi.Keys;
}
}
public class ValEnum : Val
{
/// <summary>
/// The raw enum value.
/// </summary>
public int i;
/// <summary>
/// The possible values for the enum.
/// </summary>
public readonly Selections selections;
public override Type ty { get => Type.Enum; }
public ValEnum(int i, Selections sels)
{
this.selections = sels;
}
public static ValEnum FromEnum<k>(int i) where k : System.Enum
{
Selections sels = Selections.FromEnum<k>();
return new ValEnum(i, sels);
}
public override bool GetBool()
{
return (this.i != 0) ? true : false;
}
public override int GetInt()
{
return this.i;
}
public override uint GetUInt()
{
return (uint)this.i;
}
public override long GetInt64()
{
return (long)this.i;
}
public override ulong GetUInt64()
{
return (ulong)this.i;
}
public override float GetFloat()
{
return this.i;
}
public override double GetFloat64()
{
return this.i;
}
public override bool SetBool(bool v)
{
this.i = v ? 1 : 0;
return true;
}
public override bool SetInt(int v)
{
this.i = v;
return true;
}
public override bool SetUInt(uint v)
{
this.i = (int)v;
return true;
}
public override bool SetInt64(long v)
{
this.i = (int)v;
return true;
}
public override bool SetUInt64(ulong v)
{
this.i = (int)v;
return true;
}
public override bool SetFloat(float v)
{
this.i = (int)v;
return true;
}
public override bool SetFloat64(double v)
{
this.i = (int)v;
return true;
}
public override string GetString()
{
return this.selections.GetString(this.i);
}
public override bool SetString(string v)
{
int ? idx = this.selections.GetInt(v);
if(idx.HasValue)
{
this.i = idx.Value;
return true;
}
int ip;
if(int.TryParse(v, out ip) == false)
return false;
this.i = ip;
return true;
}
public override Val Clone()
{
return new ValEnum(this.i, this.selections);
}
public override bool SetValue(Val v)
{
this.i = v.GetInt();
return true;
}
public override Val Add(Val vb)
{
return new ValInt(this.i + vb.GetInt());
}
public override Val Mul(Val vb)
{
return new ValInt(this.i * vb.GetInt());
}
public override Val Min(Val vb)
{
return new ValInt(Mathf.Min(this.i, vb.GetInt()));
}
public override Val Max(Val vb)
{
return new ValInt(Mathf.Max(this.i, vb.GetInt()));
}
public override bool SetIndex(int idx, Val v) => false;
public override bool SetIndex(string idx, Val v) => false;
public override bool SetIndex(Val idx, Val v) => false;
public override bool Equivalent(Val v)
{
return this.i == v.GetInt();
}
}
}