RTTI.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt/Jolt.h>
  4. #include <Jolt/Core/RTTI.h>
  5. #include <Jolt/Core/StringTools.h>
  6. JPH_NAMESPACE_BEGIN
  7. //////////////////////////////////////////////////////////////////////////////////////////
  8. // RTTI
  9. //////////////////////////////////////////////////////////////////////////////////////////
  10. RTTI::RTTI(const char *inName, int inSize, pCreateObjectFunction inCreateObject, pDestructObjectFunction inDestructObject) :
  11. mName(inName),
  12. mSize(inSize),
  13. mCreate(inCreateObject),
  14. mDestruct(inDestructObject)
  15. {
  16. JPH_ASSERT(inDestructObject != nullptr, "Object cannot be destructed");
  17. }
  18. RTTI::RTTI(const char *inName, int inSize, pCreateObjectFunction inCreateObject, pDestructObjectFunction inDestructObject, pCreateRTTIFunction inCreateRTTI) :
  19. mName(inName),
  20. mSize(inSize),
  21. mCreate(inCreateObject),
  22. mDestruct(inDestructObject)
  23. {
  24. JPH_ASSERT(inDestructObject != nullptr, "Object cannot be destructed");
  25. inCreateRTTI(*this);
  26. }
  27. int RTTI::GetBaseClassCount() const
  28. {
  29. return (int)mBaseClasses.size();
  30. }
  31. const RTTI *RTTI::GetBaseClass(int inIdx) const
  32. {
  33. return mBaseClasses[inIdx].mRTTI;
  34. }
  35. uint32 RTTI::GetHash() const
  36. {
  37. // Perform diffusion step to get from 64 to 32 bits (see https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function)
  38. uint64 hash = HashString(mName);
  39. return (uint32)(hash ^ (hash >> 32));
  40. }
  41. void *RTTI::CreateObject() const
  42. {
  43. return IsAbstract()? nullptr : mCreate();
  44. }
  45. void RTTI::DestructObject(void *inObject) const
  46. {
  47. mDestruct(inObject);
  48. }
  49. void RTTI::AddBaseClass(const RTTI *inRTTI, int inOffset)
  50. {
  51. JPH_ASSERT(inOffset >= 0 && inOffset < mSize, "Base class not contained in derived class");
  52. // Add base class
  53. BaseClass base;
  54. base.mRTTI = inRTTI;
  55. base.mOffset = inOffset;
  56. mBaseClasses.push_back(base);
  57. // Add attributes of base class
  58. for (const SerializableAttribute &a : inRTTI->mAttributes)
  59. mAttributes.push_back(SerializableAttribute(a, inOffset));
  60. }
  61. bool RTTI::operator == (const RTTI &inRHS) const
  62. {
  63. // Compare addresses
  64. if (this == &inRHS)
  65. return true;
  66. // Check that the names differ (if that is the case we probably have two instances
  67. // of the same attribute info across the program, probably the second is in a DLL)
  68. JPH_ASSERT(strcmp(mName, inRHS.mName) != 0);
  69. return false;
  70. }
  71. bool RTTI::IsKindOf(const RTTI *inRTTI) const
  72. {
  73. // Check if this is the same type
  74. if (this == inRTTI)
  75. return true;
  76. // Check all base classes
  77. for (const BaseClass &b : mBaseClasses)
  78. if (b.mRTTI->IsKindOf(inRTTI))
  79. return true;
  80. return false;
  81. }
  82. const void *RTTI::CastTo(const void *inObject, const RTTI *inRTTI) const
  83. {
  84. JPH_ASSERT(inObject != nullptr);
  85. // Check if this is the same type
  86. if (this == inRTTI)
  87. return inObject;
  88. // Check all base classes
  89. for (const BaseClass &b : mBaseClasses)
  90. {
  91. // Cast the pointer to the base class
  92. const void *casted = (const void *)(((const uint8 *)inObject) + b.mOffset);
  93. // Test base class
  94. const void *rv = b.mRTTI->CastTo(casted, inRTTI);
  95. if (rv != nullptr)
  96. return rv;
  97. }
  98. // Not possible to cast
  99. return nullptr;
  100. }
  101. void RTTI::AddAttribute(const SerializableAttribute &inAttribute)
  102. {
  103. mAttributes.push_back(inAttribute);
  104. }
  105. int RTTI::GetAttributeCount() const
  106. {
  107. return (int)mAttributes.size();
  108. }
  109. const SerializableAttribute &RTTI::GetAttribute(int inIdx) const
  110. {
  111. return mAttributes[inIdx];
  112. }
  113. JPH_NAMESPACE_END