Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
PropertyValue.cs
Go to the documentation of this file.
3
5
6internal readonly struct PropertyValue
7{
8 [StructLayout(LayoutKind.Explicit)]
9 public struct Scalar
10 {
11 [FieldOffset(0)]
12 public bool AsBoolean;
13
14 [FieldOffset(0)]
15 public byte AsByte;
16
17 [FieldOffset(0)]
18 public sbyte AsSByte;
19
20 [FieldOffset(0)]
21 public char AsChar;
22
23 [FieldOffset(0)]
24 public short AsInt16;
25
26 [FieldOffset(0)]
27 public ushort AsUInt16;
28
29 [FieldOffset(0)]
30 public int AsInt32;
31
32 [FieldOffset(0)]
33 public uint AsUInt32;
34
35 [FieldOffset(0)]
36 public long AsInt64;
37
38 [FieldOffset(0)]
39 public ulong AsUInt64;
40
41 [FieldOffset(0)]
43
44 [FieldOffset(0)]
46
47 [FieldOffset(0)]
48 public float AsSingle;
49
50 [FieldOffset(0)]
51 public double AsDouble;
52
53 [FieldOffset(0)]
54 public Guid AsGuid;
55
56 [FieldOffset(0)]
58
59 [FieldOffset(0)]
61
62 [FieldOffset(0)]
64
65 [FieldOffset(0)]
66 public decimal AsDecimal;
67 }
68
69 private abstract class TypeHelper
70 {
71 public abstract Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property);
72
73 protected static Delegate GetGetMethod(PropertyInfo property, Type propertyType)
74 {
75 return property.GetMethod.CreateDelegate(typeof(Func<, >).MakeGenericType(property.DeclaringType, propertyType));
76 }
77 }
78
79 private sealed class ReferenceTypeHelper<TContainer> : TypeHelper where TContainer : class
80 {
81 public override Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property)
82 {
83 Type type = property.PropertyType;
84 if (!type.IsValueType)
85 {
86 Func<TContainer, object> getter = (Func<TContainer, object>)TypeHelper.GetGetMethod(property, type);
87 return (PropertyValue container) => new PropertyValue(getter((TContainer)container.ReferenceValue));
88 }
89 if (type.IsEnum)
90 {
92 }
93 if (type == typeof(bool))
94 {
95 Func<TContainer, bool> f = (Func<TContainer, bool>)TypeHelper.GetGetMethod(property, type);
96 return (PropertyValue container) => new PropertyValue(f((TContainer)container.ReferenceValue));
97 }
98 if (type == typeof(byte))
99 {
100 Func<TContainer, byte> f2 = (Func<TContainer, byte>)TypeHelper.GetGetMethod(property, type);
101 return (PropertyValue container) => new PropertyValue(f2((TContainer)container.ReferenceValue));
102 }
103 if (type == typeof(sbyte))
104 {
105 Func<TContainer, sbyte> f3 = (Func<TContainer, sbyte>)TypeHelper.GetGetMethod(property, type);
106 return (PropertyValue container) => new PropertyValue(f3((TContainer)container.ReferenceValue));
107 }
108 if (type == typeof(char))
109 {
110 Func<TContainer, char> f4 = (Func<TContainer, char>)TypeHelper.GetGetMethod(property, type);
111 return (PropertyValue container) => new PropertyValue(f4((TContainer)container.ReferenceValue));
112 }
113 if (type == typeof(short))
114 {
115 Func<TContainer, short> f5 = (Func<TContainer, short>)TypeHelper.GetGetMethod(property, type);
116 return (PropertyValue container) => new PropertyValue(f5((TContainer)container.ReferenceValue));
117 }
118 if (type == typeof(ushort))
119 {
120 Func<TContainer, ushort> f6 = (Func<TContainer, ushort>)TypeHelper.GetGetMethod(property, type);
121 return (PropertyValue container) => new PropertyValue(f6((TContainer)container.ReferenceValue));
122 }
123 if (type == typeof(int))
124 {
125 Func<TContainer, int> f7 = (Func<TContainer, int>)TypeHelper.GetGetMethod(property, type);
126 return (PropertyValue container) => new PropertyValue(f7((TContainer)container.ReferenceValue));
127 }
128 if (type == typeof(uint))
129 {
130 Func<TContainer, uint> f8 = (Func<TContainer, uint>)TypeHelper.GetGetMethod(property, type);
131 return (PropertyValue container) => new PropertyValue(f8((TContainer)container.ReferenceValue));
132 }
133 if (type == typeof(long))
134 {
135 Func<TContainer, long> f9 = (Func<TContainer, long>)TypeHelper.GetGetMethod(property, type);
136 return (PropertyValue container) => new PropertyValue(f9((TContainer)container.ReferenceValue));
137 }
138 if (type == typeof(ulong))
139 {
140 Func<TContainer, ulong> f10 = (Func<TContainer, ulong>)TypeHelper.GetGetMethod(property, type);
141 return (PropertyValue container) => new PropertyValue(f10((TContainer)container.ReferenceValue));
142 }
143 if (type == typeof(IntPtr))
144 {
145 Func<TContainer, IntPtr> f11 = (Func<TContainer, IntPtr>)TypeHelper.GetGetMethod(property, type);
146 return (PropertyValue container) => new PropertyValue(f11((TContainer)container.ReferenceValue));
147 }
148 if (type == typeof(UIntPtr))
149 {
150 Func<TContainer, UIntPtr> f12 = (Func<TContainer, UIntPtr>)TypeHelper.GetGetMethod(property, type);
151 return (PropertyValue container) => new PropertyValue(f12((TContainer)container.ReferenceValue));
152 }
153 if (type == typeof(float))
154 {
155 Func<TContainer, float> f13 = (Func<TContainer, float>)TypeHelper.GetGetMethod(property, type);
156 return (PropertyValue container) => new PropertyValue(f13((TContainer)container.ReferenceValue));
157 }
158 if (type == typeof(double))
159 {
160 Func<TContainer, double> f14 = (Func<TContainer, double>)TypeHelper.GetGetMethod(property, type);
161 return (PropertyValue container) => new PropertyValue(f14((TContainer)container.ReferenceValue));
162 }
163 if (type == typeof(Guid))
164 {
165 Func<TContainer, Guid> f15 = (Func<TContainer, Guid>)TypeHelper.GetGetMethod(property, type);
166 return (PropertyValue container) => new PropertyValue(f15((TContainer)container.ReferenceValue));
167 }
168 if (type == typeof(DateTime))
169 {
170 Func<TContainer, DateTime> f16 = (Func<TContainer, DateTime>)TypeHelper.GetGetMethod(property, type);
171 return (PropertyValue container) => new PropertyValue(f16((TContainer)container.ReferenceValue));
172 }
173 if (type == typeof(DateTimeOffset))
174 {
175 Func<TContainer, DateTimeOffset> f17 = (Func<TContainer, DateTimeOffset>)TypeHelper.GetGetMethod(property, type);
176 return (PropertyValue container) => new PropertyValue(f17((TContainer)container.ReferenceValue));
177 }
178 if (type == typeof(TimeSpan))
179 {
180 Func<TContainer, TimeSpan> f18 = (Func<TContainer, TimeSpan>)TypeHelper.GetGetMethod(property, type);
181 return (PropertyValue container) => new PropertyValue(f18((TContainer)container.ReferenceValue));
182 }
183 if (type == typeof(decimal))
184 {
185 Func<TContainer, decimal> f19 = (Func<TContainer, decimal>)TypeHelper.GetGetMethod(property, type);
186 return (PropertyValue container) => new PropertyValue(f19((TContainer)container.ReferenceValue));
187 }
188 return (PropertyValue container) => new PropertyValue(property.GetValue(container.ReferenceValue));
189 }
190 }
191
192 private readonly object _reference;
193
194 private readonly Scalar _scalar;
195
196 private readonly int _scalarLength;
197
198 public object ReferenceValue => _reference;
199
201
203
204 private PropertyValue(object value)
205 {
207 _scalar = default(Scalar);
208 _scalarLength = 0;
209 }
210
211 private PropertyValue(Scalar scalar, int scalarLength)
212 {
213 _reference = null;
214 _scalar = scalar;
215 _scalarLength = scalarLength;
216 }
217
218 private PropertyValue(bool value)
219 : this(new Scalar
220 {
221 AsBoolean = value
222 }, 1)
223 {
224 }
225
226 private PropertyValue(byte value)
227 : this(new Scalar
228 {
229 AsByte = value
230 }, 1)
231 {
232 }
233
234 private PropertyValue(sbyte value)
235 : this(new Scalar
236 {
237 AsSByte = value
238 }, 1)
239 {
240 }
241
242 private PropertyValue(char value)
243 : this(new Scalar
244 {
245 AsChar = value
246 }, 2)
247 {
248 }
249
250 private PropertyValue(short value)
251 : this(new Scalar
252 {
253 AsInt16 = value
254 }, 2)
255 {
256 }
257
258 private PropertyValue(ushort value)
259 : this(new Scalar
260 {
261 AsUInt16 = value
262 }, 2)
263 {
264 }
265
266 private PropertyValue(int value)
267 : this(new Scalar
268 {
269 AsInt32 = value
270 }, 4)
271 {
272 }
273
274 private PropertyValue(uint value)
275 : this(new Scalar
276 {
277 AsUInt32 = value
278 }, 4)
279 {
280 }
281
282 private PropertyValue(long value)
283 : this(new Scalar
284 {
285 AsInt64 = value
286 }, 8)
287 {
288 }
289
290 private PropertyValue(ulong value)
291 : this(new Scalar
292 {
293 AsUInt64 = value
294 }, 8)
295 {
296 }
297
298 private unsafe PropertyValue(IntPtr value)
299 : this(new Scalar
300 {
301 AsIntPtr = value
302 }, sizeof(IntPtr))
303 {
304 }
305
307 : this(new Scalar
308 {
309 AsUIntPtr = value
310 }, sizeof(UIntPtr))
311 {
312 }
313
314 private PropertyValue(float value)
315 : this(new Scalar
316 {
317 AsSingle = value
318 }, 4)
319 {
320 }
321
322 private PropertyValue(double value)
323 : this(new Scalar
324 {
325 AsDouble = value
326 }, 8)
327 {
328 }
329
330 private unsafe PropertyValue(Guid value)
331 : this(new Scalar
332 {
333 AsGuid = value
334 }, sizeof(Guid))
335 {
336 }
337
339 : this(new Scalar
340 {
341 AsDateTime = value
342 }, sizeof(DateTime))
343 {
344 }
345
347 : this(new Scalar
348 {
349 AsDateTimeOffset = value
350 }, sizeof(DateTimeOffset))
351 {
352 }
353
355 : this(new Scalar
356 {
357 AsTimeSpan = value
358 }, sizeof(TimeSpan))
359 {
360 }
361
362 private PropertyValue(decimal value)
363 : this(new Scalar
364 {
365 AsDecimal = value
366 }, 16)
367 {
368 }
369
370 public static Func<object, PropertyValue> GetFactory(Type type)
371 {
372 if (type == typeof(bool))
373 {
374 return (object value) => new PropertyValue((bool)value);
375 }
376 if (type == typeof(byte))
377 {
378 return (object value) => new PropertyValue((byte)value);
379 }
380 if (type == typeof(sbyte))
381 {
382 return (object value) => new PropertyValue((sbyte)value);
383 }
384 if (type == typeof(char))
385 {
386 return (object value) => new PropertyValue((char)value);
387 }
388 if (type == typeof(short))
389 {
390 return (object value) => new PropertyValue((short)value);
391 }
392 if (type == typeof(ushort))
393 {
394 return (object value) => new PropertyValue((ushort)value);
395 }
396 if (type == typeof(int))
397 {
398 return (object value) => new PropertyValue((int)value);
399 }
400 if (type == typeof(uint))
401 {
402 return (object value) => new PropertyValue((uint)value);
403 }
404 if (type == typeof(long))
405 {
406 return (object value) => new PropertyValue((long)value);
407 }
408 if (type == typeof(ulong))
409 {
410 return (object value) => new PropertyValue((ulong)value);
411 }
412 if (type == typeof(IntPtr))
413 {
414 return (object value) => new PropertyValue((IntPtr)value);
415 }
416 if (type == typeof(UIntPtr))
417 {
418 return (object value) => new PropertyValue((UIntPtr)value);
419 }
420 if (type == typeof(float))
421 {
422 return (object value) => new PropertyValue((float)value);
423 }
424 if (type == typeof(double))
425 {
426 return (object value) => new PropertyValue((double)value);
427 }
428 if (type == typeof(Guid))
429 {
430 return (object value) => new PropertyValue((Guid)value);
431 }
432 if (type == typeof(DateTime))
433 {
434 return (object value) => new PropertyValue((DateTime)value);
435 }
436 if (type == typeof(DateTimeOffset))
437 {
438 return (object value) => new PropertyValue((DateTimeOffset)value);
439 }
440 if (type == typeof(TimeSpan))
441 {
442 return (object value) => new PropertyValue((TimeSpan)value);
443 }
444 if (type == typeof(decimal))
445 {
446 return (object value) => new PropertyValue((decimal)value);
447 }
448 return (object value) => new PropertyValue(value);
449 }
450
451 public static Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property)
452 {
453 if (property.DeclaringType.IsValueType)
454 {
455 return GetBoxedValueTypePropertyGetter(property);
456 }
457 return GetReferenceTypePropertyGetter(property);
458 }
459
460 private static Func<PropertyValue, PropertyValue> GetBoxedValueTypePropertyGetter(PropertyInfo property)
461 {
462 Type type = property.PropertyType;
463 if (type.IsEnum)
464 {
466 }
467 Func<object, PropertyValue> factory = GetFactory(type);
468 return (PropertyValue container) => factory(property.GetValue(container.ReferenceValue));
469 }
470
471 private static Func<PropertyValue, PropertyValue> GetReferenceTypePropertyGetter(PropertyInfo property)
472 {
473 TypeHelper typeHelper = (TypeHelper)Activator.CreateInstance(typeof(ReferenceTypeHelper<>).MakeGenericType(property.DeclaringType));
474 return typeHelper.GetPropertyGetter(property);
475 }
476}
static ? object CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors|DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture)
Definition Activator.cs:17
override Func< PropertyValue, PropertyValue > GetPropertyGetter(PropertyInfo property)
static Delegate GetGetMethod(PropertyInfo property, Type propertyType)
Func< PropertyValue, PropertyValue > GetPropertyGetter(PropertyInfo property)
static Type GetUnderlyingType(Type enumType)
Definition Enum.cs:309
object? GetValue(object? obj)
bool IsValueType
Definition Type.cs:234
static Func< object, PropertyValue > GetFactory(Type type)
static Func< PropertyValue, PropertyValue > GetReferenceTypePropertyGetter(PropertyInfo property)
static Func< PropertyValue, PropertyValue > GetBoxedValueTypePropertyGetter(PropertyInfo property)
static Func< PropertyValue, PropertyValue > GetPropertyGetter(PropertyInfo property)
unsafe PropertyValue(DateTimeOffset value)
PropertyValue(Scalar scalar, int scalarLength)