SerializableField.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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 that are used to define properties of a single field in a managed object.
  12. /// </summary>
  13. internal enum SerializableFieldAttributes // Note: Must match C++ enum ScriptFieldFlags
  14. {
  15. Serializable = 0x01,
  16. Inspectable = 0x02,
  17. Ranged = 0x04,
  18. Stepped = 0x08,
  19. Animable = 0x10
  20. }
  21. /// <summary>
  22. /// Allows you to access meta-data about field in an object. Similar to Reflection but simpler and faster.
  23. /// </summary>
  24. public class SerializableField : ScriptObject
  25. {
  26. private SerializableObject parent;
  27. private SerializableProperty.FieldType type;
  28. private int flags;
  29. private Type internalType;
  30. private string name;
  31. /// <summary>
  32. /// Constructor for internal use by the runtime.
  33. /// </summary>
  34. /// <param name="parent">Object that conains the field.</param>
  35. /// <param name="name">Name of the field.</param>
  36. /// <param name="flags">Flags that control whether the field is inspectable or serializable.</param>
  37. /// <param name="internalType">Internal C# type of the field.</param>
  38. private SerializableField(SerializableObject parent, string name, int flags, Type internalType)
  39. {
  40. this.parent = parent;
  41. this.name = name;
  42. this.flags = flags;
  43. this.type = SerializableProperty.DetermineFieldType(internalType);
  44. this.internalType = internalType;
  45. }
  46. /// <summary>
  47. /// Returns the type of data contained in the field.
  48. /// </summary>
  49. public SerializableProperty.FieldType Type
  50. {
  51. get { return type; }
  52. }
  53. /// <summary>
  54. /// Returns the actual type of the object contained in the field.
  55. /// </summary>
  56. public Type InternalType
  57. {
  58. get { return internalType; }
  59. }
  60. /// <summary>
  61. /// Returns the name of the field.
  62. /// </summary>
  63. public string Name
  64. {
  65. get { return name; }
  66. }
  67. /// <summary>
  68. /// Returns true if the field will be visible in the default inspector.
  69. /// </summary>
  70. public bool Inspectable
  71. {
  72. get { return (flags & (byte)SerializableFieldAttributes.Inspectable) != 0; }
  73. }
  74. /// <summary>
  75. /// Returns true if the field will be automatically serialized.
  76. /// </summary>
  77. public bool Serializable
  78. {
  79. get { return (flags & (byte)SerializableFieldAttributes.Serializable) != 0; }
  80. }
  81. /// <summary>
  82. /// Returns true if the field can be animated.
  83. /// </summary>
  84. public bool Animable
  85. {
  86. get { return (flags & (byte)SerializableFieldAttributes.Animable) != 0; }
  87. }
  88. /// <summary>
  89. /// Returns the requested style of the field, that may be used for controlling how the field is displayed and how
  90. /// is its input filtered.
  91. /// </summary>
  92. public SerializableFieldStyle Style
  93. {
  94. get
  95. {
  96. SerializableFieldStyle style;
  97. Internal_GetStyle(mCachedPtr, out style);
  98. return style;
  99. }
  100. }
  101. /// <summary>
  102. /// Returns a serializable property for the field.
  103. /// </summary>
  104. /// <returns>Serializable property that allows you to manipulate contents of the field.</returns>
  105. public SerializableProperty GetProperty()
  106. {
  107. SerializableProperty.Getter getter = () =>
  108. {
  109. object parentObject = parent.GetReferencedObject();
  110. if (parentObject != null)
  111. return Internal_GetValue(mCachedPtr, parentObject);
  112. else
  113. return null;
  114. };
  115. SerializableProperty.Setter setter = (object value) =>
  116. {
  117. object parentObject = parent.GetReferencedObject();
  118. if (parentObject != null)
  119. {
  120. Internal_SetValue(mCachedPtr, parentObject, value);
  121. // If value type we cannot just modify the parent object because it's just a copy
  122. if (parentObject.GetType().IsValueType && parent.parentProperty != null)
  123. parent.parentProperty.SetValue(parentObject);
  124. }
  125. };
  126. SerializableProperty newProperty = Internal_CreateProperty(mCachedPtr);
  127. newProperty.Construct(type, internalType, getter, setter);
  128. return newProperty;
  129. }
  130. [MethodImpl(MethodImplOptions.InternalCall)]
  131. private static extern SerializableProperty Internal_CreateProperty(IntPtr nativeInstance);
  132. [MethodImpl(MethodImplOptions.InternalCall)]
  133. private static extern object Internal_GetValue(IntPtr nativeInstance, object instance);
  134. [MethodImpl(MethodImplOptions.InternalCall)]
  135. private static extern void Internal_SetValue(IntPtr nativeInstance, object instance, object value);
  136. [MethodImpl(MethodImplOptions.InternalCall)]
  137. private static extern void Internal_GetStyle(IntPtr nativeInstance, out SerializableFieldStyle style);
  138. }
  139. /// <summary>
  140. /// Contains information about a style of a serializable field.
  141. /// </summary>
  142. public struct SerializableFieldStyle // Note: Must match C++ struct SerializableMemberStyle
  143. {
  144. /// <summary>
  145. /// True if the range of the field is limited, false if unlimited.
  146. /// </summary>
  147. public bool HasRange;
  148. /// <summary>
  149. /// Returns the lower bound of the range. Only relevant if <see cref="HasRange"/> is true.
  150. /// </summary>
  151. public float RangeMin;
  152. /// <summary>
  153. /// Returns the upper bound of the range. Only relevant if <see cref="HasRange"/> is true.
  154. /// </summary>
  155. public float RangeMax;
  156. /// <summary>
  157. /// True if the field value can only be incremented in specific increments.
  158. /// </summary>
  159. public bool HasStep;
  160. /// <summary>
  161. /// Minimum increment the field value can be increment/decremented by. Only relevant if <see cref="HasStep"/> is true.
  162. /// </summary>
  163. public float StepIncrement;
  164. /// <summary>
  165. /// If true, number fields will be displayed as sliders instead of regular input boxes.
  166. /// </summary>
  167. public bool DisplayAsSlider;
  168. }
  169. /** @} */
  170. }