A game about forced loneliness, made by TACStudios
1using System;
2using System.Runtime.CompilerServices;
3using UnityEngine;
4
5namespace UnityEditor.Rendering
6{
7 /// <summary>
8 /// Extensions for <see cref="SerializedProperty"/>
9 /// </summary>
10 public static class SerializedPropertyExtension
11 {
12 /// <summary>
13 /// Checks if the property target is alive
14 /// </summary>
15 /// <param name="property">The <see cref="SerializedProperty"/> to check </param>
16 /// <returns>true, if the property is not null</returns>
17 public static bool IsTargetAlive(this SerializedProperty property)
18 => property != null && property.serializedObject.targetObject != null &&
19 !property.serializedObject.targetObject.Equals(null);
20
21 /// <summary>
22 /// Helper to get an enum value from a SerializedProperty.
23 /// This handle case where index do not correspond to enum value.
24 /// </summary>
25 /// <typeparam name="T">A valid <see cref="Enum"/></typeparam>
26 /// <param name="property">The <see cref="SerializedProperty"/></param>
27 /// <returns>The <see cref="Enum"/> value</returns>
28 /// <example>
29 /// <code>
30 /// enum MyEnum
31 /// {
32 /// A = 2,
33 /// B = 4,
34 /// }
35 /// public class MyObject : MonoBehavior
36 /// {
37 /// public MyEnum theEnum = MyEnum.A;
38 /// }
39 /// [CustomEditor(typeof(MyObject))]
40 /// class MyObjectEditor : Editor
41 /// {
42 /// public override void OnInspectorGUI()
43 /// {
44 /// Debug.Log($"By enumValueIndex: {(MyEnum)serializedObject.FindProperty("theEnum").enumValueIndex}"); //write the value (MyEnum)(0)
45 /// Debug.Log($"By GetEnumValue: {(MyEnum)serializedObject.FindProperty("theEnum").GetEnumValue<MyEnum>()}"); //write the value MyEnum.A
46 /// }
47 /// }
48 /// </code>
49 /// </example>
50 [MethodImpl(MethodImplOptions.AggressiveInlining)]
51 public static T GetEnumValue<T>(this SerializedProperty property)
52 where T : Enum
53 => GetEnumValue_Internal<T>(property);
54
55 /// <summary>
56 /// Helper to get an enum name from a SerializedProperty
57 /// </summary>
58 /// <typeparam name="T">A valid <see cref="Enum"/></typeparam>
59 /// <param name="property">The <see cref="SerializedProperty"/></param>
60 /// <returns>The string containing the name of the enum</returns>
61 [MethodImpl(MethodImplOptions.AggressiveInlining)]
62 public static string GetEnumName<T>(this SerializedProperty property)
63 where T : Enum
64 => property.hasMultipleDifferentValues
65 ? "MultipleDifferentValues"
66 : property.enumNames[property.enumValueIndex];
67
68 /// <summary>
69 /// Helper to set an enum value to a SerializedProperty
70 /// </summary>
71 /// <typeparam name="T">A valid <see cref="Enum"/></typeparam>
72 /// <param name="property">The <see cref="SerializedProperty"/></param>
73 /// <param name="value">The <see cref="Enum"/></param>
74 [MethodImpl(MethodImplOptions.AggressiveInlining)]
75 public static void SetEnumValue<T>(this SerializedProperty property, T value)
76 where T : Enum
77 // intValue actually is the value underlying beside the enum
78 => SetEnumValue_Internal(property, value);
79
80 /// <summary>
81 /// Get the value of a <see cref="SerializedProperty"/>.
82 ///
83 /// This function will be inlined by the compiler.
84 /// Caution: The case of Enum is not handled here.
85 /// </summary>
86 /// <typeparam name="T">
87 /// The type of the value to get.
88 ///
89 /// It is expected to be a supported type by the <see cref="SerializedProperty"/>.
90 /// </typeparam>
91 /// <param name="serializedProperty">The property to get.</param>
92 /// <returns>The value of the property.</returns>
93 [MethodImpl(MethodImplOptions.AggressiveInlining)]
94 public static T GetInline<T>(this SerializedProperty serializedProperty)
95 where T : struct
96 {
97 if (typeof(T) == typeof(Color))
98 return (T)(object)serializedProperty.colorValue;
99 if (typeof(T) == typeof(string))
100 return (T)(object)serializedProperty.stringValue;
101 if (typeof(T) == typeof(double))
102 return (T)(object)serializedProperty.doubleValue;
103 if (typeof(T) == typeof(float))
104 return (T)(object)serializedProperty.floatValue;
105 if (typeof(T) == typeof(long))
106 return (T)(object)serializedProperty.longValue;
107 if (typeof(T) == typeof(int))
108 return (T)(object)serializedProperty.intValue;
109 if (typeof(T) == typeof(bool))
110 return (T)(object)serializedProperty.boolValue;
111 if (typeof(T) == typeof(BoundsInt))
112 return (T)(object)serializedProperty.boundsIntValue;
113 if (typeof(T) == typeof(Bounds))
114 return (T)(object)serializedProperty.boundsValue;
115 if (typeof(T) == typeof(RectInt))
116 return (T)(object)serializedProperty.rectIntValue;
117 if (typeof(T) == typeof(Rect))
118 return (T)(object)serializedProperty.rectValue;
119 if (typeof(T) == typeof(Quaternion))
120 return (T)(object)serializedProperty.quaternionValue;
121 if (typeof(T) == typeof(Vector2Int))
122 return (T)(object)serializedProperty.vector2IntValue;
123 if (typeof(T) == typeof(Vector4))
124 return (T)(object)serializedProperty.vector4Value;
125 if (typeof(T) == typeof(Vector3))
126 return (T)(object)serializedProperty.vector3Value;
127 if (typeof(T) == typeof(Vector2))
128 return (T)(object)serializedProperty.vector2Value;
129 if (typeof(T).IsEnum)
130 return GetEnumValue_Internal<T>(serializedProperty);
131 throw new ArgumentOutOfRangeException($"<{typeof(T)}> is not a valid type for a serialized property.");
132 }
133
134 /// <summary>
135 /// Set the value of a <see cref="SerializedProperty"/>.
136 ///
137 /// This function will be inlined by the compiler.
138 /// Caution: The case of Enum is not handled here.
139 /// </summary>
140 /// <typeparam name="T">
141 /// The type of the value to set.
142 ///
143 /// It is expected to be a supported type by the <see cref="SerializedProperty"/>.
144 /// </typeparam>
145 /// <param name="serializedProperty">The property to set.</param>
146 /// <param name="value">The value to set.</param>
147 [MethodImpl(MethodImplOptions.AggressiveInlining)]
148 public static void SetInline<T>(this SerializedProperty serializedProperty, T value)
149 where T : struct
150 {
151 if (typeof(T) == typeof(Color))
152 {
153 serializedProperty.colorValue = (Color)(object)value;
154 return;
155 }
156 if (typeof(T) == typeof(string))
157 {
158 serializedProperty.stringValue = (string)(object)value;
159 return;
160 }
161 if (typeof(T) == typeof(double))
162 {
163 serializedProperty.doubleValue = (double)(object)value;
164 return;
165 }
166 if (typeof(T) == typeof(float))
167 {
168 serializedProperty.floatValue = (float)(object)value;
169 return;
170 }
171 if (typeof(T) == typeof(long))
172 {
173 serializedProperty.longValue = (long)(object)value;
174 return;
175 }
176 if (typeof(T) == typeof(int))
177 {
178 serializedProperty.intValue = (int)(object)value;
179 return;
180 }
181 if (typeof(T) == typeof(bool))
182 {
183 serializedProperty.boolValue = (bool)(object)value;
184 return;
185 }
186 if (typeof(T) == typeof(BoundsInt))
187 {
188 serializedProperty.boundsIntValue = (BoundsInt)(object)value;
189 return;
190 }
191 if (typeof(T) == typeof(Bounds))
192 {
193 serializedProperty.boundsValue = (Bounds)(object)value;
194 return;
195 }
196 if (typeof(T) == typeof(RectInt))
197 {
198 serializedProperty.rectIntValue = (RectInt)(object)value;
199 return;
200 }
201 if (typeof(T) == typeof(Rect))
202 {
203 serializedProperty.rectValue = (Rect)(object)value;
204 return;
205 }
206 if (typeof(T) == typeof(Quaternion))
207 {
208 serializedProperty.quaternionValue = (Quaternion)(object)value;
209 return;
210 }
211 if (typeof(T) == typeof(Vector2Int))
212 {
213 serializedProperty.vector2IntValue = (Vector2Int)(object)value;
214 return;
215 }
216 if (typeof(T) == typeof(Vector4))
217 {
218 serializedProperty.vector4Value = (Vector4)(object)value;
219 return;
220 }
221 if (typeof(T) == typeof(Vector3))
222 {
223 serializedProperty.vector3Value = (Vector3)(object)value;
224 return;
225 }
226 if (typeof(T) == typeof(Vector2))
227 {
228 serializedProperty.vector2Value = (Vector2)(object)value;
229 return;
230 }
231 if (typeof(T).IsEnum)
232 {
233 SetEnumValue_Internal(serializedProperty, value);
234 return;
235 }
236 throw new ArgumentOutOfRangeException($"<{typeof(T)}> is not a valid type for a serialized property.");
237 }
238
239 [MethodImpl(MethodImplOptions.AggressiveInlining)]
240 private static T GetEnumValue_Internal<T>(SerializedProperty property)
241 // intValue actually is the value underlying beside the enum
242 => (T)(object)property.intValue;
243
244
245 [MethodImpl(MethodImplOptions.AggressiveInlining)]
246 private static void SetEnumValue_Internal<T>(SerializedProperty property, T value)
247 // intValue actually is the value underlying beside the enum
248 => property.intValue = (int)(object)value;
249 }
250}