protected object ReadProperties(ES3Reader reader, object obj) { // Iterate through each property in the file and try to load it using the appropriate // ES3Member in the members array. foreach (string propertyName in reader.Properties) { // Find the property. ES3Member property = null; for (int i = 0; i < members.Length; i++) { if (members[i].name == propertyName) { property = members[i]; break; } } if (property == null) { reader.Skip(); } else { var type = ES3TypeMgr.GetOrCreateES3Type(property.type); if (ES3Reflection.IsAssignableFrom(typeof(IDictionary), property.type)) { property.reflectedMember.SetValue(obj, ((ES3DictionaryType)type).Read(reader)); } else if (ES3Reflection.IsAssignableFrom(typeof(ICollection), property.type)) { property.reflectedMember.SetValue(obj, ((ES3CollectionType)type).Read(reader)); } else { object readObj = reader.Read <object>(type); property.reflectedMember.SetValue(obj, readObj); } } } return(obj); }
private string GenerateReads() { var type = types[selectedType].type; bool isComponent = typeof(Component).IsAssignableFrom(type); string reads = ""; for (int i = 0; i < fields.Length; i++) { var field = fields[i]; var selected = fieldSelected[i]; if (!selected || isComponent && (field.Name == "tag" || field.Name == "name")) { continue; } string fieldTypeName = GetFullTypeName(field.MemberType); string es3TypeParam = HasExplicitES3Type(field.MemberType) ? ES3TypeMgr.GetES3Type(field.MemberType).GetType().Name + ".Instance" : ""; // If this is static, access the field through the class name rather than through an instance. string instance = (field.IsStatic) ? GetFullTypeName(type) : "instance"; // If we're writing a private field or property, we need to write it using a different method. if (!field.IsPublic) { es3TypeParam = ", " + es3TypeParam; if (field.isProperty) { reads += String.Format("\r\n\t\t\t\t\tcase \"{0}\":\r\n\t\t\t\t\treader.SetPrivateProperty(\"{0}\", reader.Read<{1}>(), instance);\r\n\t\t\t\t\tbreak;", field.Name, fieldTypeName); } else { reads += String.Format("\r\n\t\t\t\t\tcase \"{0}\":\r\n\t\t\t\t\treader.SetPrivateField(\"{0}\", reader.Read<{1}>(), instance);\r\n\t\t\t\t\tbreak;", field.Name, fieldTypeName); } } else { reads += String.Format("\r\n\t\t\t\t\tcase \"{0}\":\r\n\t\t\t\t\t\t{3}.{0} = reader.Read<{1}>({2});\r\n\t\t\t\t\t\tbreak;", field.Name, fieldTypeName, es3TypeParam, instance); } } return(reads); }
public override object Read <T>(ES3Reader reader) { if (members == null) { GetMembers(reader.settings.safeReflection); } object obj; string propertyName = reader.ReadPropertyName(); // If we're loading a derived type, use it's specific ES3Type. if (propertyName == ES3Type.typeFieldName) { return(ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).Read <T>(reader)); } // If we're loading a reference, load it. Else, create an instance. if (propertyName == ES3ReferenceMgrBase.referencePropertyName) { long id = reader.Read <long>(ES3Type_long.Instance); obj = ES3ReferenceMgrBase.Current.Get(id); if (obj == null) { // If an instance isn't already registered for this object, create an instance and register the reference. obj = ES3Reflection.CreateInstance(this.type); ES3ReferenceMgrBase.Current.Add((UnityEngine.Object)obj, id); } } else { reader.overridePropertiesName = propertyName; obj = ES3Reflection.CreateInstance(this.type); } // Iterate through each property in the file and try to load it using the appropriate // ES3Property in the members array. ReadProperties(reader, obj); return(obj); }
private string GenerateReads() { var type = types[selectedType].type; bool isComponent = typeof(Component).IsAssignableFrom(type); string reads = ""; for (int i = 0; i < fields.Length; i++) { var field = fields[i]; var selected = fieldSelected[i]; var es3Type = ES3TypeMgr.GetOrCreateES3Type(field.FieldType); if (!selected || isComponent && (field.Name == "tag" || field.Name == "name")) { continue; } string fieldTypeName = GetFullTypeName(field.FieldType); string es3TypeParam = HasExplicitES3Type(es3Type.type) ? es3Type.GetType().Name + ".Instance" : ""; // If we're writing a private field or property, we need to write it using a different method. if (!field.IsPublic) { es3TypeParam = ", " + es3TypeParam; if (field.isProperty) { reads += String.Format("\n\t\t\t\t\tcase \"{0}\":\n\t\t\t\t\treader.SetPrivateProperty(\"{0}\", reader.Read<{1}>(), instance);\n\t\t\t\t\tbreak;", field.Name, fieldTypeName); } else { reads += String.Format("\n\t\t\t\t\tcase \"{0}\":\n\t\t\t\t\treader.SetPrivateField(\"{0}\", reader.Read<{1}>(), instance);\n\t\t\t\t\tbreak;", field.Name, fieldTypeName); } } else { reads += String.Format("\n\t\t\t\t\tcase \"{0}\":\n\t\t\t\t\t\tinstance.{0} = reader.Read<{1}>({2});\n\t\t\t\t\t\tbreak;", field.Name, fieldTypeName, es3TypeParam); } } return(reads); }
protected bool WriteUsingDerivedType(object obj, ES3Writer writer, ES3.ReferenceMode mode) { var objType = obj.GetType(); if (objType != this.type) { writer.WriteType(objType); var es3Type = ES3TypeMgr.GetOrCreateES3Type(objType); if (es3Type is ES3UnityObjectType) { ((ES3UnityObjectType)es3Type).WriteObject(obj, writer, mode); } else { es3Type.Write(obj, writer); } return(true); } return(false); }
public override object Read <T>(ES3Reader reader) { string propertyName; while (true) { propertyName = ReadPropertyName(reader); if (propertyName == ES3Type.typeFieldName) { return(ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).Read <T>(reader)); } else if (propertyName == null) { return(null); } else { reader.overridePropertiesName = propertyName; return(ReadObject <T>(reader)); } } }
public override void ReadInto <T>(ES3Reader reader, object obj) { string propertyName; while (true) { propertyName = ReadPropertyName(reader); if (propertyName == ES3Type.typeFieldName) { ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).ReadInto <T>(reader, obj); return; } else if (propertyName == null) { return; } else { reader.overridePropertiesName = propertyName; ReadObject <T>(reader, obj); } } }
public override void ReadInto <T>(ES3Reader reader, object obj) { if (members == null) { GetMembers(reader.settings.safeReflection); } string propertyName = reader.ReadPropertyName(); // If we're loading a derived type, use it's specific ES3Type. if (propertyName == ES3Type.typeFieldName) { ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).ReadInto <T>(reader, obj); return; } else { reader.overridePropertiesName = propertyName; } // Iterate through each property in the file and try to load it using the appropriate // ES3Property in the members array. ReadProperties(reader, obj); }
/// <summary>Reads a value of type T from the reader into an existing object.</summary> /// <param name="obj">The object we want to read our value into.</param> public virtual void ReadInto <T>(object obj) { ReadInto <T>(obj, ES3TypeMgr.GetOrCreateES3Type(typeof(T))); }
protected void WriteProperties(object obj, ES3Writer writer) { if (members == null) { GetMembers(writer.settings.safeReflection); } for (int i = 0; i < members.Length; i++) { var property = members[i]; writer.WriteProperty(property.name, property.reflectedMember.GetValue(obj), ES3TypeMgr.GetOrCreateES3Type(property.type), writer.settings.memberReferenceMode); } }
protected void ReadUsingDerivedType <T>(ES3Reader reader, object obj) { ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).ReadInto <T>(reader, obj); }
protected ES3Type(Type type) { ES3TypeMgr.Add(type, this); this.type = type; this.isValueType = ES3Reflection.IsValueType(type); }
/// <summary>Writes a field or property to the writer. Note that this should only be called within an ES3Type.</summary> /// <param name="name">The name of the field or property.</param> /// <param name="value">The value we want to write.</param> public virtual void WriteProperty <T>(string name, object value) { WriteProperty(name, value, ES3TypeMgr.GetOrCreateES3Type(typeof(T)), settings.memberReferenceMode); }
public virtual void Write(object value, ES3Type type, ES3.ReferenceMode memberReferenceMode = ES3.ReferenceMode.ByRef) { // Note that we have to check UnityEngine.Object types for null by casting it first, otherwise // it will always return false. if (value == null || (ES3Reflection.IsAssignableFrom(typeof(UnityEngine.Object), value.GetType()) && value as UnityEngine.Object == null)) { WriteNull(); return; } // Deal with System.Objects if (type == null || type.type == typeof(object)) { var valueType = value.GetType(); type = ES3TypeMgr.GetOrCreateES3Type(valueType); if (type == null) { throw new NotSupportedException("Types of " + valueType + " are not supported. Please see the Supported Types guide for more information: https://docs.moodkie.com/easy-save-3/es3-supported-types/"); } if (!type.isCollection && !type.isDictionary) { StartWriteObject(null); WriteType(valueType); type.Write(value, this); EndWriteObject(null); return; } } if (type == null) { throw new ArgumentNullException("ES3Type argument cannot be null."); } if (type.isUnsupported) { if (type.isCollection || type.isDictionary) { throw new NotSupportedException(type.type + " is not supported because it's element type is not supported. Please see the Supported Types guide for more information: https://docs.moodkie.com/easy-save-3/es3-supported-types/"); } else { throw new NotSupportedException("Types of " + type.type + " are not supported. Please see the Supported Types guide for more information: https://docs.moodkie.com/easy-save-3/es3-supported-types/"); } } if (type.isPrimitive || type.isEnum) { type.Write(value, this); } else if (type.isCollection) { StartWriteCollection(); ((ES3CollectionType)type).Write(value, this, memberReferenceMode); EndWriteCollection(); } else if (type.isDictionary) { StartWriteDictionary(); ((ES3DictionaryType)type).Write(value, this, memberReferenceMode); EndWriteDictionary(); } else { if (type.type == typeof(GameObject)) { ((ES3Type_GameObject)type).saveChildren = settings.saveChildren; } StartWriteObject(null); if (type.isES3TypeUnityObject) { ((ES3UnityObjectType)type).WriteObject(value, this, memberReferenceMode); } else { type.Write(value, this); } EndWriteObject(null); } }
public override object Read <T>(ES3Reader reader) { UnityEngine.Object obj = null; // Read the intial properties regarding the instance we're loading. while (true) { var refMgr = ES3ReferenceMgrBase.Current; if (refMgr == null) { reader.Skip(); continue; } var propertyName = ReadPropertyName(reader); if (propertyName == ES3Type.typeFieldName) { return(ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).Read <T>(reader)); } else if (propertyName == ES3ReferenceMgrBase.referencePropertyName) { if (refMgr == null) { reader.Skip(); continue; } long id = reader.Read <long>(ES3Type_long.Instance); obj = refMgr.Get(id); if (obj == null) { // If an instance isn't already registered for this object, create an instance and register the reference. obj = new GameObject(); refMgr.Add(obj, id); } else if (!ES3Reflection.IsAssignableFrom(typeof(T), obj.GetType())) { throw new MissingReferenceException("The instance with ID \"" + id + "\" is a different type than expected. Expected \"" + typeof(T) + "\", found \"" + obj.GetType() + "\""); } } else if (propertyName == transformPropertyName) { if (refMgr == null) { reader.Skip(); continue; } // Now load the Transform's ID and assign it to the Transform of our object. long transformID = reader.Read <long>(ES3Type_long.Instance); refMgr.Add(((GameObject)obj).transform, transformID); } else if (propertyName == prefabPropertyName) { if (ES3ReferenceMgrBase.Current == null) { reader.Skip(); } else { obj = reader.Read <GameObject>(ES3Type_ES3PrefabInternal.Instance); } } else if (propertyName == null) { return(obj); } else { reader.overridePropertiesName = propertyName; break; } } if (obj == null) { obj = new GameObject(); } ReadInto <T>(reader, obj); return(obj); }
public override void Write(object obj, ES3Writer writer) { // Manage NULL values. if (obj == null) { writer.WriteNull(); return; } ; UnityEngine.Object unityObj = obj as UnityEngine.Object; bool isUnityEngineObject = (unityObj != null); // If this is a derived type, write the type as a property and use it's specific ES3Type. var objType = obj.GetType(); if (objType != this.type) { writer.WriteType(objType); ES3TypeMgr.GetOrCreateES3Type(objType).Write(obj, writer); return; } if (isUnityEngineObject) { writer.WriteRef(unityObj); } if (members == null) { GetMembers(writer.settings.safeReflection); } for (int i = 0; i < members.Length; i++) { var property = members[i]; if (ES3Reflection.IsAssignableFrom(typeof(UnityEngine.Object), property.type)) { object valueObj = property.reflectedMember.GetValue(obj); UnityEngine.Object value = (valueObj == null) ? null : (UnityEngine.Object)valueObj; writer.WritePropertyByRef(property.name, value); } else { writer.WriteProperty(property.name, property.reflectedMember.GetValue(obj), ES3TypeMgr.GetOrCreateES3Type(property.type)); } } }
/// <summary>Initialises Easy Save. This happens automatically when any ES3 methods are called, but is useful if you want to perform initialisation before calling an ES3 method.</summary> public static void Init() { ES3Settings.LoadDefaults(); ES3TypeMgr.Init(); }
protected override object ReadObject <T>(ES3Reader reader) { UnityEngine.Object obj = null; var refMgr = ES3ReferenceMgrBase.Current; long id = 0; // Read the intial properties regarding the instance we're loading. while (true) { if (refMgr == null) { throw new InvalidOperationException("An Easy Save 3 Manager is required to load references. To add one to your scene, exit playmode and go to Assets > Easy Save 3 > Add Manager to Scene"); } var propertyName = ReadPropertyName(reader); if (propertyName == ES3Type.typeFieldName) { return(ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).Read <T>(reader)); } else if (propertyName == ES3ReferenceMgrBase.referencePropertyName) { id = reader.Read_ref(); obj = refMgr.Get(id, true); } else if (propertyName == transformPropertyName) { // Now load the Transform's ID and assign it to the Transform of our object. long transformID = reader.Read_ref(); if (obj == null) { obj = CreateNewGameObject(refMgr, id); } refMgr.Add(((GameObject)obj).transform, transformID); } else if (propertyName == prefabPropertyName) { if (obj != null || ES3ReferenceMgrBase.Current == null) { reader.Skip(); } else { obj = reader.Read <GameObject>(ES3Type_ES3PrefabInternal.Instance); ES3ReferenceMgrBase.Current.Add(obj, id); } } else if (propertyName == null) { if (obj == null) { return(CreateNewGameObject(refMgr, id)); } return(obj); } else { reader.overridePropertiesName = propertyName; break; } } if (obj == null) { obj = CreateNewGameObject(refMgr, id); } ReadInto <T>(reader, obj); return(obj); }
protected object ReadProperties(ES3Reader reader, object obj) { // Iterate through each property in the file and try to load it using the appropriate // ES3Member in the members array. foreach (string propertyName in reader.Properties) { // Find the property. ES3Member property = null; for (int i = 0; i < members.Length; i++) { if (members[i].name == propertyName) { property = members[i]; break; } } // If this is a class which derives directly from a Collection, we need to load it's dictionary first. if (propertyName == "_Values") { var baseType = ES3TypeMgr.GetOrCreateES3Type(ES3Reflection.BaseType(obj.GetType())); if (baseType.isDictionary) { var dict = (IDictionary)obj; var loaded = (IDictionary)baseType.Read <IDictionary>(reader); foreach (DictionaryEntry kvp in loaded) { dict[kvp.Key] = kvp.Value; } } else if (baseType.isCollection) { var loaded = (IEnumerable)baseType.Read <IEnumerable>(reader); var type = baseType.GetType(); if (type == typeof(ES3ListType)) { foreach (var item in loaded) { ((IList)obj).Add(item); } } else if (type == typeof(ES3QueueType)) { var method = baseType.type.GetMethod("Enqueue"); foreach (var item in loaded) { method.Invoke(obj, new object[] { item }); } } else if (type == typeof(ES3StackType)) { var method = baseType.type.GetMethod("Push"); foreach (var item in loaded) { method.Invoke(obj, new object[] { item }); } } else if (type == typeof(ES3HashSetType)) { var method = baseType.type.GetMethod("Add"); foreach (var item in loaded) { method.Invoke(obj, new object[] { item }); } } } } if (property == null) { reader.Skip(); } else { var type = ES3TypeMgr.GetOrCreateES3Type(property.type); if (ES3Reflection.IsAssignableFrom(typeof(ES3DictionaryType), type.GetType())) { property.reflectedMember.SetValue(obj, ((ES3DictionaryType)type).Read(reader)); } else if (ES3Reflection.IsAssignableFrom(typeof(ES3CollectionType), type.GetType())) { property.reflectedMember.SetValue(obj, ((ES3CollectionType)type).Read(reader)); } else { object readObj = reader.Read <object>(type); property.reflectedMember.SetValue(obj, readObj); } } } return(obj); }
public virtual void Write(object value, ES3Type type, ES3.ReferenceMode memberReferenceMode = ES3.ReferenceMode.ByRef) { // Deal with System.Objects if (type.type == typeof(object)) { var valueType = value.GetType(); type = ES3TypeMgr.GetOrCreateES3Type(valueType); if (!type.isCollection && !type.isDictionary) { StartWriteObject(null); WriteType(valueType); type.Write(value, this); EndWriteObject(null); return; } } // Note that we have to check UnityEngine.Object types for null by casting it first, otherwise // it will always return false. if (value == null || (type.isES3TypeUnityObject && ((UnityEngine.Object)value) == null)) { WriteNull(); return; } if (type == null) { throw new ArgumentNullException("ES3Type argument cannot be null."); } if (type.isUnsupported) { throw new NotSupportedException("Types of " + type.type + " are not supported."); } if (type.isPrimitive) { type.Write(value, this); } else if (type.isCollection) { StartWriteCollection(); ((ES3CollectionType)type).Write(value, this, memberReferenceMode); EndWriteCollection(); } else if (type.isDictionary) { StartWriteDictionary(); ((ES3DictionaryType)type).Write(value, this, memberReferenceMode); EndWriteDictionary(); } else { if (type.type == typeof(GameObject)) { ((ES3Type_GameObject)type).saveChildren = settings.saveChildren; } StartWriteObject(null); if (type.isES3TypeUnityObject) { ((ES3UnityObjectType)type).WriteObject(value, this, memberReferenceMode); } else { type.Write(value, this); } EndWriteObject(null); } }
protected override object ReadObject <T>(ES3Reader reader) { UnityEngine.Object obj = null; var refMgr = ES3ReferenceMgrBase.Current; long id = 0; // Read the intial properties regarding the instance we're loading. while (true) { if (refMgr == null) { reader.Skip(); continue; } var propertyName = ReadPropertyName(reader); if (propertyName == ES3Type.typeFieldName) { return(ES3TypeMgr.GetOrCreateES3Type(reader.ReadType()).Read <T>(reader)); } else if (propertyName == ES3ReferenceMgrBase.referencePropertyName) { if (refMgr == null) { reader.Skip(); continue; } id = reader.Read <long>(ES3Type_long.Instance); obj = refMgr.Get(id); } else if (propertyName == transformPropertyName) { if (refMgr == null) { reader.Skip(); continue; } // Now load the Transform's ID and assign it to the Transform of our object. long transformID = reader.Read <long>(ES3Type_long.Instance); if (obj == null) { obj = CreateNewGameObject(refMgr, id); } refMgr.Add(((GameObject)obj).transform, transformID); } else if (propertyName == prefabPropertyName) { if (obj != null || ES3ReferenceMgrBase.Current == null) { reader.Skip(); } else { obj = reader.Read <GameObject>(ES3Type_ES3PrefabInternal.Instance); } } else if (propertyName == null) { if (obj == null) { return(CreateNewGameObject(refMgr, id)); } return(obj); } else { reader.overridePropertiesName = propertyName; break; } } if (obj == null) { obj = CreateNewGameObject(refMgr, id); } ReadInto <T>(reader, obj); return(obj); }
/// <summary>Reads a value of type T from the reader.</summary> public virtual T Read <T>() { return(Read <T>(ES3TypeMgr.GetOrCreateES3Type(typeof(T)))); }
public T ReadProperty <T>() { return(ReadProperty <T>(ES3TypeMgr.GetOrCreateES3Type(typeof(T)))); }
public override void WriteObject(object obj, ES3Writer writer, ES3.ReferenceMode mode) { if (WriteUsingDerivedType(obj, writer)) { return; } var instance = (UnityEngine.GameObject)obj; if (mode != ES3.ReferenceMode.ByValue) { writer.WriteRef(instance); var es3Prefab = instance.GetComponent <ES3Prefab>(); if (es3Prefab != null) { writer.WriteProperty(prefabPropertyName, es3Prefab, ES3Type_ES3PrefabInternal.Instance); } // Write the ID of this Transform so we can assign it's ID when we load. writer.WriteProperty(transformPropertyName, ES3ReferenceMgrBase.Current.Add(instance.transform)); if (mode == ES3.ReferenceMode.ByRef) { return; } } var es3AutoSave = instance.GetComponent <ES3AutoSave>(); writer.WriteProperty("layer", instance.layer, ES3Type_int.Instance); writer.WriteProperty("tag", instance.tag, ES3Type_string.Instance); writer.WriteProperty("name", instance.name, ES3Type_string.Instance); writer.WriteProperty("hideFlags", instance.hideFlags); writer.WriteProperty("active", instance.activeSelf); if (saveChildren || (es3AutoSave != null && es3AutoSave.saveChildren)) { writer.WriteProperty("children", GetChildren(instance), ES3.ReferenceMode.ByRefAndValue); } List <Component> components; // If there's an ES3AutoSave attached and Components are marked to be saved, save these. var autoSave = instance.GetComponent <ES3AutoSave>(); if (autoSave != null && autoSave.componentsToSave != null && autoSave.componentsToSave.Count > 0) { components = autoSave.componentsToSave; } // Otherwise, only save explicitly-supported Components, /*or those explicitly marked as Serializable*/. else { components = new List <Component>(); foreach (var component in instance.GetComponents <Component>()) { if (component != null && ES3TypeMgr.GetES3Type(component.GetType()) != null) { components.Add(component); } } } writer.WriteProperty("components", components, ES3.ReferenceMode.ByRefAndValue); }
private void ReadComponents(ES3Reader reader, GameObject go) { if (reader.StartReadCollection()) { return; } var components = new List <Component>(go.GetComponents <Component>()); // Read each Component in Components array while (true) { if (!reader.StartReadCollectionItem()) { break; } if (reader.StartReadObject()) { return; } Type type = null; string propertyName; while (true) { propertyName = ReadPropertyName(reader); if (propertyName == ES3Type.typeFieldName) { type = reader.ReadType(); } else if (propertyName == ES3ReferenceMgrBase.referencePropertyName) { if (type == null) { throw new InvalidOperationException("Cannot load Component because no type data has been stored with it, so it's not possible to determine it's type"); } var componentRef = reader.Read_ref(); // Rather than loading by reference, load using the Components list. var c = components.Find(x => x.GetType() == type); // If the Component exists in the Component list, load into it and remove it from the list. if (c != null) { if (ES3ReferenceMgrBase.Current != null) { ES3ReferenceMgrBase.Current.Add(c, componentRef); } ES3TypeMgr.GetOrCreateES3Type(type).ReadInto <Component>(reader, c); components.Remove(c); } // Else, create a new Component. else { var component = ES3TypeMgr.GetOrCreateES3Type(type).Read <Component>(reader); if (component != null) { ES3ReferenceMgrBase.Current.Add((Component)component, componentRef); } } break; } else if (propertyName == null) { break; } else { reader.overridePropertiesName = propertyName; ReadObject <Component>(reader); break; } } reader.EndReadObject(); if (reader.EndReadCollectionItem()) { break; } } reader.EndReadCollection(); }