CmRTTIReflectableField.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #pragma once
  2. #include "CmPrerequisitesUtil.h"
  3. #include "CmRTTIField.h"
  4. #include "CmIReflectable.h"
  5. namespace CamelotFramework
  6. {
  7. struct RTTIReflectableFieldBase : public RTTIField
  8. {
  9. virtual IReflectable& getValue(void* object) = 0;
  10. virtual IReflectable& getArrayValue(void* object, UINT32 index) = 0;
  11. virtual void setValue(void* object, IReflectable& value) = 0;
  12. virtual void setArrayValue(void* object, UINT32 index, IReflectable& value) = 0;
  13. virtual std::shared_ptr<IReflectable> newObject() = 0;
  14. virtual bool hasDynamicSize() { return true; }
  15. };
  16. template <class DataType, class ObjectType>
  17. struct RTTIReflectableField : public RTTIReflectableFieldBase
  18. {
  19. /**
  20. * @brief Initializes a field with a data type implementing IReflectable interface.
  21. *
  22. * @param name Name of the field.
  23. * @param uniqueId Unique identifier for this field. Although name is also a unique
  24. * identifier we want a small data type that can be used for efficiently
  25. * serializing data to disk and similar. It is primarily used for compatibility
  26. * between different versions of serialized data.
  27. * @param getter The getter method for the field. Cannot be null. Must be a specific signature: DataType&(ObjectType*)
  28. * @param setter The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, DataType)
  29. * @param flags Various flags you can use to specialize how systems handle this field
  30. */
  31. void initSingle(const String& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
  32. {
  33. initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_Reflectable, flags);
  34. }
  35. /**
  36. * @brief Initializes a VECTOR field with data type implementing by IReflectable interface.
  37. *
  38. * @param name Name of the field.
  39. * @param uniqueId Unique identifier for this field. Although name is also a unique
  40. * identifier we want a small data type that can be used for efficiently
  41. * serializing data to disk and similar. It is primarily used for compatibility
  42. * between different versions of serialized data.
  43. * @param getter The getter method for the field. Cannot be null. Must be a specific signature: DataType&(ObjectType*, UINT32)
  44. * @param getSize Getter method that returns the size of an array. Cannot be null. Must be a specific signature: UINT32(ObjectType*)
  45. * @param setter The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, UINT32, DataType)
  46. * @param setSize Setter method that allows you to resize an array. Can be null. Can be null. Must be a specific signature: void(ObjectType*, UINT32)
  47. * @param flags Various flags you can use to specialize how systems handle this field
  48. */
  49. void initArray(const String& name, UINT16 uniqueId, boost::any getter,
  50. boost::any getSize, boost::any setter, boost::any setSize, UINT64 flags)
  51. {
  52. initAll(getter, setter, getSize, setSize, name, uniqueId, true, SerializableFT_Reflectable, flags);
  53. }
  54. virtual UINT32 getTypeSize()
  55. {
  56. return 0; // Complex types don't store size the conventional way
  57. }
  58. virtual IReflectable& getValue(void* object)
  59. {
  60. checkIsArray(false);
  61. ObjectType* castObjType = static_cast<ObjectType*>(object);
  62. boost::function<DataType&(ObjectType*)> f = boost::any_cast<boost::function<DataType&(ObjectType*)>>(valueGetter);
  63. IReflectable& castDataType = f(castObjType);
  64. return castDataType;
  65. }
  66. virtual IReflectable& getArrayValue(void* object, UINT32 index)
  67. {
  68. checkIsArray(true);
  69. ObjectType* castObjType = static_cast<ObjectType*>(object);
  70. boost::function<DataType&(ObjectType*, UINT32)> f = boost::any_cast<boost::function<DataType&(ObjectType*, UINT32)>>(valueGetter);
  71. IReflectable& castDataType = f(castObjType, index);
  72. return castDataType;
  73. }
  74. virtual void setValue(void* object, IReflectable& value)
  75. {
  76. checkIsArray(false);
  77. if(valueSetter.empty())
  78. {
  79. CM_EXCEPT(InternalErrorException,
  80. "Specified field (" + mName + ") has no setter.");
  81. }
  82. ObjectType* castObjType = static_cast<ObjectType*>(object);
  83. DataType& castDataObj = static_cast<DataType&>(value);
  84. boost::function<void(ObjectType*, DataType&)> f = boost::any_cast<boost::function<void(ObjectType*, DataType&)>>(valueSetter);
  85. f(castObjType, castDataObj);
  86. }
  87. virtual void setArrayValue(void* object, UINT32 index, IReflectable& value)
  88. {
  89. checkIsArray(true);
  90. if(valueSetter.empty())
  91. {
  92. CM_EXCEPT(InternalErrorException,
  93. "Specified field (" + mName + ") has no setter.");
  94. }
  95. ObjectType* castObjType = static_cast<ObjectType*>(object);
  96. DataType& castDataObj = static_cast<DataType&>(value);
  97. boost::function<void(ObjectType*, UINT32, DataType&)> f = boost::any_cast<boost::function<void(ObjectType*, UINT32, DataType&)>>(valueSetter);
  98. f(castObjType, index, castDataObj);
  99. }
  100. virtual UINT32 getArraySize(void* object)
  101. {
  102. checkIsArray(true);
  103. boost::function<UINT32(ObjectType*)> f = boost::any_cast<boost::function<UINT32(ObjectType*)>>(arraySizeGetter);
  104. ObjectType* castObject = static_cast<ObjectType*>(object);
  105. return f(castObject);
  106. }
  107. virtual void setArraySize(void* object, UINT32 size)
  108. {
  109. checkIsArray(true);
  110. if(arraySizeSetter.empty())
  111. {
  112. CM_EXCEPT(InternalErrorException,
  113. "Specified field (" + mName + ") has no array size setter.");
  114. }
  115. boost::function<void(ObjectType*, UINT32)> f = boost::any_cast<boost::function<void(ObjectType*, UINT32)>>(arraySizeSetter);
  116. ObjectType* castObject = static_cast<ObjectType*>(object);
  117. f(castObject, size);
  118. }
  119. virtual std::shared_ptr<IReflectable> newObject()
  120. {
  121. return DataType::getRTTIStatic()->newRTTIObject();
  122. }
  123. };
  124. }