Entitas  0.35.0
Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
TypeSerializationExtension.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text.RegularExpressions;
5 
6 namespace Entitas.Serialization {
7 
8  public static class TypeSerializationExtension {
9 
10  /// Generates a simplified type string for the specified type that
11  /// can be compiled. This is useful for code generation that will
12  /// produce compilable source code.
13  /// e.g. int instead of System.Int32
14  /// e.g. System.Collections.Generic.Dictionary<int, string> instead of
15  /// System.Collections.Generic.Dictionary`2[System.Int32,System.String]
16  public static string ToCompilableString(this Type type) {
17  if(_builtInTypesToString.ContainsKey(type.FullName)) {
18  return _builtInTypesToString[type.FullName];
19  }
20  if(type.IsGenericType) {
21  var genericMainType = type.FullName.Split('`')[0];
22  var genericArguments = type.GetGenericArguments().Select(
23  argType => argType.ToCompilableString()
24  ).ToArray();
25  return genericMainType +
26  "<" + string.Join(", ", genericArguments) + ">";
27  }
28  if(type.IsArray) {
29  return type.GetElementType().ToCompilableString() +
30  "[" + new string(',', type.GetArrayRank() - 1) + "]";
31  }
32  if(type.IsNested) {
33  return type.FullName.Replace('+', '.');
34  }
35 
36  return type.FullName;
37  }
38 
39  /// Generates a simplified type string for the specified type that
40  /// is easy to read and can be parsed and converted into System.Type.
41  /// This is useful for code generation that serializes objects which is
42  /// also used to create runtime objects based on the type string.
43  /// e.g. int instead of System.Int32
44  /// e.g. System.Collections.Generic.Dictionary<int, string> instead of
45  /// System.Collections.Generic.Dictionary`2[System.Int32,System.String]
46  public static string ToReadableString(this Type type) {
47  if(_builtInTypesToString.ContainsKey(type.FullName)) {
48  return _builtInTypesToString[type.FullName];
49  }
50  if(type.IsGenericType) {
51  var genericMainType = type.FullName.Split('`')[0];
52  var genericArguments = type.GetGenericArguments().Select(
53  argType => argType.ToReadableString()
54  ).ToArray();
55  return genericMainType +
56  "<" + string.Join(", ", genericArguments) + ">";
57  }
58  if(type.IsArray) {
59  return type.GetElementType().ToReadableString() +
60  "[" + new string(',', type.GetArrayRank() - 1) + "]";
61  }
62 
63  return type.FullName;
64  }
65 
66  /// Tries to find and create a type based on the specified type string.
67  public static Type ToType(this string typeString) {
68  var fullTypeName = generateTypeString(typeString);
69  var type = Type.GetType(fullTypeName);
70  if(type != null) {
71  return type;
72  }
73 
74  foreach(var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
75  type = assembly.GetType(fullTypeName);
76  if(type != null) {
77  return type;
78  }
79  }
80 
81  return null;
82  }
83 
84  static string generateTypeString(string typeString) {
85  if(_builtInTypeStrings.ContainsKey(typeString)) {
86  typeString = _builtInTypeStrings[typeString];
87  } else {
88  typeString = generateGenericArguments(typeString);
89  typeString = generateArray(typeString);
90  }
91 
92  return typeString;
93  }
94 
95  static string generateGenericArguments(string typeString) {
96  const string genericArgsPattern = @"<(?<arg>.*)>";
97  var separator = new [] { ", " };
98  typeString = Regex.Replace(typeString, genericArgsPattern,
99  m => {
100  var ts = generateTypeString(m.Groups["arg"].Value);
101  var argsCount = ts.Split(separator, StringSplitOptions.None).Length;
102 
103  return "`" + argsCount + "[" + ts + "]";
104  });
105 
106  return typeString;
107  }
108 
109  static string generateArray(string typeString) {
110  const string arrayPattern = @"(?<type>[^\[]*)(?<rank>\[,*\])";
111  typeString = Regex.Replace(typeString, arrayPattern,
112  m => {
113  var type = generateTypeString(m.Groups["type"].Value);
114  var rank = m.Groups["rank"].Value;
115  return type + rank;
116  });
117 
118  return typeString;
119  }
120 
121  static readonly Dictionary<string, string> _builtInTypesToString = new Dictionary<string, string>() {
122  { "System.Boolean", "bool" },
123  { "System.Byte", "byte" },
124  { "System.SByte", "sbyte" },
125  { "System.Char", "char" },
126  { "System.Decimal", "decimal" },
127  { "System.Double", "double" },
128  { "System.Single", "float" },
129  { "System.Int32", "int" },
130  { "System.UInt32", "uint" },
131  { "System.Int64", "long" },
132  { "System.UInt64", "ulong" },
133  { "System.Object", "object" },
134  { "System.Int16", "short" },
135  { "System.UInt16", "ushort" },
136  { "System.String", "string" },
137  { "System.Void", "void" }
138  };
139 
140  static readonly Dictionary<string, string> _builtInTypeStrings = new Dictionary<string, string>() {
141  { "bool", "System.Boolean" },
142  { "byte", "System.Byte" },
143  { "sbyte", "System.SByte" },
144  { "char", "System.Char" },
145  { "decimal", "System.Decimal" },
146  { "double", "System.Double" },
147  { "float", "System.Single" },
148  { "int", "System.Int32" },
149  { "uint", "System.UInt32" },
150  { "long", "System.Int64" },
151  { "ulong", "System.UInt64" },
152  { "object", "System.Object" },
153  { "short", "System.Int16" },
154  { "ushort", "System.UInt16" },
155  { "string", "System.String" },
156  { "void", "System.Void" }
157  };
158  }
159 }
static Type ToType(this string typeString)
Tries to find and create a type based on the specified type string.