CmRTTIReflectablePtrField.h 6.5 KB

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