RTTI.cpp 3.4 KB

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