BsRTTIManagedDataBlockField.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. #include "BsRTTIField.h"
  4. #include "BsManagedDataBlock.h"
  5. namespace BansheeEngine
  6. {
  7. /** @cond INTERNAL */
  8. /** @addtogroup RTTI
  9. * @{
  10. */
  11. /**
  12. * Base class containing common functionality for a managed data block class field.
  13. *
  14. * @note
  15. * Managed data blocks are just blocks of memory that may, or may not be released automatically when they are no longer
  16. * referenced. They are useful when wanting to return some temporary data only for serialization purposes.
  17. */
  18. struct RTTIManagedDataBlockFieldBase : public RTTIField
  19. {
  20. Any mCustomAllocator;
  21. /** Retrieves a managed data block from the specified instance. */
  22. virtual ManagedDataBlock getValue(void* object) = 0;
  23. /** Sets a managed data block on the specified instance. */
  24. virtual void setValue(void* object, ManagedDataBlock value) = 0;
  25. /**
  26. * Allocate memory for the managed data block. Used primarily to allocate memory before sending it to
  27. * setValue() method.
  28. */
  29. virtual UINT8* allocate(void* object, UINT32 bytes) = 0;
  30. };
  31. /** Class containing a managed data block field containing a specific type. */
  32. template <class DataType, class ObjectType>
  33. struct RTTIManagedDataBlockField : public RTTIManagedDataBlockFieldBase
  34. {
  35. /**
  36. * Initializes a field that returns a block of bytes. Can be used for serializing pretty much anything.
  37. *
  38. * @param[in] name Name of the field.
  39. * @param[in] uniqueId Unique identifier for this field. Although name is also a unique identifier we want a
  40. * small data type that can be used for efficiently serializing data to disk and similar.
  41. * It is primarily used for compatibility between different versions of serialized data.
  42. * @param[in] getter The getter method for the field. Must be a specific signature: SerializableDataBlock(ObjectType*)
  43. * @param[in] setter The setter method for the field. Must be a specific signature: void(ObjectType*, SerializableDataBlock)
  44. * @param[in] flags Various flags you can use to specialize how systems handle this field. See RTTIFieldFlag.
  45. * @param[in] customAllocator (optional) Custom allocator that will be used when de-serializing DataBlock memory.
  46. */
  47. void initSingle(const String& name, UINT16 uniqueId, Any getter, Any setter, UINT64 flags, Any customAllocator = Any())
  48. {
  49. initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_DataBlock, flags);
  50. mCustomAllocator = customAllocator;
  51. }
  52. /** @copydoc RTTIField::getTypeSize */
  53. virtual UINT32 getTypeSize() override
  54. {
  55. return 0; // Data block types don't store size the conventional way
  56. }
  57. /** @copydoc RTTIField::hasDynamicSize */
  58. virtual bool hasDynamicSize() override
  59. {
  60. return true;
  61. }
  62. /** @copydoc RTTIField::getArraySize */
  63. virtual UINT32 getArraySize(void* object) override
  64. {
  65. BS_EXCEPT(InternalErrorException,
  66. "Data block types don't support arrays.");
  67. }
  68. /** @copydoc RTTIField::setArraySize */
  69. virtual void setArraySize(void* object, UINT32 size) override
  70. {
  71. BS_EXCEPT(InternalErrorException,
  72. "Data block types don't support arrays.");
  73. }
  74. /** @copydoc RTTIManagedDataBlockFieldBase::getValue */
  75. virtual ManagedDataBlock getValue(void* object) override
  76. {
  77. ObjectType* castObj = static_cast<ObjectType*>(object);
  78. std::function<ManagedDataBlock(ObjectType*)> f = any_cast<std::function<ManagedDataBlock(ObjectType*)>>(valueGetter);
  79. return f(castObj);
  80. }
  81. /** @copydoc RTTIManagedDataBlockFieldBase::setValue */
  82. virtual void setValue(void* object, ManagedDataBlock value) override
  83. {
  84. ObjectType* castObj = static_cast<ObjectType*>(object);
  85. std::function<void(ObjectType*, ManagedDataBlock)> f = any_cast<std::function<void(ObjectType*, ManagedDataBlock)>>(valueSetter);
  86. f(castObj, value);
  87. }
  88. /** @copydoc RTTIManagedDataBlockFieldBase::allocate */
  89. virtual UINT8* allocate(void* object, UINT32 bytes) override
  90. {
  91. if(mCustomAllocator.empty())
  92. return (UINT8*)bs_alloc(bytes);
  93. else
  94. {
  95. ObjectType* castObj = static_cast<ObjectType*>(object);
  96. std::function<UINT8*(ObjectType*, UINT32)> f = any_cast<std::function<UINT8*(ObjectType*, UINT32)>>(mCustomAllocator);
  97. return f(castObj, bytes);
  98. }
  99. }
  100. };
  101. /** @} */
  102. /** @endcond */
  103. }