2
0

BsRTTIManagedDataBlockField.h 4.5 KB

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