CmRTTIReflectablePtrField.h 6.0 KB

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