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); }
//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); } }