Browse Source

Small refactoring of SceneComponent virtuals

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
31cd375b7e

+ 12 - 11
AnKi/Scene/Components/SceneComponent.cpp

@@ -31,10 +31,11 @@ SceneComponentRtti::SceneComponentRtti(const char* name, U32 size, U32 alignment
 	m_classId = kMaxU8;
 
 	g_rttis[g_sceneComponentClassCount] = this;
-	g_sceneComponentCallbacks.m_constructors[g_sceneComponentClassCount] = vtable.m_constructor;
-	g_sceneComponentCallbacks.m_destructors[g_sceneComponentClassCount] = vtable.m_destructor;
-	g_sceneComponentCallbacks.m_onDestroys[g_sceneComponentClassCount] = vtable.m_onDestroy;
-	g_sceneComponentCallbacks.m_updates[g_sceneComponentClassCount] = vtable.m_update;
+
+#define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) \
+	g_sceneComponentCallbacks.m_##name[g_sceneComponentClassCount] = vtable.m_##name;
+#include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
+
 	++g_sceneComponentClassCount;
 
 	// Sort everything because the IDs should be consistend between platforms and compilation builds
@@ -51,9 +52,11 @@ SceneComponentRtti::SceneComponentRtti(const char* name, U32 size, U32 alignment
 		for(U32 i = 0; i < g_sceneComponentClassCount; ++i)
 		{
 			temps[i].m_rrti = g_rttis[i];
-			temps[i].m_vtable = {g_sceneComponentCallbacks.m_constructors[i],
-								 g_sceneComponentCallbacks.m_destructors[i], g_sceneComponentCallbacks.m_onDestroys[i],
-								 g_sceneComponentCallbacks.m_updates[i]};
+			temps[i].m_vtable = {
+#define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) g_sceneComponentCallbacks.m_##name[i]
+#define ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR ,
+#include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
+			};
 		}
 
 		std::sort(&temps[0], &temps[g_sceneComponentClassCount], [](const Temp& a, const Temp& b) {
@@ -70,10 +73,8 @@ SceneComponentRtti::SceneComponentRtti(const char* name, U32 size, U32 alignment
 		for(U32 i = 0; i < g_sceneComponentClassCount; ++i)
 		{
 			g_rttis[i] = temps[i].m_rrti;
-			g_sceneComponentCallbacks.m_constructors[i] = temps[i].m_vtable.m_constructor;
-			g_sceneComponentCallbacks.m_destructors[i] = temps[i].m_vtable.m_destructor;
-			g_sceneComponentCallbacks.m_onDestroys[i] = temps[i].m_vtable.m_onDestroy;
-			g_sceneComponentCallbacks.m_updates[i] = temps[i].m_vtable.m_update;
+#define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) g_sceneComponentCallbacks.m_##name[i] = temps[i].m_vtable.m_##name;
+#include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
 		}
 	}
 }

+ 22 - 17
AnKi/Scene/Components/SceneComponent.h

@@ -20,28 +20,22 @@ class SceneComponentUpdateInfo;
 constexpr U32 kMaxSceneComponentClasses = 64;
 static_assert(kMaxSceneComponentClasses < 128, "It can oly be 7 bits because of SceneComponent::m_classId");
 
-using SceneComponentConstructorCallback = void (*)(SceneComponent& self, SceneNode& owner);
-using SceneComponentDestructorCallback = void (*)(SceneComponent& self);
-using SceneComponentOnDestroyCallback = void (*)(SceneComponent& self, SceneNode& owner);
-using SceneComponentUpdateCallback = Error (*)(SceneComponent& self, SceneComponentUpdateInfo& info, Bool& updated);
+#define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) using SceneComponentCallback_##name = type;
+#include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
 
 class SceneComponentVtable
 {
 public:
-	SceneComponentConstructorCallback m_constructor;
-	SceneComponentDestructorCallback m_destructor;
-	SceneComponentOnDestroyCallback m_onDestroy;
-	SceneComponentUpdateCallback m_update;
+#define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) SceneComponentCallback_##name m_##name;
+#include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
 };
 
 /// Callbacks live in their own arrays for better caching.
 class SceneComponentCallbacks
 {
 public:
-	SceneComponentConstructorCallback m_constructors[kMaxSceneComponentClasses];
-	SceneComponentDestructorCallback m_destructors[kMaxSceneComponentClasses];
-	SceneComponentOnDestroyCallback m_onDestroys[kMaxSceneComponentClasses];
-	SceneComponentUpdateCallback m_updates[kMaxSceneComponentClasses];
+#define ANKI_SCENE_COMPONENT_VIRTUAL(name, type) SceneComponentCallback_##name m_##name[kMaxSceneComponentClasses];
+#include <AnKi/Scene/Components/SceneComponentVirtuals.defs.h>
 };
 
 extern SceneComponentCallbacks g_sceneComponentCallbacks;
@@ -77,6 +71,10 @@ public:
 	{ \
 		return static_cast<className&>(self).update(info, updated); \
 	} \
+	static void _onOtherComponentRemovedOrAdded(SceneComponent& self, SceneComponent* other, Bool added) \
+	{ \
+		static_cast<className&>(self).onOtherComponentRemovedOrAdded(other, added); \
+	} \
 \
 public: \
 	static U8 getStaticClassId() \
@@ -88,9 +86,9 @@ private:
 
 /// Define the statics of a scene component.
 #define ANKI_SCENE_COMPONENT_STATICS(className) \
-	SceneComponentRtti className::_m_rtti( \
-		ANKI_STRINGIZE(className), sizeof(className), alignof(className), \
-		{className::_construct, className::_destruct, className::_onDestroy, className::_update});
+	SceneComponentRtti className::_m_rtti(ANKI_STRINGIZE(className), sizeof(className), alignof(className), \
+										  {className::_construct, className::_destruct, className::_onDestroy, \
+										   className::_update, className::_onOtherComponentRemovedOrAdded});
 
 /// Passed to SceneComponent::update.
 /// @memberof SceneComponent
@@ -141,12 +139,12 @@ public:
 
 	ANKI_INTERNAL void onDestroyReal(SceneNode& node)
 	{
-		g_sceneComponentCallbacks.m_onDestroys[m_classId](*this, node);
+		g_sceneComponentCallbacks.m_onDestroy[m_classId](*this, node);
 	}
 
 	ANKI_INTERNAL Error updateReal(SceneComponentUpdateInfo& info, Bool& updated)
 	{
-		return g_sceneComponentCallbacks.m_updates[m_classId](*this, info, updated);
+		return g_sceneComponentCallbacks.m_update[m_classId](*this, info, updated);
 	}
 
 	/// Don't call it directly.
@@ -175,6 +173,13 @@ protected:
 		return Error::kNone;
 	}
 
+	/// Called when a component is added or removed in the SceneNode.
+	/// @param other The component that was inserted.
+	/// @param added Was it inserted or removed?
+	void onOtherComponentRemovedOrAdded([[maybe_unused]] SceneComponent* other, [[maybe_unused]] Bool added)
+	{
+	}
+
 private:
 	Timestamp m_timestamp = 1; ///< Indicates when an update happened
 	U8 m_classId : 7; ///< Cache the type ID.

+ 22 - 0
AnKi/Scene/Components/SceneComponentVirtuals.defs.h

@@ -0,0 +1,22 @@
+// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#if !defined(ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR)
+#	define ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR
+#endif
+
+ANKI_SCENE_COMPONENT_VIRTUAL(constructor, void (*)(SceneComponent& self, SceneNode& owner))
+ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR
+ANKI_SCENE_COMPONENT_VIRTUAL(destructor, void (*)(SceneComponent& self))
+ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR
+ANKI_SCENE_COMPONENT_VIRTUAL(onDestroy, void (*)(SceneComponent& self, SceneNode& owner))
+ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR
+ANKI_SCENE_COMPONENT_VIRTUAL(update, Error (*)(SceneComponent& self, SceneComponentUpdateInfo& info, Bool& updated))
+ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR
+ANKI_SCENE_COMPONENT_VIRTUAL(onOtherComponentRemovedOrAdded,
+							 void (*)(SceneComponent& self, SceneComponent* other, Bool added))
+
+#undef ANKI_SCENE_COMPONENT_VIRTUAL
+#undef ANKI_SCENE_COMPONENT_VIRTUAL_SEPERATOR

+ 1 - 1
AnKi/Scene/SceneNode.cpp

@@ -25,7 +25,7 @@ SceneNode::~SceneNode()
 	for(SceneComponent* comp : m_components)
 	{
 		comp->onDestroyReal(*this);
-		g_sceneComponentCallbacks.m_destructors[comp->getClassId()](*comp);
+		g_sceneComponentCallbacks.m_destructor[comp->getClassId()](*comp);
 
 		pool.free(comp);
 	}