//********************************** 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 * @{ */ /// /// Flags as defined in native code in BsManagedSerializableObjectInfo.h /// enum SerializableFieldAttributes : byte { Serializable = 0x01, Inspectable = 0x02, Ranged = 0x04, Stepped = 0x08 } /// /// Allows you to access meta-data about field in an object. Similar to Reflection but simpler and faster. /// public class SerializableField : ScriptObject { private SerializableObject parent; private SerializableProperty.FieldType type; private int flags; private Type internalType; private string name; /// /// Constructor for internal use by the runtime. /// /// Object that conains the field. /// Name of the field. /// Flags that control whether the field is inspectable or serializable. /// Internal C# type of the field. private SerializableField(SerializableObject parent, string name, int flags, Type internalType) { this.parent = parent; this.name = name; this.flags = flags; this.type = SerializableProperty.DetermineFieldType(internalType); this.internalType = internalType; } /// /// Returns the type of data contained in the field. /// public SerializableProperty.FieldType Type { get { return type; } } /// /// Returns the actual type of the object contained in the field. /// public Type InternalType { get { return internalType; } } /// /// Returns the name of the field. /// public string Name { get { return name; } } /// /// Returns true if the field accepts a defined range. /// public bool IsRanged { get { return (flags & (byte)SerializableFieldAttributes.Ranged) != 0; } } /// /// Returns the upper bound of the range. /// public float RangeMaximum { get { return IsRanged? Internal_GetRangeMaximum(mCachedPtr) : 0; } } /// /// Returns the lower bound of the range. /// public float RangeMinimum { get { return IsRanged? Internal_GetRangeMinimum(mCachedPtr) : 0; } } /// /// Whether the field is rendered as a slider. /// public bool IsSlider { get { return (IsRanged && Internal_RenderAsSlider(mCachedPtr)); } } /// /// Whether the field has an associated step value. /// public bool IsStepped { get { return (flags & (byte)SerializableFieldAttributes.Stepped) != 0; } } /// /// Returns the step of the range /// public float Step { get { return IsStepped? Internal_GetStep(mCachedPtr) : 0; } } /// /// Returns true if the field will be visible in the default inspector. /// public bool Inspectable { get { return (flags & (byte)SerializableFieldAttributes.Inspectable) != 0; } } /// /// Returns true if the field will be automatically serialized. /// public bool Serializable { get { return (flags & (byte)SerializableFieldAttributes.Serializable) != 0; } } /// /// Returns a serializable property for the field. /// /// Serializable property that allows you to manipulate contents of the field. public SerializableProperty GetProperty() { SerializableProperty.Getter getter = () => { object parentObject = parent.GetReferencedObject(); if (parentObject != null) return Internal_GetValue(mCachedPtr, parentObject); else return null; }; SerializableProperty.Setter setter = (object value) => { object parentObject = parent.GetReferencedObject(); if (parentObject != null) { Internal_SetValue(mCachedPtr, parentObject, value); // If value type we cannot just modify the parent object because it's just a copy if (parentObject.GetType().IsValueType && parent.parentProperty != null) parent.parentProperty.SetValue(parentObject); } }; SerializableProperty newProperty = Internal_CreateProperty(mCachedPtr); newProperty.Construct(type, internalType, getter, setter); return newProperty; } [MethodImpl(MethodImplOptions.InternalCall)] private static extern SerializableProperty Internal_CreateProperty(IntPtr nativeInstance); [MethodImpl(MethodImplOptions.InternalCall)] private static extern object Internal_GetValue(IntPtr nativeInstance, object instance); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void Internal_SetValue(IntPtr nativeInstance, object instance, object value); [MethodImpl(MethodImplOptions.InternalCall)] private static extern float Internal_GetRangeMaximum(IntPtr field); [MethodImpl(MethodImplOptions.InternalCall)] private static extern float Internal_GetRangeMinimum(IntPtr field); [MethodImpl(MethodImplOptions.InternalCall)] private static extern bool Internal_RenderAsSlider(IntPtr field); [MethodImpl(MethodImplOptions.InternalCall)] private static extern float Internal_GetStep(IntPtr field); } /** @} */ }