//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// using System; using System.Runtime.CompilerServices; namespace BansheeEngine { /** @addtogroup Serialization * @{ */ #pragma warning disable 649 /// /// Allows you to access meta-data about a managed array and its children. Similar to Reflection but simpler and faster. /// public sealed class SerializableArray : ScriptObject { private SerializableProperty.FieldType elementPropertyType; private Type elementType; private SerializableProperty parentProperty; /// /// Type of serializable property used for the elements stored in the array. /// public SerializableProperty.FieldType ElementPropertyType { get { return elementPropertyType; } } /// /// Type used for the elements stored in the array. /// public Type ElementType { get { return elementType; } } /// /// Constructor for use by the runtime only. /// /// C# type of the elements in the array. /// Property used for retrieving this entry. private SerializableArray(Type elementType, SerializableProperty parentProperty) { this.parentProperty = parentProperty; this.elementType = elementType; elementPropertyType = SerializableProperty.DetermineFieldType(elementType); } /// /// Returns a serializable property for a specific array element. /// /// Index of the element in the array. /// Serializable property that allows you to manipulate contents of the array entry. public SerializableProperty GetProperty(int elementIdx) { SerializableProperty.Getter getter = () => { Array array = parentProperty.GetValue(); if (array != null) return array.GetValue(elementIdx); else return null; }; SerializableProperty.Setter setter = (object value) => { Array array = parentProperty.GetValue(); if(array != null) array.SetValue(value, elementIdx); }; SerializableProperty property = Internal_CreateProperty(mCachedPtr); property.Construct(ElementPropertyType, elementType, getter, setter); return property; } /// /// Returns number of elements in the array. /// /// Number of elements in the array. public int GetLength() { Array array = parentProperty.GetValue(); if (array != null) return array.GetLength(0); // TODO - Support multi-rank arrays else return 0; } /// /// Uses the provided path elements to find an array element at the specified index, and returns a property /// to the element, or to a child property of that element. /// /// Path elements representing field names and keys to look for. /// Index in the array to start the search at. /// Property representing the final path element, or null if not found (array index is out of range, or /// property with that path doesn't exist). internal SerializableProperty FindProperty(PropertyPathElement[] pathElements, int elementIdx) { int arrayIdx; if (string.IsNullOrEmpty(pathElements[elementIdx].key)) arrayIdx = 0; else { if (!int.TryParse(pathElements[elementIdx].key, out arrayIdx)) return null; else { if (arrayIdx < 0 || arrayIdx >= GetLength()) return null; } } SerializableProperty property = GetProperty(arrayIdx); if (elementIdx == (pathElements.Length - 1)) return property; return property.FindProperty(pathElements, elementIdx + 1); } [MethodImpl(MethodImplOptions.InternalCall)] private static extern SerializableProperty Internal_CreateProperty(IntPtr nativeInstance); } /** @} */ }