Tanoda
ToStringConverter.cs
Go to the documentation of this file.
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Reflection;
7using UnityEngine;
9
11{
12 public static class ToStringConverter
13 {
14 private static readonly Dictionary<Type, Func<object, string>> _toStringConverters = new Dictionary<Type, Func<object, string>>();
15
16 public static void AddConverter<TObj>(Func<TObj, string> objectToString)
17 {
18 _toStringConverters.Add(typeof(TObj), o => objectToString.Invoke((TObj)o));
19 }
20
21 public static string ObjectToString(object value)
22 {
23 var isNull = value.IsNullOrDestroyed();
24 if (isNull != null) return isNull;
25
26 var s = value as string;
27 var t = value as Transform;
28 var o = value as GameObject;
29 var ex = value as Exception;
30 var d = value as Delegate;
31 var collection = value as ICollection;
32 if (s != null) return s;
33 if (t != null) return t.name;
34 if (o != null) return o.name;
35 if (ex != null) return "EXCEPTION: " + ex.Message;
36 if (d != null) return DelegateToString(d);
37
38 var valueType = value.GetType();
39 Func<object, string> func;
40 if (NewMethod(valueType, out func))
41 {
42 return func(value);
43 }
44
45 if (collection != null)
46 {
47 return string.Format("Count = {0}", collection.Count);
48 }
49
50 if (value is IEnumerable)
51 {
52 var property = valueType.GetProperty("Count", BindingFlags.Public | BindingFlags.Instance);
53 if (property != null && property.CanRead)
54 {
55 var count = property.GetValue(value, null) is int ? (int)property.GetValue(value, null) : 0;
56 return string.Format("Count = {0}", count);
57 }
58
59 return "IS ENUMERABLE";
60 }
61
62 try
63 {
64 if (valueType.IsGenericType)
65 {
66 var baseType = valueType.GetGenericTypeDefinition();
67 if (baseType == typeof(KeyValuePair<,>))
68 {
69 //var argTypes = baseType.GetGenericArguments();
70 var kvpKey = valueType.GetProperty("Key") != null ? valueType.GetProperty("Key").GetValue(value, null) : null;
71 var kvpValue = valueType.GetProperty("Value") != null ? valueType.GetProperty("Value").GetValue(value, null) : null;
72 return string.Format("[{0} | {1}]", ObjectToString(kvpKey), ObjectToString(kvpValue));
73 }
74 }
75
76 return value.ToString();
77 }
78 catch
79 {
80 return valueType.Name;
81 }
82 }
83
84 private static bool NewMethod(Type valueType, out Func<object, string> func)
85 {
86 return _toStringConverters.TryGetValue(valueType, out func);
87 }
88
89 private static string DelegateToString(Delegate unityAction)
90 {
91 if (unityAction == null) return "[NULL]";
92 string str;
93 var isNull = unityAction.Target.IsNullOrDestroyed();
94 if (isNull != null) str = "[" + isNull + "]";
95 else str = unityAction.Target.GetType().FullName;
96 var actionString = string.Format("{0}.{1}", str, unityAction.Method.Name);
97 return actionString;
98 }
99
100 internal static string EventEntryToString(UnityEventBase eventObj, int i)
101 {
102 if (eventObj == null) return "[NULL]";
103 if (i < 0 || i >= eventObj.GetPersistentEventCount()) return "[Event index out of range]";
104 // It's fine to use ? here because GetType works fine on disposed objects and we want to know the type name
105 return string.Format("{0}.{1}", eventObj.GetPersistentTarget(i) != null ? eventObj.GetPersistentTarget(i).GetType().FullName : "[NULL]",
106 eventObj.GetPersistentMethodName(i));
107 }
108
109 private static readonly Dictionary<Type, bool> _canCovertCache = new Dictionary<Type, bool>();
110
111 public static bool CanEditValue(ICacheEntry field, object value)
112 {
113 var valueType = field.Type();
114 if (valueType == typeof(string))
115 return true;
116
117 if (_canCovertCache.ContainsKey(valueType))
118 return _canCovertCache[valueType];
119
120 if (TomlTypeConverter.GetConverter(valueType) != null)
121 {
122 _canCovertCache[valueType] = true;
123 return true;
124 }
125
126 try
127 {
128 var converted = ToStringConverter.ObjectToString(value);
129 var _ = Convert.ChangeType(converted, valueType);
130 _canCovertCache[valueType] = true;
131 return true;
132 }
133 catch
134 {
135 _canCovertCache[valueType] = false;
136 return false;
137 }
138 }
139
140 public static void SetEditValue(ICacheEntry field, object value, string result)
141 {
142 var valueType = field.Type();
143 object converted;
144 if (valueType == typeof(string))
145 {
146 converted = result;
147 }
148 else
149 {
150 var typeConverter = TomlTypeConverter.GetConverter(valueType);
151 converted = typeConverter != null ? typeConverter.ConvertToObject(result, valueType) : Convert.ChangeType(result, valueType);
152 }
153
154 if (!Equals(converted, value))
155 field.SetValue(converted);
156 }
157
158 public static string GetEditValue(ICacheEntry field, object value)
159 {
160 var valueType = field.Type();
161
162 if (valueType == typeof(string))
163 return (string)value ?? "";
164
165 var isNull = value.IsNullOrDestroyed();
166 if (isNull != null) return isNull;
167
168 var typeConverter = TomlTypeConverter.GetConverter(valueType);
169 if (typeConverter != null) return typeConverter.ConvertToString(value, valueType);
170
171 return ToStringConverter.ObjectToString(value);
172 }
173 }
174}
Definition: ICacheEntry.cs:6
void SetValue(object newValue)
Type Type()