RTTI.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. #ifdef JPH_OBJECT_STREAM
  59. // Add attributes of base class
  60. for (const SerializableAttribute &a : inRTTI->mAttributes)
  61. mAttributes.push_back(SerializableAttribute(a, inOffset));
  62. #endif // JPH_OBJECT_STREAM
  63. }
  64. bool RTTI::operator == (const RTTI &inRHS) const
  65. {
  66. // Compare addresses
  67. if (this == &inRHS)
  68. return true;
  69. // Check that the names differ (if that is the case we probably have two instances
  70. // of the same attribute info across the program, probably the second is in a DLL)
  71. JPH_ASSERT(strcmp(mName, inRHS.mName) != 0);
  72. return false;
  73. }
  74. bool RTTI::IsKindOf(const RTTI *inRTTI) const
  75. {
  76. // Check if this is the same type
  77. if (this == inRTTI)
  78. return true;
  79. // Check all base classes
  80. for (const BaseClass &b : mBaseClasses)
  81. if (b.mRTTI->IsKindOf(inRTTI))
  82. return true;
  83. return false;
  84. }
  85. const void *RTTI::CastTo(const void *inObject, const RTTI *inRTTI) const
  86. {
  87. JPH_ASSERT(inObject != nullptr);
  88. // Check if this is the same type
  89. if (this == inRTTI)
  90. return inObject;
  91. // Check all base classes
  92. for (const BaseClass &b : mBaseClasses)
  93. {
  94. // Cast the pointer to the base class
  95. const void *casted = (const void *)(((const uint8 *)inObject) + b.mOffset);
  96. // Test base class
  97. const void *rv = b.mRTTI->CastTo(casted, inRTTI);
  98. if (rv != nullptr)
  99. return rv;
  100. }
  101. // Not possible to cast
  102. return nullptr;
  103. }
  104. #ifdef JPH_OBJECT_STREAM
  105. void RTTI::AddAttribute(const SerializableAttribute &inAttribute)
  106. {
  107. mAttributes.push_back(inAttribute);
  108. }
  109. int RTTI::GetAttributeCount() const
  110. {
  111. return (int)mAttributes.size();
  112. }
  113. const SerializableAttribute &RTTI::GetAttribute(int inIdx) const
  114. {
  115. return mAttributes[inIdx];
  116. }
  117. #endif // JPH_OBJECT_STREAM
  118. JPH_NAMESPACE_END