BsRTTIReflectableField.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsPrerequisitesUtil.h"
  5. #include "BsRTTIField.h"
  6. #include "BsIReflectable.h"
  7. namespace BansheeEngine
  8. {
  9. /** @cond INTERNAL */
  10. /** @addtogroup RTTI
  11. * @{
  12. */
  13. /**
  14. * Base class containing common functionality for a reflectable class field.
  15. *
  16. * @note
  17. * Reflectable fields are fields containing complex types deriving from IReflectable. They are serialized recursively
  18. * and you may add/remove fields from them without breaking the serialized data.
  19. */
  20. struct RTTIReflectableFieldBase : public RTTIField
  21. {
  22. /**
  23. * Retrieves the IReflectable value from the provided instance.
  24. *
  25. * @note Field type must not be an array.
  26. */
  27. virtual IReflectable& getValue(void* object) = 0;
  28. /**
  29. * Retrieves the IReflectable value from an array on the provided instance and index.
  30. *
  31. * @note Field type must be an array.
  32. */
  33. virtual IReflectable& getArrayValue(void* object, UINT32 index) = 0;
  34. /**
  35. * Sets the IReflectable value in the provided instance.
  36. *
  37. * @note Field type must not be an array.
  38. */
  39. virtual void setValue(void* object, IReflectable& value) = 0;
  40. /**
  41. * Sets the IReflectable value in an array on the provided instance and index.
  42. *
  43. * @note Field type must be an array.
  44. */
  45. virtual void setArrayValue(void* object, UINT32 index, IReflectable& value) = 0;
  46. /** Creates a new object of the field type. */
  47. virtual std::shared_ptr<IReflectable> newObject() = 0;
  48. /** @copydoc RTTIField::hasDynamicSize */
  49. bool hasDynamicSize() override { return true; }
  50. /** Retrieves the RTTI object for the type the field contains. */
  51. virtual RTTITypeBase* getType() = 0;
  52. };
  53. /** Reflectable field containing a specific type with RTTI implemented. */
  54. template <class DataType, class ObjectType>
  55. struct RTTIReflectableField : public RTTIReflectableFieldBase
  56. {
  57. /**
  58. * Initializes a field containing a single data type implementing IReflectable interface.
  59. *
  60. * @param[in] name Name of the field.
  61. * @param[in] uniqueId Unique identifier for this field. Although name is also a unique identifier we want a
  62. * small data type that can be used for efficiently serializing data to disk and similar.
  63. * It is primarily used for compatibility between different versions of serialized data.
  64. * @param[in] getter The getter method for the field. Must be a specific signature: DataType&(ObjectType*)
  65. * @param[in] setter The setter method for the field. Must be a specific signature: void(ObjectType*, DataType)
  66. * @param[in] flags Various flags you can use to specialize how systems handle this field. See "RTTIFieldFlag".
  67. */
  68. void initSingle(const String& name, UINT16 uniqueId, Any getter, Any setter, UINT64 flags)
  69. {
  70. initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_Reflectable, flags);
  71. }
  72. /**
  73. * @brief Initializes a field containing an array of data types implementing IReflectable interface.
  74. *
  75. * @param[in] name Name of the field.
  76. * @param[in] uniqueId Unique identifier for this field. Although name is also a unique identifier we want a
  77. * small data type that can be used for efficiently serializing data to disk and similar.
  78. * It is primarily used for compatibility between different versions of serialized data.
  79. * @param[in] getter The getter method for the field. Must be a specific signature: DataType&(ObjectType*, UINT32)
  80. * @param[in] getSize Getter method that returns the size of an array. Must be a specific signature: UINT32(ObjectType*)
  81. * @param[in] setter The setter method for the field. Must be a specific signature: void(ObjectType*, UINT32, DataType)
  82. * @param[in] setSize Setter method that allows you to resize an array. Must be a specific signature: void(ObjectType*, UINT32)
  83. * @param[in] flags Various flags you can use to specialize how systems handle this field. See "RTTIFieldFlag".
  84. */
  85. void initArray(const String& name, UINT16 uniqueId, Any getter,
  86. Any getSize, Any setter, Any setSize, UINT64 flags)
  87. {
  88. initAll(getter, setter, getSize, setSize, name, uniqueId, true, SerializableFT_Reflectable, flags);
  89. }
  90. /** @copydoc RTTIField::getTypeSize */
  91. UINT32 getTypeSize() override
  92. {
  93. return 0; // Complex types don't store size the conventional way
  94. }
  95. /** @copydoc RTTIReflectableFieldBase::getValue */
  96. IReflectable& getValue(void* object) override
  97. {
  98. checkIsArray(false);
  99. ObjectType* castObjType = static_cast<ObjectType*>(object);
  100. std::function<DataType&(ObjectType*)> f = any_cast<std::function<DataType&(ObjectType*)>>(valueGetter);
  101. IReflectable& castDataType = f(castObjType);
  102. return castDataType;
  103. }
  104. /** @copydoc RTTIReflectableFieldBase::getArrayValue */
  105. IReflectable& getArrayValue(void* object, UINT32 index) override
  106. {
  107. checkIsArray(true);
  108. ObjectType* castObjType = static_cast<ObjectType*>(object);
  109. std::function<DataType&(ObjectType*, UINT32)> f = any_cast<std::function<DataType&(ObjectType*, UINT32)>>(valueGetter);
  110. IReflectable& castDataType = f(castObjType, index);
  111. return castDataType;
  112. }
  113. /** @copydoc RTTIReflectableFieldBase::setValue */
  114. void setValue(void* object, IReflectable& value) override
  115. {
  116. checkIsArray(false);
  117. if(valueSetter.empty())
  118. {
  119. BS_EXCEPT(InternalErrorException,
  120. "Specified field (" + mName + ") has no setter.");
  121. }
  122. ObjectType* castObjType = static_cast<ObjectType*>(object);
  123. DataType& castDataObj = static_cast<DataType&>(value);
  124. std::function<void(ObjectType*, DataType&)> f = any_cast<std::function<void(ObjectType*, DataType&)>>(valueSetter);
  125. f(castObjType, castDataObj);
  126. }
  127. /** @copydoc RTTIReflectableFieldBase::setArrayValue */
  128. void setArrayValue(void* object, UINT32 index, IReflectable& value) override
  129. {
  130. checkIsArray(true);
  131. if(valueSetter.empty())
  132. {
  133. BS_EXCEPT(InternalErrorException,
  134. "Specified field (" + mName + ") has no setter.");
  135. }
  136. ObjectType* castObjType = static_cast<ObjectType*>(object);
  137. DataType& castDataObj = static_cast<DataType&>(value);
  138. std::function<void(ObjectType*, UINT32, DataType&)> f = any_cast<std::function<void(ObjectType*, UINT32, DataType&)>>(valueSetter);
  139. f(castObjType, index, castDataObj);
  140. }
  141. /** @copydoc RTTIField::getArraySize */
  142. UINT32 getArraySize(void* object) override
  143. {
  144. checkIsArray(true);
  145. std::function<UINT32(ObjectType*)> f = any_cast<std::function<UINT32(ObjectType*)>>(arraySizeGetter);
  146. ObjectType* castObject = static_cast<ObjectType*>(object);
  147. return f(castObject);
  148. }
  149. /** @copydoc RTTIField::setArraySize */
  150. void setArraySize(void* object, UINT32 size) override
  151. {
  152. checkIsArray(true);
  153. if(arraySizeSetter.empty())
  154. {
  155. BS_EXCEPT(InternalErrorException,
  156. "Specified field (" + mName + ") has no array size setter.");
  157. }
  158. std::function<void(ObjectType*, UINT32)> f = any_cast<std::function<void(ObjectType*, UINT32)>>(arraySizeSetter);
  159. ObjectType* castObject = static_cast<ObjectType*>(object);
  160. f(castObject, size);
  161. }
  162. /** @copydoc RTTIReflectableFieldBase::newObject */
  163. std::shared_ptr<IReflectable> newObject() override
  164. {
  165. return DataType::getRTTIStatic()->newRTTIObject();
  166. }
  167. /** @copydoc RTTIReflectableFieldBase::getType */
  168. RTTITypeBase* getType() override
  169. {
  170. return DataType::getRTTIStatic();
  171. }
  172. };
  173. /** @} */
  174. /** @endcond */
  175. }