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