Entitas  0.35.0
Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
PublicMemberInfo.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Reflection;
4 
5 namespace Entitas.Serialization {
6 
7  public class PublicMemberInfo {
8 
9  public readonly Type type;
10  public readonly string name;
11  public readonly AttributeInfo[] attributes;
12 
13  readonly FieldInfo _fieldInfo;
14  readonly PropertyInfo _propertyInfo;
15 
16  public PublicMemberInfo(FieldInfo info) {
17  _fieldInfo = info;
18  _propertyInfo = null;
19  type = _fieldInfo.FieldType;
20  name = _fieldInfo.Name;
21  attributes = getAttributes(_fieldInfo.GetCustomAttributes(false));
22  }
23 
24  public PublicMemberInfo(PropertyInfo info) {
25  _fieldInfo = null;
26  _propertyInfo = info;
27  type = _propertyInfo.PropertyType;
28  name = _propertyInfo.Name;
29  attributes = getAttributes(_propertyInfo.GetCustomAttributes(false));
30  }
31 
32  public PublicMemberInfo(Type type, string name, AttributeInfo[] attributes = null) {
33  this.type = type;
34  this.name = name;
35  this.attributes = attributes;
36  }
37 
38  public object GetValue(object obj) {
39  return _fieldInfo != null
40  ? _fieldInfo.GetValue(obj)
41  : _propertyInfo.GetValue(obj, null);
42  }
43 
44  public void SetValue(object obj, object value) {
45  if(_fieldInfo != null) {
46  _fieldInfo.SetValue(obj, value);
47  } else {
48  _propertyInfo.SetValue(obj, value, null);
49  }
50  }
51 
52  static AttributeInfo[] getAttributes(object[] attributes) {
53  var infos = new AttributeInfo[attributes.Length];
54  for (int i = 0; i < attributes.Length; i++) {
55  var attr = attributes[i];
56  infos[i] = new AttributeInfo(attr, attr.GetType().GetPublicMemberInfos());
57  }
58 
59  return infos;
60  }
61  }
62 
63  public class AttributeInfo {
64 
65  public readonly object attribute;
66  public readonly List<PublicMemberInfo> memberInfos;
67 
68  public AttributeInfo(object attribute, List<PublicMemberInfo> memberInfos) {
69  this.attribute = attribute;
70  this.memberInfos = memberInfos;
71  }
72  }
73 
74  public static class PublicMemberInfoExtension {
75 
76  public static List<PublicMemberInfo> GetPublicMemberInfos(this Type type) {
77  const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
78 
79  var fieldInfos = type.GetFields(bindingFlags);
80  var propertyInfos = type.GetProperties(bindingFlags);
81  var memberInfos = new List<PublicMemberInfo>(
82  fieldInfos.Length + propertyInfos.Length
83  );
84 
85  for (int i = 0; i < fieldInfos.Length; i++) {
86  memberInfos.Add(new PublicMemberInfo(fieldInfos[i]));
87  }
88 
89  for (int i = 0; i < propertyInfos.Length; i++) {
90  var propertyInfo = propertyInfos[i];
91  if(propertyInfo.CanRead && propertyInfo.CanWrite) {
92  memberInfos.Add(new PublicMemberInfo(propertyInfo));
93  }
94  }
95 
96  return memberInfos;
97  }
98 
99  public static object PublicMemberClone(this object obj) {
100  var clone = Activator.CreateInstance(obj.GetType());
101  CopyPublicMemberValues(obj, clone);
102  return clone;
103  }
104 
105  public static T PublicMemberClone<T>(this object obj) where T : new() {
106  var clone = new T();
107  CopyPublicMemberValues(obj, clone);
108  return clone;
109  }
110 
111  public static void CopyPublicMemberValues(this object source, object target) {
112  var memberInfos = source.GetType().GetPublicMemberInfos();
113  for (int i = 0; i < memberInfos.Count; i++) {
114  var info = memberInfos[i];
115  info.SetValue(target, info.GetValue(source));
116  }
117  }
118  }
119 }