/// <summary> /// Write the values into the stream writer. /// </summary> static void Write(StreamWriter writer, string name, object value, int tab = 0) { bool prefix = false; if (!string.IsNullOrEmpty(name)) { prefix = true; writer.WriteTabs(tab); writer.Write(name); } else if (value != null) { writer.WriteTabs(tab); } if (value != null && !writer.WriteObject(value, prefix)) { Type type = value.GetType(); #if !STANDALONE if (value is AnimationCurve) { AnimationCurve ac = value as AnimationCurve; Keyframe[] kfs = ac.keys; type = typeof(Vector4[]); Vector4[] vs = new Vector4[kfs.Length]; for (int i = 0, imax = kfs.Length; i < imax; ++i) { Keyframe kf = kfs[i]; vs[i] = new Vector4(kf.time, kf.value, kf.inTangent, kf.outTangent); } value = vs; } #endif if (value is TList) { TList list = value as TList; if (prefix) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); if (list.Count > 0) { for (int i = 0, imax = list.Count; i < imax; ++i) { writer.Write('\n'); Write(writer, null, list.Get(i), tab + 1); } } return; } if (value is System.Collections.IList) { System.Collections.IList list = value as System.Collections.IList; if (prefix) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); if (list.Count > 0) { for (int i = 0, imax = list.Count; i < imax; ++i) { writer.Write('\n'); Write(writer, null, list[i], tab + 1); } } return; } if (value is IDataNodeSerializable) { IDataNodeSerializable ser = value as IDataNodeSerializable; DataNode node = new DataNode(); ser.Serialize(node); if (prefix) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); for (int i = 0; i < node.children.size; ++i) { DataNode child = node.children[i]; writer.Write('\n'); child.Write(writer, tab + 1); } return; } #if REFLECTION_SUPPORT if (prefix) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); List <FieldInfo> fields = type.GetSerializableFields(); if (fields.size > 0) { for (int i = 0; i < fields.size; ++i) { FieldInfo field = fields[i]; object val = field.GetValue(value); if (val != null) { writer.Write('\n'); Write(writer, field.Name, val, tab + 1); } } } #endif } }
/// <summary> /// Set the node's value using its text representation. /// Returns whether the child nodes should be processed or not. /// </summary> bool SetValue(string text, Type type, string[] parts) { if (type == null || type == typeof(void)) { mValue = null; } else if (type == typeof(string)) { mValue = text; } else if (type == typeof(bool)) { bool b = false; if (bool.TryParse(text, out b)) { mValue = b; } } else if (type == typeof(byte)) { byte b; if (byte.TryParse(text, out b)) { mValue = b; } } else if (type == typeof(Int16)) { Int16 b; if (Int16.TryParse(text, out b)) { mValue = b; } } else if (type == typeof(UInt16)) { UInt16 b; if (UInt16.TryParse(text, out b)) { mValue = b; } } else if (type == typeof(Int32)) { Int32 b; if (Int32.TryParse(text, out b)) { mValue = b; } } else if (type == typeof(UInt32)) { UInt32 b; if (UInt32.TryParse(text, out b)) { mValue = b; } } else if (type == typeof(float)) { float b; if (float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out b)) { mValue = b; } } else if (type == typeof(double)) { double b; if (double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out b)) { mValue = b; } } else if (type == typeof(Vector2)) { if (parts == null) { parts = text.Split(','); } if (parts.Length == 2) { Vector2 v; if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out v.x) && float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out v.y)) { mValue = v; } } } else if (type == typeof(Vector3)) { if (parts == null) { parts = text.Split(','); } if (parts.Length == 3) { Vector3 v; if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out v.x) && float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out v.y) && float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out v.z)) { mValue = v; } } } else if (type == typeof(Vector4)) { if (parts == null) { parts = text.Split(','); } if (parts.Length == 4) { Vector4 v; if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out v.x) && float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out v.y) && float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out v.z) && float.TryParse(parts[3], NumberStyles.Float, CultureInfo.InvariantCulture, out v.w)) { mValue = v; } } } else if (type == typeof(Quaternion)) { if (parts == null) { parts = text.Split(','); } if (parts.Length == 3) { Vector3 v; if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out v.x) && float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out v.y) && float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out v.z)) { mValue = Quaternion.Euler(v); } } else if (parts.Length == 4) { Quaternion v; if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out v.x) && float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out v.y) && float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out v.z) && float.TryParse(parts[3], NumberStyles.Float, CultureInfo.InvariantCulture, out v.w)) { mValue = v; } } } else if (type == typeof(Color)) { if (parts == null) { parts = text.Split(','); } if (parts.Length == 4) { Color v; if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out v.r) && float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out v.g) && float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out v.b) && float.TryParse(parts[3], NumberStyles.Float, CultureInfo.InvariantCulture, out v.a)) { mValue = v; } } } else if (type == typeof(Rect)) { if (parts == null) { parts = text.Split(','); } if (parts.Length == 4) { Vector4 v; if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out v.x) && float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out v.y) && float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out v.z) && float.TryParse(parts[3], NumberStyles.Float, CultureInfo.InvariantCulture, out v.w)) { mValue = new Rect(v.x, v.y, v.z, v.w); } } } else if (type.Implements(typeof(IDataNodeSerializable))) { IDataNodeSerializable ds = (IDataNodeSerializable)type.Create(); ds.Deserialize(this); mValue = ds; return(false); } else if (!type.IsSubclassOf(typeof(Component))) { bool isIList = type.Implements(typeof(System.Collections.IList)); bool isTList = (!isIList && type.Implements(typeof(TList))); mValue = (isTList || isIList) ? type.Create(children.size) : type.Create(); if (mValue == null) { Debug.LogError("Unable to create a " + type); return(true); } if (isTList) { TList list = mValue as TList; Type elemType = type.GetGenericArgument(); if (elemType != null) { for (int i = 0; i < children.size; ++i) { DataNode child = children[i]; if (child.value == null) { child.mValue = child.name; child.mResolved = false; child.ResolveValue(elemType); list.Add(child.mValue); } else if (child.name == "Add") { child.ResolveValue(elemType); list.Add(child.mValue); } else { Debug.LogWarning("Unexpected node in an array: " + child.name); } } return(false); } else { Debug.LogError("Unable to determine the element type of " + type); } } else if (isIList) { // This is for both List<Type> and Type[] arrays. System.Collections.IList list = mValue as System.Collections.IList; Type elemType = type.GetGenericArgument(); if (elemType == null) { elemType = type.GetElementType(); } bool fixedSize = (list.Count == children.size); if (elemType != null) { for (int i = 0; i < children.size; ++i) { DataNode child = children[i]; if (child.value == null) { child.mValue = child.name; child.mResolved = false; child.ResolveValue(elemType); if (fixedSize) { list[i] = child.mValue; } else { list.Add(child.mValue); } } else if (child.name == "Add") { child.ResolveValue(elemType); if (fixedSize) { list[i] = child.mValue; } else { list.Add(child.mValue); } } else { Debug.LogWarning("Unexpected node in an array: " + child.name); } } return(false); } else { Debug.LogError("Unable to determine the element type of " + type); } } else if (type.IsClass) { for (int i = 0; i < children.size; ++i) { DataNode child = children[i]; mValue.SetSerializableField(child.name, child.value); } return(false); } else { Debug.LogError("Unhandled type: " + type); } } return(true); }
/// <summary> /// Process the string values, converting them to proper objects. /// Returns whether child nodes should be processed in turn. /// </summary> public bool ResolveValue(Type type = null) { if (mValue is string) { mResolved = true; string line = mValue as string; // Trim strings wrapped in quotes if (type == typeof(string)) { if (line == "\"\"") { mValue = ""; } else { int len = line.Length; if (len > 2 && line[0] == '"' && line[len - 1] == '"') { mValue = line.Substring(1, len - 2); } } return(true); } // Try to resolve this type as a simple type if (Serialization.ReadObject(line, out mValue, type)) { return(true); } // This type is either a class or an array if (type == null) { type = Serialization.NameToType(line); } if (type == null || type == typeof(void)) { mValue = null; return(true); } else if (type.Implements(typeof(IDataNodeSerializable))) { IDataNodeSerializable ds = (IDataNodeSerializable)type.Create(); ds.Deserialize(this); mValue = ds; return(false); } #if !STANDALONE else if (type == typeof(AnimationCurve)) { if (children.size != 0) { AnimationCurve cv = new AnimationCurve(); Keyframe[] kfs = new Keyframe[children.size]; for (int i = 0; i < children.size; ++i) { DataNode child = children[i]; if (child.value == null) { child.mValue = child.name; child.mResolved = false; child.ResolveValue(typeof(Vector4)); Vector4 v = (Vector4)child.mValue; kfs[i] = new Keyframe(v.x, v.y, v.z, v.w); } else { Vector4 v = (Vector4)child.mValue; kfs[i] = new Keyframe(v.x, v.y, v.z, v.w); } } cv.keys = kfs; mValue = cv; children.Clear(); } return(false); } else if (type == typeof(LayerMask)) { mValue = (LayerMask)Get <int>(); } #endif else #if !STANDALONE if (!type.IsSubclassOf(typeof(Component))) #endif { bool isIList = type.Implements(typeof(System.Collections.IList)); bool isTList = (!isIList && type.Implements(typeof(TList))); mValue = (isTList || isIList) ? type.Create(children.size) : type.Create(); if (mValue == null) { Tools.LogError("Unable to create a " + type); return(true); } if (isTList) { TList list = mValue as TList; Type elemType = type.GetGenericArgument(); if (elemType != null) { for (int i = 0; i < children.size; ++i) { DataNode child = children[i]; if (child.value == null) { child.mValue = child.name; child.mResolved = false; child.ResolveValue(elemType); list.Add(child.mValue); } else if (child.name == "Add") { child.ResolveValue(elemType); list.Add(child.mValue); } else { Tools.LogError("Unexpected node in an array: " + child.name); } } return(false); } else { Tools.LogError("Unable to determine the element type of " + type); } } else if (isIList) { // This is for both List<Type> and Type[] arrays. System.Collections.IList list = mValue as System.Collections.IList; Type elemType = type.GetGenericArgument(); if (elemType == null) { elemType = type.GetElementType(); } bool fixedSize = (list.Count == children.size); if (elemType != null) { for (int i = 0; i < children.size; ++i) { DataNode child = children[i]; if (child.value == null) { child.mValue = child.name; child.mResolved = false; child.ResolveValue(elemType); if (fixedSize) { list[i] = child.mValue; } else { list.Add(child.mValue); } } else if (child.name == "Add") { child.ResolveValue(elemType); if (fixedSize) { list[i] = child.mValue; } else { list.Add(child.mValue); } } else { Tools.LogError("Unexpected node in an array: " + child.name); } } return(false); } else { Tools.LogError("Unable to determine the element type of " + type); } } else if (type.IsClass) { for (int i = 0; i < children.size; ++i) { DataNode child = children[i]; mValue.SetFieldOrPropertyValue(child.name, child.value); } return(false); } #if UNITY_EDITOR else { Debug.LogError("Unhandled type: " + type); } #else else { Tools.LogError("Unhandled type: " + type); } #endif } return(true); }
/// <summary> /// Write the values into the stream writer. /// </summary> static void Write(StreamWriter writer, int tab, string name, object value, bool writeType) { if (string.IsNullOrEmpty(name) && value == null) { return; } WriteTabs(writer, tab); if (name != null) { writer.Write(Escape(name)); if (value == null) { writer.Write('\n'); return; } } Type type = value.GetType(); if (type == typeof(string)) { if (name != null) { writer.Write(" = \""); } writer.Write((string)value); if (name != null) { writer.Write('"'); } writer.Write('\n'); } else if (type == typeof(bool)) { if (name != null) { writer.Write(" = "); } writer.Write((bool)value ? "true" : "false"); writer.Write('\n'); } else if (type == typeof(Int32) || type == typeof(float) || type == typeof(UInt32) || type == typeof(byte) || type == typeof(short) || type == typeof(ushort)) { if (name != null) { writer.Write(" = "); } writer.Write(value.ToString()); writer.Write('\n'); } else if (type == typeof(Vector2)) { Vector2 v = (Vector2)value; writer.Write(name != null ? " = (" : "("); writer.Write(v.x.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.y.ToString(CultureInfo.InvariantCulture)); writer.Write(")\n"); } else if (type == typeof(Vector3)) { Vector3 v = (Vector3)value; writer.Write(name != null ? " = (" : "("); writer.Write(v.x.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.y.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.z.ToString(CultureInfo.InvariantCulture)); writer.Write(")\n"); } else if (type == typeof(Color)) { Color c = (Color)value; writer.Write(name != null ? " = (" : "("); writer.Write(c.r.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(c.g.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(c.b.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(c.a.ToString(CultureInfo.InvariantCulture)); writer.Write(")\n"); } else if (type == typeof(Color32)) { Color32 c = (Color32)value; writer.Write(name != null ? " = 0x" : "0x"); if (c.a == 255) { int i = (c.r << 16) | (c.g << 8) | c.b; writer.Write(i.ToString("X6")); } else { int i = (c.r << 24) | (c.g << 16) | (c.b << 8) | c.a; writer.Write(i.ToString("X8")); } writer.Write('\n'); } else { if (type == typeof(Vector4)) { Vector4 v = (Vector4)value; if (name != null) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); writer.Write('('); writer.Write(v.x.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.y.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.z.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.w.ToString(CultureInfo.InvariantCulture)); writer.Write(")\n"); } else if (type == typeof(Quaternion)) { Quaternion q = (Quaternion)value; Vector3 v = q.eulerAngles; if (name != null) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); writer.Write('('); writer.Write(v.x.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.y.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(v.z.ToString(CultureInfo.InvariantCulture)); writer.Write(")\n"); } else if (type == typeof(Rect)) { Rect r = (Rect)value; if (name != null) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); writer.Write('('); writer.Write(r.x.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(r.y.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(r.width.ToString(CultureInfo.InvariantCulture)); writer.Write(", "); writer.Write(r.height.ToString(CultureInfo.InvariantCulture)); writer.Write(")\n"); } else if (value is TList) { TList list = value as TList; if (name != null) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); writer.Write('\n'); if (list.Count > 0) { for (int i = 0, imax = list.Count; i < imax; ++i) { Write(writer, tab + 1, null, list.Get(i), false); } } } else if (value is System.Collections.IList) { System.Collections.IList list = value as System.Collections.IList; if (name != null) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); writer.Write('\n'); if (list.Count > 0) { for (int i = 0, imax = list.Count; i < imax; ++i) { Write(writer, tab + 1, null, list[i], false); } } } else if (value is IDataNodeSerializable) { IDataNodeSerializable ser = value as IDataNodeSerializable; DataNode node = new DataNode(); ser.Serialize(node); if (name != null) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); writer.Write('\n'); for (int i = 0; i < node.children.size; ++i) { DataNode child = node.children[i]; child.Write(writer, tab + 1); } } else if (value is GameObject) { Debug.LogError("It's not possible to save game objects."); writer.Write('\n'); } else if ((value as Component) != null) { Debug.LogError("It's not possible to save components."); writer.Write('\n'); } else { if (writeType) { if (name != null) { writer.Write(" = "); } writer.Write(Serialization.TypeToName(type)); } writer.Write('\n'); #if REFLECTION_SUPPORT List <FieldInfo> fields = type.GetSerializableFields(); if (fields.size > 0) { for (int i = 0; i < fields.size; ++i) { FieldInfo field = fields[i]; object val = field.GetValue(value); if (val != null) { Write(writer, tab + 1, field.Name, val, true); } } } #endif } } }