Пример #1
0
            public static object FromJSONElement(Type objType, JSONElement node, object defualtObject = null)
            {
                object obj = null;

                //If object is an array convert each element one by one
                if (objType.IsArray)
                {
                    JSONArray jsonArray = (JSONArray)node;

                    int numChildren = node != null ? jsonArray._elements.Count : 0;

                    //Create a new array from this nodes children
                    Array array = Array.CreateInstance(objType.GetElementType(), numChildren);

                    for (int i = 0; i < array.Length; i++)
                    {
                        //Convert child node
                        object elementObj = FromJSONElement(objType.GetElementType(), jsonArray._elements[i]);
                        //Then set it on the array
                        array.SetValue(elementObj, i);
                    }

                    //Then set value on member
                    obj = array;
                }
                else
                {
                    //First find the actual object type from the JSONElement (could be different due to inheritance)
                    Type realObjType = GetRuntimeType(node);

                    //If the JSON node type and passed in type are both generic then read type from runtime type node
                    if (NeedsRuntimeTypeInfo(objType, realObjType))
                    {
                        realObjType = ReadTypeFromRuntimeTypeInfo(node);

                        //If its still can't be found then use passed in type
                        if (realObjType == null)
                        {
                            realObjType = objType;
                        }
                    }
                    //If we don't have an JSONElement or the object type is invalid then use passed in type
                    else if (node == null || realObjType == null || realObjType.IsAbstract || realObjType.IsGenericType)
                    {
                        realObjType = objType;
                    }

                    //Convert objects fields
                    if (defualtObject != null)
                    {
                        obj = defualtObject;
                    }
                    //Create an object instance if default not passed in
                    else if (!realObjType.IsAbstract)
                    {
                        obj = CreateInstance(realObjType);
                    }

                    //If the object has an associated converter class, convert the object using it
                    ObjectConverter converter = GetConverter(realObjType);
                    if (converter != null)
                    {
                        obj = converter._onConvertFromJSONElement(obj, node);
                    }
                    //Otherwise convert fields
                    else if (node != null && obj != null)
                    {
                        JSONField[] JSONFields = GetJSONFields(realObjType);
                        foreach (JSONField JSONField in JSONFields)
                        {
                            //First try and find JSON node with an id attribute matching our attribute id
                            JSONElement fieldNode = JSONUtils.FindChildWithAttributeValue(node, kJSONFieldIdAttributeTag, JSONField.GetID());

                            object fieldObj     = JSONField.GetValue(obj);
                            Type   fieldObjType = JSONField.GetFieldType();

                            //Convert the object from JSON node
                            fieldObj = FromJSONElement(fieldObjType, fieldNode, fieldObj);

                            //Then set value on parent object
                            try
                            {
                                JSONField.SetValue(obj, fieldObj);
                            }
                            catch (Exception e)
                            {
                                throw e;
                            }
                        }
                    }
                }

                //IJSONConversionCallbackReceiver callback
                if (obj is IJSONConversionCallbackReceiver)
                {
                    ((IJSONConversionCallbackReceiver)obj).OnConvertFromJSONElement(node);
                }

                return(obj);
            }
Пример #2
0
            //The equivalent of a SerializedPropertyField but for objects serialized using JSON.
            public static T ObjectField <T>(T obj, GUIContent label, out bool dataChanged)
            {
                //If object is an array show an editable array field
                if (typeof(T).IsArray)
                {
                    bool  arrayChanged = false;
                    Array arrayObj     = obj as Array;
                    arrayObj = ArrayField(label, arrayObj, typeof(T).GetElementType(), ref arrayChanged);

                    if (arrayChanged)
                    {
                        dataChanged = true;
                        return((T)(arrayObj as object));
                    }

                    dataChanged = false;
                    return(obj);
                }

                //If the object is a IJSONCustomEditable then just need to call its render properties function.
                if (obj != null && obj is IJSONCustomEditable)
                {
                    dataChanged = ((IJSONCustomEditable)obj).RenderObjectProperties(label);
                    return(obj);
                }

                Type objType = obj == null ? typeof(T) : obj.GetType();

                //Otherwise check the class has a object editor class associated with it.
                JSONEditorAttribute.RenderPropertiesDelegate renderPropertiesDelegate = GetEditorDelegateForObject(objType);
                if (renderPropertiesDelegate != null)
                {
                    //If it has one then just need to call its render properties function.
                    return((T)renderPropertiesDelegate(obj, label, out dataChanged));
                }

                //Otherwise loop through each JSON field in object and render each as a property field
                {
                    dataChanged = false;
                    JSONField[] JSONFields = JSONConverter.GetJSONFields(objType);
                    foreach (JSONField JSONField in JSONFields)
                    {
                        if (!JSONField.HideInEditor())
                        {
                            //Create GUIContent for label and optional tooltip
                            string           fieldName       = StringUtils.FromCamelCase(JSONField.GetID());
                            TooltipAttribute fieldToolTipAtt = SystemUtils.GetAttribute <TooltipAttribute>(JSONField);
                            GUIContent       labelContent    = fieldToolTipAtt != null ? new GUIContent(fieldName, fieldToolTipAtt.tooltip) : new GUIContent(fieldName);

                            bool   fieldChanged;
                            object nodeFieldObject = JSONField.GetValue(obj);

                            if (JSONField.GetFieldType().IsArray)
                            {
                                fieldChanged    = false;
                                nodeFieldObject = ArrayField(labelContent, nodeFieldObject as Array, JSONField.GetFieldType().GetElementType(), ref fieldChanged);
                            }
                            else
                            {
                                nodeFieldObject = ObjectField(nodeFieldObject, labelContent, out fieldChanged);
                            }

                            if (fieldChanged)
                            {
                                dataChanged = true;
                                JSONField.SetValue(obj, nodeFieldObject);
                            }
                        }
                    }

                    return(obj);
                }
            }