SceneComponent.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Scene/Common.h>
  7. #include <AnKi/Util/Functions.h>
  8. #include <AnKi/Util/BitMask.h>
  9. namespace anki {
  10. // Forward
  11. class SceneComponentUpdateInfo;
  12. /// @addtogroup scene
  13. /// @{
  14. constexpr U32 kMaxSceneComponentClasses = 64;
  15. static_assert(kMaxSceneComponentClasses < 128, "It can oly be 7 bits because of SceneComponent::m_classId");
  16. #define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) using SceneComponentCallback_##name = type;
  17. #include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
  18. class SceneComponentVtable
  19. {
  20. public:
  21. #define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) SceneComponentCallback_##name m_##name;
  22. #include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
  23. };
  24. /// Callbacks live in their own arrays for better caching.
  25. class SceneComponentCallbacks
  26. {
  27. public:
  28. #define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) SceneComponentCallback_##name m_##name[kMaxSceneComponentClasses];
  29. #include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
  30. };
  31. extern SceneComponentCallbacks g_sceneComponentCallbacks;
  32. /// Scene component class info.
  33. class SceneComponentRtti
  34. {
  35. public:
  36. const char* m_className;
  37. F32 m_updateWeight; ///< It give the order it will get updated compared to other components.
  38. U16 m_classSize;
  39. U8 m_classAlignment;
  40. U8 m_classId;
  41. SceneComponentRtti(const char* name, F32 updateWeight, U32 size, U32 alignment, SceneComponentVtable vtable);
  42. };
  43. /// Define a scene component.
  44. #define ANKI_SCENE_COMPONENT(className) \
  45. static SceneComponentRtti _m_rtti; \
  46. static void _construct(SceneComponent& self, SceneNode& node) \
  47. { \
  48. callConstructor(static_cast<className&>(self), &node); \
  49. } \
  50. static void _destruct(SceneComponent& self) \
  51. { \
  52. callDestructor(static_cast<className&>(self)); \
  53. } \
  54. static void _onDestroy(SceneComponent& self, SceneNode& node) \
  55. { \
  56. static_cast<className&>(self).onDestroy(node); \
  57. } \
  58. static Error _update(SceneComponent& self, SceneComponentUpdateInfo& info, Bool& updated) \
  59. { \
  60. return static_cast<className&>(self).update(info, updated); \
  61. } \
  62. static void _onOtherComponentRemovedOrAdded(SceneComponent& self, SceneComponent* other, Bool added) \
  63. { \
  64. static_cast<className&>(self).onOtherComponentRemovedOrAdded(other, added); \
  65. } \
  66. \
  67. public: \
  68. static U8 getStaticClassId() \
  69. { \
  70. return _m_rtti.m_classId; \
  71. } \
  72. \
  73. private:
  74. /// Define the statics of a scene component.
  75. #define ANKI_SCENE_COMPONENT_STATICS(className, updateWeight) \
  76. SceneComponentRtti className::_m_rtti(ANKI_STRINGIZE(className), updateWeight, sizeof(className), \
  77. alignof(className), \
  78. {className::_construct, className::_destruct, className::_onDestroy, \
  79. className::_update, className::_onOtherComponentRemovedOrAdded});
  80. /// Passed to SceneComponent::update.
  81. /// @memberof SceneComponent
  82. class SceneComponentUpdateInfo
  83. {
  84. public:
  85. SceneNode* m_node = nullptr;
  86. const Second m_previousTime;
  87. const Second m_currentTime;
  88. const Second m_dt;
  89. StackMemoryPool* m_framePool = nullptr;
  90. SceneComponentUpdateInfo(Second prevTime, Second crntTime)
  91. : m_previousTime(prevTime)
  92. , m_currentTime(crntTime)
  93. , m_dt(crntTime - prevTime)
  94. {
  95. }
  96. };
  97. /// Scene node component.
  98. /// @note Doesn't have C++ virtuals to keep it compact.
  99. class SceneComponent
  100. {
  101. public:
  102. /// Construct the scene component.
  103. SceneComponent(SceneNode* node, U8 classId);
  104. U8 getClassId() const
  105. {
  106. return m_classId;
  107. }
  108. Timestamp getTimestamp() const
  109. {
  110. return m_timestamp;
  111. }
  112. static const SceneComponentRtti& findClassRtti(CString className);
  113. static const SceneComponentRtti& getClassRtti(U8 classId);
  114. const SceneComponentRtti& getClassRtti() const
  115. {
  116. return getClassRtti(m_classId);
  117. }
  118. ANKI_INTERNAL void onDestroyReal(SceneNode& node)
  119. {
  120. g_sceneComponentCallbacks.m_onDestroy[m_classId](*this, node);
  121. }
  122. ANKI_INTERNAL Error updateReal(SceneComponentUpdateInfo& info, Bool& updated)
  123. {
  124. return g_sceneComponentCallbacks.m_update[m_classId](*this, info, updated);
  125. }
  126. ANKI_INTERNAL void onOtherComponentRemovedOrAddedReal(SceneComponent* other, Bool added)
  127. {
  128. ANKI_ASSERT(other);
  129. g_sceneComponentCallbacks.m_onOtherComponentRemovedOrAdded[m_classId](*this, other, added);
  130. }
  131. /// Don't call it directly.
  132. ANKI_INTERNAL void setTimestamp(Timestamp timestamp)
  133. {
  134. ANKI_ASSERT(timestamp > 0);
  135. ANKI_ASSERT(timestamp >= m_timestamp);
  136. m_timestamp = timestamp;
  137. }
  138. protected:
  139. ANKI_PURE static SceneGraphExternalSubsystems& getExternalSubsystems(const SceneNode& node);
  140. /// Pseudo-virtual
  141. void onDestroy([[maybe_unused]] SceneNode& node)
  142. {
  143. // Do nothing
  144. }
  145. /// Pseudo-virtual to update the component.
  146. /// @param[in,out] info Update info.
  147. /// @param[out] updated true if an update happened.
  148. Error update([[maybe_unused]] SceneComponentUpdateInfo& info, Bool& updated)
  149. {
  150. updated = false;
  151. return Error::kNone;
  152. }
  153. /// Pseudo-virtual. Called when a component is added or removed in the SceneNode.
  154. /// @param other The component that was inserted.
  155. /// @param added Was it inserted or removed?
  156. void onOtherComponentRemovedOrAdded([[maybe_unused]] SceneComponent* other, [[maybe_unused]] Bool added)
  157. {
  158. }
  159. private:
  160. Timestamp m_timestamp = 1; ///< Indicates when an update happened
  161. U8 m_classId; ///< Cache the type ID.
  162. };
  163. /// @}
  164. } // end namespace anki