Exemple #1
0
        private string GenerateWrites()
        {
            var    type        = types[selectedType].type;
            bool   isComponent = typeof(Component).IsAssignableFrom(type);
            string writes      = "";

            for (int i = 0; i < fields.Length; i++)
            {
                var field    = fields[i];
                var selected = fieldSelected[i];
                var es3Type  = ES3TypeMgr.GetES3Type(field.MemberType);

                if (!selected || isComponent && (field.Name == ES3Reflection.componentTagFieldName || field.Name == ES3Reflection.componentNameFieldName))
                {
                    continue;
                }

                string writeByRef   = ES3Reflection.IsAssignableFrom(typeof(UnityEngine.Object), field.MemberType) ? "ByRef" : "";
                string es3TypeParam = HasExplicitES3Type(es3Type) && writeByRef == "" ? ", " + es3Type.GetType().Name + ".Instance" : "";

                if (!field.IsPublic)
                {
                    string memberType = field.isProperty ? "Property" : "Field";
                    writes += String.Format("\n\t\t\twriter.WritePrivate{3}{1}(\"{0}\", instance);", field.Name, writeByRef, es3TypeParam, memberType);
                }
                else
                {
                    writes += String.Format("\n\t\t\twriter.WriteProperty{1}(\"{0}\", instance.{0}{2});", field.Name, writeByRef, es3TypeParam);
                }
            }
            return(writes);
        }
Exemple #2
0
        private string GenerateWrites()
        {
            var    type        = types[selectedType].type;
            bool   isComponent = typeof(Component).IsAssignableFrom(type);
            string writes      = "";

            for (int i = 0; i < fields.Length; i++)
            {
                var field    = fields[i];
                var selected = fieldSelected[i];
                var es3Type  = ES3TypeMgr.GetES3Type(field.MemberType);

                if (!selected || isComponent && (field.Name == ES3Reflection.componentTagFieldName || field.Name == ES3Reflection.componentNameFieldName))
                {
                    continue;
                }

                string writeByRef   = ES3Reflection.IsAssignableFrom(typeof(UnityEngine.Object), field.MemberType) ? "ByRef" : "";
                string es3TypeParam = HasExplicitES3Type(es3Type) && writeByRef == "" ? ", " + es3Type.GetType().Name + ".Instance" : (writeByRef == "" ? ", ES3Internal.ES3TypeMgr.GetOrCreateES3Type(typeof(" + GetFullTypeName(field.MemberType) + "))" : "");
                // If this is static, access the field through the class name rather than through an instance.
                string instance = (field.IsStatic) ? GetFullTypeName(type) : "instance";

                if (!field.IsPublic)
                {
                    string memberType = field.isProperty ? "Property" : "Field";
                    writes += String.Format("\r\n\t\t\twriter.WritePrivate{2}{1}(\"{0}\", instance);", field.Name, writeByRef, memberType);
                }
                else
                {
                    writes += String.Format("\r\n\t\t\twriter.WriteProperty{1}(\"{0}\", {3}.{0}{2});", field.Name, writeByRef, es3TypeParam, instance);
                }
            }
            return(writes);
        }
Exemple #3
0
        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));
                }
            }
        }
Exemple #4
0
        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);
        }
Exemple #5
0
    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);
        }
    }
Exemple #6
0
        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 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);
        }
        private void TypePane()
        {
            if (selectedType < 0)
            {
                return;
            }

            var style = EditorStyle.Get;

            var typeListItem = types[selectedType];
            var type         = typeListItem.type;

            typePaneScrollPos = EditorGUILayout.BeginScrollView(typePaneScrollPos, style.area);

            GUILayout.Label(typeListItem.name, style.subheading);
            GUILayout.Label(typeListItem.namespaceName);

            EditorGUILayout.BeginVertical(style.area);

            bool hasParameterlessConstructor = ES3Reflection.HasParameterlessConstructor(type);
            bool isComponent = ES3Reflection.IsAssignableFrom(typeof(Component), type);

            string path = GetOutputPath(types[selectedType].type);

            // An ES3Type file already exists.
            if (File.Exists(path))
            {
                if (hasParameterlessConstructor || isComponent)
                {
                    EditorGUILayout.BeginHorizontal();
                    if (GUILayout.Button("Reset to Default"))
                    {
                        SelectNone(true, true);
                        AssetDatabase.MoveAssetToTrash("Assets" + path.Remove(0, Application.dataPath.Length));
                        SelectType(selectedType);
                    }
                    if (GUILayout.Button("Edit ES3Type Script"))
                    {
                        UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(path, 1);
                    }
                    EditorGUILayout.EndHorizontal();
                }
                else
                {
                    EditorGUILayout.HelpBox("This type has no public parameterless constructors.\n\nTo support this type you will need to modify the ES3Type script to use a specific constructor instead of the parameterless constructor.", MessageType.Info);
                    if (GUILayout.Button("Click here to edit the ES3Type script"))
                    {
                        UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(path, 1);
                    }
                    if (GUILayout.Button("Reset to Default"))
                    {
                        SelectAll(true, true);
                        File.Delete(path);
                        AssetDatabase.Refresh();
                    }
                }
            }
            // No ES3Type file and no fields.
            else if (fields.Length == 0)
            {
                if (!hasParameterlessConstructor && !isComponent)
                {
                    EditorGUILayout.HelpBox("This type has no public parameterless constructors.\n\nTo support this type you will need to create an ES3Type script and modify it to use a specific constructor instead of the parameterless constructor.", MessageType.Info);
                }

                if (GUILayout.Button("Create ES3Type Script"))
                {
                    Generate();
                }
            }
            // No ES3Type file, but fields are selectable.
            else
            {
                if (!hasParameterlessConstructor && !isComponent)
                {
                    EditorGUILayout.HelpBox("This type has no public parameterless constructors.\n\nTo support this type you will need to select the fields you wish to serialize below, and then modify the generated ES3Type script to use a specific constructor instead of the parameterless constructor.", MessageType.Info);
                    if (GUILayout.Button("Select all fields and generate ES3Type script"))
                    {
                        SelectAll(true, false);
                        Generate();
                    }
                }
                else
                {
                    if (GUILayout.Button("Create ES3Type Script"))
                    {
                        Generate();
                    }
                }
            }

            EditorGUILayout.EndVertical();

            PropertyPane();

            EditorGUILayout.EndScrollView();
        }