SerializableField.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Runtime.CompilerServices;
  5. namespace BansheeEngine
  6. {
  7. /** @addtogroup Serialization
  8. * @{
  9. */
  10. /// <summary>
  11. /// Flags as defined in native code in BsManagedSerializableObjectInfo.h
  12. /// </summary>
  13. enum SerializableFieldAttributes : byte
  14. {
  15. Serializable = 0x01,
  16. Inspectable = 0x02,
  17. Ranged = 0x04,
  18. Stepped = 0x08
  19. }
  20. /// <summary>
  21. /// Allows you to access meta-data about field in an object. Similar to Reflection but simpler and faster.
  22. /// </summary>
  23. public class SerializableField : ScriptObject
  24. {
  25. private SerializableObject parent;
  26. private SerializableProperty.FieldType type;
  27. private int flags;
  28. private Type internalType;
  29. private string name;
  30. /// <summary>
  31. /// Constructor for internal use by the runtime.
  32. /// </summary>
  33. /// <param name="parent">Object that conains the field.</param>
  34. /// <param name="name">Name of the field.</param>
  35. /// <param name="flags">Flags that control whether the field is inspectable or serializable.</param>
  36. /// <param name="internalType">Internal C# type of the field.</param>
  37. private SerializableField(SerializableObject parent, string name, int flags, Type internalType)
  38. {
  39. this.parent = parent;
  40. this.name = name;
  41. this.flags = flags;
  42. this.type = SerializableProperty.DetermineFieldType(internalType);
  43. this.internalType = internalType;
  44. }
  45. /// <summary>
  46. /// Returns the type of data contained in the field.
  47. /// </summary>
  48. public SerializableProperty.FieldType Type
  49. {
  50. get { return type; }
  51. }
  52. /// <summary>
  53. /// Returns the actual type of the object contained in the field.
  54. /// </summary>
  55. public Type InternalType
  56. {
  57. get { return internalType; }
  58. }
  59. /// <summary>
  60. /// Returns the name of the field.
  61. /// </summary>
  62. public string Name
  63. {
  64. get { return name; }
  65. }
  66. /// <summary>
  67. /// Returns true if the field accepts a defined range.
  68. /// </summary>
  69. public bool IsRanged
  70. {
  71. get { return (flags & (byte)SerializableFieldAttributes.Ranged) != 0; }
  72. }
  73. /// <summary>
  74. /// Returns the upper bound of the range.
  75. /// </summary>
  76. public float RangeMaximum
  77. {
  78. get { return IsRanged? Internal_GetRangeMaximum(mCachedPtr) : 0; }
  79. }
  80. /// <summary>
  81. /// Returns the lower bound of the range.
  82. /// </summary>
  83. public float RangeMinimum
  84. {
  85. get { return IsRanged? Internal_GetRangeMinimum(mCachedPtr) : 0; }
  86. }
  87. /// <summary>
  88. /// Whether the field is rendered as a slider.
  89. /// </summary>
  90. public bool IsSlider
  91. {
  92. get { return (IsRanged && Internal_RenderAsSlider(mCachedPtr)); }
  93. }
  94. /// <summary>
  95. /// Whether the field has an associated step value.
  96. /// </summary>
  97. public bool IsStepped
  98. {
  99. get { return (flags & (byte)SerializableFieldAttributes.Stepped) != 0; }
  100. }
  101. /// <summary>
  102. /// Returns the step of the range
  103. /// </summary>
  104. public float Step
  105. {
  106. get { return IsStepped? Internal_GetStep(mCachedPtr) : 0; }
  107. }
  108. /// <summary>
  109. /// Returns true if the field will be visible in the default inspector.
  110. /// </summary>
  111. public bool Inspectable
  112. {
  113. get { return (flags & (byte)SerializableFieldAttributes.Inspectable) != 0; }
  114. }
  115. /// <summary>
  116. /// Returns true if the field will be automatically serialized.
  117. /// </summary>
  118. public bool Serializable
  119. {
  120. get { return (flags & (byte)SerializableFieldAttributes.Serializable) != 0; }
  121. }
  122. /// <summary>
  123. /// Returns a serializable property for the field.
  124. /// </summary>
  125. /// <returns>Serializable property that allows you to manipulate contents of the field.</returns>
  126. public SerializableProperty GetProperty()
  127. {
  128. SerializableProperty.Getter getter = () =>
  129. {
  130. object parentObject = parent.GetReferencedObject();
  131. if (parentObject != null)
  132. return Internal_GetValue(mCachedPtr, parentObject);
  133. else
  134. return null;
  135. };
  136. SerializableProperty.Setter setter = (object value) =>
  137. {
  138. object parentObject = parent.GetReferencedObject();
  139. if (parentObject != null)
  140. {
  141. Internal_SetValue(mCachedPtr, parentObject, value);
  142. // If value type we cannot just modify the parent object because it's just a copy
  143. if (parentObject.GetType().IsValueType && parent.parentProperty != null)
  144. parent.parentProperty.SetValue(parentObject);
  145. }
  146. };
  147. SerializableProperty newProperty = Internal_CreateProperty(mCachedPtr);
  148. newProperty.Construct(type, internalType, getter, setter);
  149. return newProperty;
  150. }
  151. [MethodImpl(MethodImplOptions.InternalCall)]
  152. private static extern SerializableProperty Internal_CreateProperty(IntPtr nativeInstance);
  153. [MethodImpl(MethodImplOptions.InternalCall)]
  154. private static extern object Internal_GetValue(IntPtr nativeInstance, object instance);
  155. [MethodImpl(MethodImplOptions.InternalCall)]
  156. private static extern void Internal_SetValue(IntPtr nativeInstance, object instance, object value);
  157. [MethodImpl(MethodImplOptions.InternalCall)]
  158. private static extern float Internal_GetRangeMaximum(IntPtr field);
  159. [MethodImpl(MethodImplOptions.InternalCall)]
  160. private static extern float Internal_GetRangeMinimum(IntPtr field);
  161. [MethodImpl(MethodImplOptions.InternalCall)]
  162. private static extern bool Internal_RenderAsSlider(IntPtr field);
  163. [MethodImpl(MethodImplOptions.InternalCall)]
  164. private static extern float Internal_GetStep(IntPtr field);
  165. }
  166. /** @} */
  167. }