wasSharp – Diff between revs 35 and 37

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 35 Rev 37
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. // 4 // rights of fair usage, the disclaimer and warranty conditions. //
5 /////////////////////////////////////////////////////////////////////////// 5 ///////////////////////////////////////////////////////////////////////////
6   6  
7 using System; 7 using System;
8 using System.Collections.Generic; 8 using System.Collections.Generic;
9 using System.Linq; 9 using System.Linq;
10 using System.Reflection; 10 using System.Reflection;
11   11  
12 namespace wasSharp 12 namespace wasSharp
13 { 13 {
14 public static class Reflection 14 public static class Reflection
15 { 15 {
16 /////////////////////////////////////////////////////////////////////////// 16 ///////////////////////////////////////////////////////////////////////////
17 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 17 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
18 /////////////////////////////////////////////////////////////////////////// 18 ///////////////////////////////////////////////////////////////////////////
19 /// <summary> 19 /// <summary>
20 /// Retrieves an attribute of type T from an enumeration. 20 /// Retrieves an attribute of type T from an enumeration.
21 /// </summary> 21 /// </summary>
22 /// <returns>an attribute of type T</returns> 22 /// <returns>an attribute of type T</returns>
23 public static T GetAttributeFromEnumValue<T>(Enum value) where T : Attribute 23 public static T GetAttributeFromEnumValue<T>(Enum value) where T : Attribute
24 { 24 {
25 return (T)value.GetType() 25 return (T)value.GetType()
26 .GetRuntimeField(value.ToString()) 26 .GetRuntimeField(value.ToString())
27 .GetCustomAttributes(typeof(T), false) 27 .GetCustomAttributes(typeof(T), false)
28 .SingleOrDefault(); 28 .SingleOrDefault();
29 } 29 }
30   30  
31 /////////////////////////////////////////////////////////////////////////// 31 ///////////////////////////////////////////////////////////////////////////
32 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 32 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
33 /////////////////////////////////////////////////////////////////////////// 33 ///////////////////////////////////////////////////////////////////////////
34 /// <summary> 34 /// <summary>
35 /// Returns all the attributes of type T of an enumeration. 35 /// Returns all the attributes of type T of an enumeration.
36 /// </summary> 36 /// </summary>
37 /// <typeparam name="T">the attribute to retrieve</typeparam> 37 /// <typeparam name="T">the attribute to retrieve</typeparam>
38 /// <returns>a list of attributes</returns> 38 /// <returns>a list of attributes</returns>
39 public static IEnumerable<T> GetEnumAttributes<T>(Enum e) where T : Attribute 39 public static IEnumerable<T> GetEnumAttributes<T>(Enum e) where T : Attribute
40 { 40 {
41 return e.GetType().GetRuntimeFields().ToArray() 41 return e.GetType().GetRuntimeFields().ToArray()
42 .AsParallel() 42 .AsParallel()
43 .Select(o => GetAttributeFromEnumValue<T>((Enum)o.GetValue(Activator.CreateInstance<T>()))); 43 .Select(o => GetAttributeFromEnumValue<T>((Enum)o.GetValue(Activator.CreateInstance<T>())));
44 } 44 }
45   45  
46 /////////////////////////////////////////////////////////////////////////// 46 ///////////////////////////////////////////////////////////////////////////
47 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 47 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
48 /////////////////////////////////////////////////////////////////////////// 48 ///////////////////////////////////////////////////////////////////////////
49 /// <summary> 49 /// <summary>
50 /// Returns all the field names of an enumeration. 50 /// Returns all the field names of an enumeration.
51 /// </summary> 51 /// </summary>
52 /// <returns>the field names</returns> 52 /// <returns>the field names</returns>
53 public static IEnumerable<string> GetEnumNames<T>() 53 public static IEnumerable<string> GetEnumNames<T>()
54 { 54 {
55 return 55 return
56 typeof(T).GetRuntimeFields().ToArray() 56 typeof(T).GetRuntimeFields().ToArray()
57 .AsParallel() 57 .AsParallel()
58 .Select(o => o.GetCustomAttribute(typeof(NameAttribute), false)) 58 .Select(o => o.GetCustomAttribute(typeof(NameAttribute), false))
59 .Select(o => (o as NameAttribute)?.Name) 59 .Select(o => (o as NameAttribute)?.Name)
60 .Where(o => !string.IsNullOrEmpty(o)) 60 .Where(o => !string.IsNullOrEmpty(o))
61 .Select(o => o); 61 .Select(o => o);
62 } 62 }
63   63  
64 /////////////////////////////////////////////////////////////////////////// 64 ///////////////////////////////////////////////////////////////////////////
65 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 65 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
66 /////////////////////////////////////////////////////////////////////////// 66 ///////////////////////////////////////////////////////////////////////////
67 /// <summary> 67 /// <summary>
68 /// Returns all the values of an enumeration. 68 /// Returns all the values of an enumeration.
69 /// </summary> 69 /// </summary>
70 /// <returns>the values of the enumeration</returns> 70 /// <returns>the values of the enumeration</returns>
71 public static IEnumerable<T> GetEnumValues<T>() 71 public static IEnumerable<T> GetEnumValues<T>()
72 { 72 {
73 return Enum.GetValues(typeof(T)).Cast<object>().Select(value => (T)value); 73 return Enum.GetValues(typeof(T)).Cast<object>().Select(value => (T)value);
74 } 74 }
75   75  
76 /////////////////////////////////////////////////////////////////////////// 76 ///////////////////////////////////////////////////////////////////////////
77 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 77 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
78 /////////////////////////////////////////////////////////////////////////// 78 ///////////////////////////////////////////////////////////////////////////
79 /// <summary> 79 /// <summary>
80 /// Get the name from an enumeration value. 80 /// Get the name from an enumeration value.
81 /// </summary> 81 /// </summary>
82 /// <param name="value">an enumeration value</param> 82 /// <param name="value">an enumeration value</param>
83 /// <returns>the description or the empty string</returns> 83 /// <returns>the description or the empty string</returns>
84 public static string GetNameFromEnumValue(Enum value) 84 public static string GetNameFromEnumValue(Enum value)
85 { 85 {
86 var attribute = value.GetType() 86 var attribute = value.GetType()
87 .GetRuntimeField(value.ToString()) 87 .GetRuntimeField(value.ToString())
88 .GetCustomAttributes(typeof(NameAttribute), false) 88 .GetCustomAttributes(typeof(NameAttribute), false)
89 .SingleOrDefault() as NameAttribute; 89 .SingleOrDefault() as NameAttribute;
90 return attribute?.Name; 90 return attribute?.Name;
91 } 91 }
92   92  
93 /////////////////////////////////////////////////////////////////////////// 93 ///////////////////////////////////////////////////////////////////////////
94 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 94 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
95 /////////////////////////////////////////////////////////////////////////// 95 ///////////////////////////////////////////////////////////////////////////
96 /// <summary> 96 /// <summary>
97 /// Get the description from an enumeration value. 97 /// Get the description from an enumeration value.
98 /// </summary> 98 /// </summary>
99 /// <param name="value">an enumeration value</param> 99 /// <param name="value">an enumeration value</param>
100 /// <returns>the description or the empty string</returns> 100 /// <returns>the description or the empty string</returns>
101 public static string GetDescriptionFromEnumValue(Enum value) 101 public static string GetDescriptionFromEnumValue(Enum value)
102 { 102 {
103 var attribute = value.GetType() 103 var attribute = value.GetType()
104 .GetRuntimeField(value.ToString()) 104 .GetRuntimeField(value.ToString())
105 .GetCustomAttributes(typeof(DescriptionAttribute), false) 105 .GetCustomAttributes(typeof(DescriptionAttribute), false)
106 .SingleOrDefault() as DescriptionAttribute; 106 .SingleOrDefault() as DescriptionAttribute;
107 return attribute?.Description; 107 return attribute?.Description;
108 } 108 }
109   109  
110 /////////////////////////////////////////////////////////////////////////// 110 ///////////////////////////////////////////////////////////////////////////
111 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 111 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
112 /////////////////////////////////////////////////////////////////////////// 112 ///////////////////////////////////////////////////////////////////////////
113 /// <summary> 113 /// <summary>
114 /// Get enumeration value from its name attribute. 114 /// Get enumeration value from its name attribute.
115 /// </summary> 115 /// </summary>
116 /// <typeparam name="T">the enumeration type</typeparam> 116 /// <typeparam name="T">the enumeration type</typeparam>
117 /// <param name="name">the description of a member</param> 117 /// <param name="name">the description of a member</param>
118 /// <param name="comparison">the string comparison to use</param> 118 /// <param name="comparison">the string comparison to use</param>
119 /// <returns>the value or the default of T if case no name attribute found</returns> 119 /// <returns>the value or the default of T if case no name attribute found</returns>
120 public static T GetEnumValueFromName<T>(string name, 120 public static T GetEnumValueFromName<T>(string name,
121 StringComparison comparison = StringComparison.OrdinalIgnoreCase) 121 StringComparison comparison = StringComparison.OrdinalIgnoreCase)
122 { 122 {
123 var field = typeof(T).GetRuntimeFields().ToArray() 123 var field = typeof(T).GetRuntimeFields().ToArray()
124 .AsParallel().SelectMany(f => f.GetCustomAttributes( 124 .AsParallel().SelectMany(f => f.GetCustomAttributes(
125 typeof(NameAttribute), false), ( 125 typeof(NameAttribute), false), (
126 f, a) => new { Field = f, Att = a }) 126 f, a) => new { Field = f, Att = a })
127 .SingleOrDefault(a => string.Equals(((NameAttribute)a.Att) 127 .SingleOrDefault(a => string.Equals(((NameAttribute)a.Att)
128 .Name, name, comparison)); 128 .Name, name, comparison));
129 return field != null ? (T)field.Field.GetValue(Activator.CreateInstance<T>()) : default(T); 129 return field != null ? (T)field.Field.GetValue(Activator.CreateInstance<T>()) : default(T);
130 } 130 }
131   131  
132 /////////////////////////////////////////////////////////////////////////// 132 ///////////////////////////////////////////////////////////////////////////
133 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 133 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
134 /////////////////////////////////////////////////////////////////////////// 134 ///////////////////////////////////////////////////////////////////////////
135 /// <summary> 135 /// <summary>
136 /// Get the name of a structure member. 136 /// Get the name of a structure member.
137 /// </summary> 137 /// </summary>
138 /// <typeparam name="T">the type of the structure to search</typeparam> 138 /// <typeparam name="T">the type of the structure to search</typeparam>
139 /// <param name="structure">the structure to search</param> 139 /// <param name="structure">the structure to search</param>
140 /// <param name="item">the value of the item to search</param> 140 /// <param name="item">the value of the item to search</param>
141 /// <returns>the description or the empty string</returns> 141 /// <returns>the description or the empty string</returns>
142 public static string GetStructureMemberName<T>(T structure, object item) where T : struct 142 public static string GetStructureMemberName<T>(T structure, object item) where T : struct
143 { 143 {
144 var f = typeof(T).GetRuntimeFields(); 144 var f = typeof(T).GetRuntimeFields();
145 var p = typeof(T).GetRuntimeProperties(); 145 var p = typeof(T).GetRuntimeProperties();
146   -  
147 dynamic r = null; -  
148   146  
-   147 if (f != null)
149 if (f != null) 148 {
150 r = f.AsParallel() 149 var r = f.AsParallel()
151 .SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false), 150 .SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false),
152 (o, a) => new { Field = o, Att = a }) 151 (o, a) => new { Field = o, Att = a })
153 .SingleOrDefault(q => q.Field.GetValue(structure).Equals(item)); 152 .SingleOrDefault(q => q.Field.GetValue(structure).Equals(item));
-   153 if (r != null)
-   154 return ((NameAttribute)r.Att).Name;
-   155 }
154   156  
-   157 if (p != null)
155 if (p != null) 158 {
156 r = p.AsParallel() 159 var r = p.AsParallel()
157 .SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false), 160 .SelectMany(o => o.GetCustomAttributes(typeof(NameAttribute), false),
158 (o, a) => new { Property = o, Att = a }) 161 (o, a) => new { Property = o, Att = a })
159 .SingleOrDefault(q => q.Property.GetValue(structure).Equals(item)); 162 .SingleOrDefault(q => q.Property.GetValue(structure).Equals(item));
-   163 if (r != null)
-   164 return ((NameAttribute)r.Att).Name;
-   165 }
160   166  
161 return r != null ? ((NameAttribute)r.Att).Name : string.Empty; 167 return string.Empty;
162 } 168 }
163   169  
164 /////////////////////////////////////////////////////////////////////////// 170 ///////////////////////////////////////////////////////////////////////////
165 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // 171 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
166 /////////////////////////////////////////////////////////////////////////// 172 ///////////////////////////////////////////////////////////////////////////
167 /// <summary> 173 /// <summary>
168 /// Get field or property from a class by supplying a path. 174 /// Get field or property from a class by supplying a path.
169 /// </summary> 175 /// </summary>
170 /// <typeparam name="T">the type of the object</typeparam> 176 /// <typeparam name="T">the type of the object</typeparam>
171 /// <param name="o">the object</param> 177 /// <param name="o">the object</param>
172 /// <param name="path">the fully qualified path to the field of property</param> 178 /// <param name="path">the fully qualified path to the field of property</param>
173 /// <returns> 179 /// <returns>
174 /// the last object in the fully qualified path or null in case the field or property could not be found 180 /// the last object in the fully qualified path or null in case the field or property could not be found
175 /// </returns> 181 /// </returns>
176 public static object GetFP<T>(this T o, string path) 182 public static object GetFP<T>(this T o, string path)
177 { 183 {
178 if (string.IsNullOrEmpty(path)) return null; 184 if (string.IsNullOrEmpty(path)) return null;
179 if (o == null) return null; 185 if (o == null) return null;
180   186  
181 var memberType = o.GetType(); 187 var memberType = o.GetType();
182 var components = path.Split('.'); 188 var components = path.Split('.');
183   189  
184 var f = memberType.GetRuntimeField(components[0]); 190 var f = memberType.GetRuntimeField(components[0]);
185 var p = memberType.GetRuntimeProperty(components[0]); 191 var p = memberType.GetRuntimeProperty(components[0]);
186   192  
187 if (f != null) 193 if (f != null)
188 return components.Length > 1 194 return components.Length > 1
189 ? GetFP(f.GetValue(o), 195 ? GetFP(f.GetValue(o),
190 components.Skip(1).Aggregate((a, i) => a + @"." + i)) 196 components.Skip(1).Aggregate((a, i) => a + @"." + i))
191 : memberType.GetRuntimeField(path).GetValue(o); 197 : memberType.GetRuntimeField(path).GetValue(o);
192   198  
193 if (p != null) 199 if (p != null)
194 return components.Length > 1 200 return components.Length > 1
195 ? GetFP(p.GetValue(o), 201 ? GetFP(p.GetValue(o),
196 components.Skip(1).Aggregate((a, i) => a + @"." + i)) 202 components.Skip(1).Aggregate((a, i) => a + @"." + i))
197 : memberType.GetRuntimeProperty(path).GetValue(o); 203 : memberType.GetRuntimeProperty(path).GetValue(o);
198   204  
199 return null; 205 return null;
200 } 206 }
201   207  
202 /////////////////////////////////////////////////////////////////////////// 208 ///////////////////////////////////////////////////////////////////////////
203 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // 209 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
204 /////////////////////////////////////////////////////////////////////////// 210 ///////////////////////////////////////////////////////////////////////////
205 /// <summary> 211 /// <summary>
206 /// Get field or property info from a class by supplying a path. 212 /// Get field or property info from a class by supplying a path.
207 /// </summary> 213 /// </summary>
208 /// <typeparam name="T">the type of the object</typeparam> 214 /// <typeparam name="T">the type of the object</typeparam>
209 /// <param name="o">the object</param> 215 /// <param name="o">the object</param>
210 /// <param name="path">the fully qualified path to the field of property</param> 216 /// <param name="path">the fully qualified path to the field of property</param>
211 /// <returns> 217 /// <returns>
212 /// the field or property info of the last object in the path or null if the object cannot be found 218 /// the field or property info of the last object in the path or null if the object cannot be found
213 /// </returns> 219 /// </returns>
214 public static object GetFPInfo<T>(this T o, string path) 220 public static object GetFPInfo<T>(this T o, string path)
215 { 221 {
216 if (string.IsNullOrEmpty(path)) return null; 222 if (string.IsNullOrEmpty(path)) return null;
217 if (o == null) return null; 223 if (o == null) return null;
218   224  
219 var memberType = o.GetType(); 225 var memberType = o.GetType();
220 var components = path.Split('.'); 226 var components = path.Split('.');
221   227  
222 var f = memberType.GetRuntimeField(components[0]); 228 var f = memberType.GetRuntimeField(components[0]);
223 var p = memberType.GetRuntimeProperty(components[0]); 229 var p = memberType.GetRuntimeProperty(components[0]);
224   230  
225 if (f != null) 231 if (f != null)
226 return components.Length > 1 232 return components.Length > 1
227 ? GetFPInfo(f.GetValue(o), 233 ? GetFPInfo(f.GetValue(o),
228 components.Skip(1).Aggregate((a, i) => a + @"." + i)) 234 components.Skip(1).Aggregate((a, i) => a + @"." + i))
229 : memberType.GetRuntimeField(path); 235 : memberType.GetRuntimeField(path);
230   236  
231 if (p != null) 237 if (p != null)
232 return components.Length > 1 238 return components.Length > 1
233 ? GetFPInfo(p.GetValue(o), 239 ? GetFPInfo(p.GetValue(o),
234 components.Skip(1).Aggregate((a, i) => a + @"." + i)) 240 components.Skip(1).Aggregate((a, i) => a + @"." + i))
235 : memberType.GetRuntimeProperty(path); 241 : memberType.GetRuntimeProperty(path);
236   242  
237 return null; 243 return null;
238 } 244 }
239   245  
240 /////////////////////////////////////////////////////////////////////////// 246 ///////////////////////////////////////////////////////////////////////////
241 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // 247 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
242 /////////////////////////////////////////////////////////////////////////// 248 ///////////////////////////////////////////////////////////////////////////
243 /// <summary>Return all the run-time properties for an object.</summary> 249 /// <summary>Return all the run-time properties for an object.</summary>
244 /// <param name="o">the object whose properties to return</param> 250 /// <param name="o">the object whose properties to return</param>
245 /// <returns>the property information for all the properties of the object</returns> 251 /// <returns>the property information for all the properties of the object</returns>
246 public static IEnumerable<PropertyInfo> GetPropertiesInfo<T>(this T o) 252 public static IEnumerable<PropertyInfo> GetPropertiesInfo<T>(this T o)
247 { 253 {
248 foreach (var p in o.GetType().GetRuntimeProperties()) 254 foreach (var p in o.GetType().GetRuntimeProperties())
249 yield return p; 255 yield return p;
250 } 256 }
251   257  
252 /////////////////////////////////////////////////////////////////////////// 258 ///////////////////////////////////////////////////////////////////////////
253 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // 259 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
254 /////////////////////////////////////////////////////////////////////////// 260 ///////////////////////////////////////////////////////////////////////////
255 /// <summary> 261 /// <summary>
256 /// Enumerate all the base types recursively starting from a type. 262 /// Enumerate all the base types recursively starting from a type.
257 /// </summary> 263 /// </summary>
258 /// <param name="type">the type</param> 264 /// <param name="type">the type</param>
259 /// <returns>an enumeration of all base types</returns> 265 /// <returns>an enumeration of all base types</returns>
260 public static IEnumerable<Type> GetBaseTypes(this Type type) 266 public static IEnumerable<Type> GetBaseTypes(this Type type)
261 { 267 {
262 var baseType = type.GetTypeInfo().BaseType; 268 var baseType = type.GetTypeInfo().BaseType;
263 if (baseType == null) 269 if (baseType == null)
264 yield break; 270 yield break;
265 yield return baseType; 271 yield return baseType;
266 foreach (var t in GetBaseTypes(baseType)) 272 foreach (var t in GetBaseTypes(baseType))
267 { 273 {
268 yield return t; 274 yield return t;
269 } 275 }
270 } 276 }
271   277  
272 /// <summary> 278 /// <summary>
273 /// A generic name attribute. 279 /// A generic name attribute.
274 /// </summary> 280 /// </summary>
275 public class NameAttribute : Attribute 281 public class NameAttribute : Attribute
276 { 282 {
277 protected readonly string name; 283 protected readonly string name;
278   284  
279 public NameAttribute(string name) 285 public NameAttribute(string name)
280 { 286 {
281 this.name = name; 287 this.name = name;
282 } 288 }
283   289  
284 public string Name => name; 290 public string Name => name;
285 } 291 }
286   292  
287 /// <summary> 293 /// <summary>
288 /// A generic description attribute. 294 /// A generic description attribute.
289 /// </summary> 295 /// </summary>
290 public class DescriptionAttribute : Attribute 296 public class DescriptionAttribute : Attribute
291 { 297 {
292 protected readonly string description; 298 protected readonly string description;
293   299  
294 public DescriptionAttribute(string description) 300 public DescriptionAttribute(string description)
295 { 301 {
296 this.description = description; 302 this.description = description;
297 } 303 }
298   304  
299 public string Description => description; 305 public string Description => description;
300 } 306 }
301 } 307 }
302 } 308 }
303   309