Initial reflection for components using the entt reflection API

Currently the only system using reflection is the drop down box when clicking "Add Component" in the entity inspector. The other systems and architecture is still designed around concrete compile time typing
This commit is contained in:
WiggleWizard
2024-09-10 15:53:32 +01:00
parent 7e341b34cf
commit ffc79ccdf4
21 changed files with 156 additions and 28 deletions

View File

@@ -13,6 +13,8 @@
#include <Engine.h>
#include <src/Resource/Prefab.h>
#include <entt/entt.hpp>
using namespace Nuake;
EditorSelectionPanel::EditorSelectionPanel()
@@ -151,32 +153,19 @@ void EditorSelectionPanel::DrawEntity(Nuake::Entity entity)
if (ImGui::BeginPopup("ComponentPopup"))
{
MenuItemComponent("Wren Script", WrenScriptComponent);
MenuItemComponent("C# Script", NetScriptComponent);
MenuItemComponent("Camera", CameraComponent);
MenuItemComponent("Light", LightComponent);
ImGui::Separator();
MenuItemComponent("Model", ModelComponent);
MenuItemComponent("Skinned Model", SkinnedModelComponent);
MenuItemComponent("Bone", BoneComponent)
ImGui::Separator();
MenuItemComponent("Sprite", SpriteComponent)
MenuItemComponent("Particle Emitter", ParticleEmitterComponent)
ImGui::Separator();
MenuItemComponent("Character Controller", CharacterControllerComponent)
MenuItemComponent("Rigid body", RigidBodyComponent)
ImGui::Separator();
MenuItemComponent("Box collider", BoxColliderComponent)
MenuItemComponent("Capsule collider", CapsuleColliderComponent)
MenuItemComponent("Cylinder collider", CylinderColliderComponent)
MenuItemComponent("Sphere collider", SphereColliderComponent)
MenuItemComponent("Mesh collider", MeshColliderComponent)
ImGui::Separator();
MenuItemComponent("Quake map", QuakeMapComponent);
ImGui::Separator();
MenuItemComponent("Audio Emitter", AudioEmitterComponent);
ImGui::Separator();
MenuItemComponent("NavMesh Volume", NavMeshVolumeComponent);
for(entt::meta_type t : entt::resolve())
{
if (entt::meta_func func = t.func(HashedFnName::GetComponentName))
{
entt::meta_any ret = func.invoke(t);
std::string className = ret.cast<std::string>();
if (ImGui::MenuItem(className.c_str()))
{
entity.AddComponent(t);
}
}
}
ImGui::EndPopup();
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include <entt/entt.hpp>
#define NK_HASHED_FN_NAME_IMPL(name) inline static constexpr entt::hashed_string name = entt::hashed_string(#name);
namespace Nuake
{
struct HashedFnName
{
NK_HASHED_FN_NAME_IMPL(GetComponentName)
NK_HASHED_FN_NAME_IMPL(AddToEntity)
};
}
#define NUAKECOMPONENT(klass, componentName) \
public: \
static std::string ClassName() \
{ \
static std::string className = #klass; \
return className; \
} \
\
static std::string ComponentName() \
{ \
static std::string name = componentName; \
return name; \
} \
\
static void AddToEntity(entt::entity entity, entt::registry* enttRegistry) \
{ \
enttRegistry->emplace_or_replace<klass>(entity); \
} \
\
inline static auto ComponentFactory = entt::meta<klass>() \
.type(entt::hashed_string(#klass)) \
.func<&klass::ComponentName>(HashedFnName::GetComponentName) \
.func<&klass::AddToEntity>(HashedFnName::AddToEntity);

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Core/Core.h"
#include "src/Resource/Serializable.h"
@@ -6,6 +8,8 @@ namespace Nuake {
class AudioEmitterComponent
{
NUAKECOMPONENT(AudioEmitterComponent, "Audio Emitter")
public:
std::string FilePath;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Core/Core.h"
#include "src/Resource/Serializable.h"
@@ -7,6 +9,8 @@ namespace Nuake
{
class BoneComponent
{
NUAKECOMPONENT(BoneComponent, "Bone")
public:
BoneComponent() = default;
~BoneComponent() = default;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Physics/PhysicsShapes.h"
#include "src/Core/Core.h"
@@ -6,6 +8,8 @@ namespace Nuake {
class BoxColliderComponent
{
NUAKECOMPONENT(BoxColliderComponent, "Box Collider")
public:
Ref<Physics::PhysicShape> Box;
Vector3 Size = Vector3(0.5f, 0.5f, 0.5f);

View File

@@ -1,4 +1,7 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "TransformComponent.h"
#include "src/Core/Core.h"
#include "src/Resource/Serializable.h"
@@ -6,8 +9,11 @@
namespace Nuake
{
class CameraComponent
{
NUAKECOMPONENT(CameraComponent, "Camera")
public:
Ref<Camera> CameraInstance;
TransformComponent* transformComponent;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Physics/PhysicsShapes.h"
#include "src/Core/Core.h"
@@ -6,6 +8,8 @@ namespace Nuake
{
class CapsuleColliderComponent
{
NUAKECOMPONENT(CapsuleColliderComponent, "Capsule Collider")
public:
Ref<Physics::Capsule> Capsule;

View File

@@ -1,10 +1,14 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Physics/CharacterController.h"
namespace Nuake
{
class CharacterControllerComponent
{
NUAKECOMPONENT(CharacterControllerComponent, "Character Controller")
private:
Ref<Physics::CharacterController> m_CharacterController;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Physics/PhysicsShapes.h"
#include "src/Core/Core.h"
@@ -6,6 +8,8 @@ namespace Nuake
{
class CylinderColliderComponent
{
NUAKECOMPONENT(CylinderColliderComponent, "Cylinder Collider")
public:
Ref<Physics::Cylinder> Cylinder;

View File

@@ -1,4 +1,7 @@
#pragma once
#include "src/Core/Object/Object.h"
#include <glm/ext/vector_float3.hpp>
#include <glm/ext/vector_float2.hpp>
#include "TransformComponent.h"
@@ -19,6 +22,8 @@ namespace Nuake
const int CSM_AMOUNT = 4;
class LightComponent
{
NUAKECOMPONENT(LightComponent, "Light")
public:
LightType Type = Point;
Vector3 Direction;

View File

@@ -1,10 +1,14 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Physics/PhysicsShapes.h"
#include "src/Core/Core.h"
namespace Nuake {
class MeshColliderComponent
{
NUAKECOMPONENT(MeshColliderComponent, "Mesh Collider")
public:
uint32_t SubMesh = 0;
bool IsTrigger;

View File

@@ -1,5 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Core/String.h"
#include "src/Resource/Model.h"
#include "src/Resource/ResourceLoader.h"
@@ -13,6 +14,8 @@ namespace Nuake
{
struct ModelComponent
{
NUAKECOMPONENT(ModelComponent, "Model")
Ref<Model> ModelResource;
std::string ModelPath;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "../Entities/Entity.h"
#include "Engine.h"
#include <src/AI/NavMesh.h>
@@ -7,6 +9,8 @@ namespace Nuake
{
struct NavMeshVolumeComponent
{
NUAKECOMPONENT(NavMeshVolumeComponent, "Nav Mesh Volume")
Vector3 VolumeSize = { 1.0f, 1.0f, 1.0f };
bool OnlyIncludeMapGeometry = true;

View File

@@ -1,5 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Core/Core.h"
#include "src/Core/Maths.h"
#include "src/FileSystem/FileSystem.h"
@@ -8,6 +9,8 @@
#include "src/Resource/File.h"
#include <any>
#include "src/Core/Object/Object.h"
namespace Nuake {
enum class NetScriptExposedVarType
@@ -33,6 +36,8 @@ namespace Nuake {
class NetScriptComponent
{
NUAKECOMPONENT(NetScriptComponent, "Net Script")
public:
std::string ScriptPath;
std::string Class;
@@ -234,4 +239,4 @@ namespace Nuake {
return true;
}
};
}
}

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Core/Core.h"
#include "src/Core/Maths.h"
#include "src/Resource/Serializable.h"
@@ -10,6 +12,8 @@ namespace Nuake
{
class ParticleEmitterComponent
{
NUAKECOMPONENT(ParticleEmitterComponent, "Particle Emitter")
public:
ParticleEmitterComponent() = default;
~ParticleEmitterComponent() = default;

View File

@@ -2,6 +2,7 @@
#include <string>
#include <vector>
#include "src/Core/Object/Object.h"
#include "src/Rendering/Mesh/Mesh.h"
#include "src/Resource/Serializable.h"
#include "src/Scene/Systems/QuakeMapBuilder.h"
@@ -12,6 +13,8 @@ namespace Nuake {
class QuakeMapComponent
{
NUAKECOMPONENT(QuakeMapComponent, "Quake Map")
public:
std::vector<Ref<Mesh>> m_Meshes;
std::vector<Entity> m_Brushes;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "TransformComponent.h"
#include "BaseComponent.h"
#include "src/Core/Core.h"
@@ -11,6 +13,8 @@ namespace Nuake {
class RigidBodyComponent
{
NUAKECOMPONENT(RigidBodyComponent, "Rigid Body")
public:
float Mass;
bool LockX = false;

View File

@@ -1,6 +1,7 @@
#pragma once
#include <vector>
#include "src/Core/Object/Object.h"
#include "src/Resource/Serializable.h"
#include "src/Resource/SkinnedModel.h"
@@ -11,6 +12,8 @@ namespace Nuake
{
struct SkinnedModelComponent
{
NUAKECOMPONENT(SkinnedModelComponent, "Skinned Model")
Ref<SkinnedModel> ModelResource;
std::string ModelPath;

View File

@@ -1,10 +1,14 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Physics/PhysicsShapes.h"
#include "src/Core/Core.h"
namespace Nuake {
class SphereColliderComponent
{
NUAKECOMPONENT(SphereColliderComponent, "Sphere Component")
public:
Ref<Physics::PhysicShape> Sphere;

View File

@@ -1,4 +1,6 @@
#pragma once
#include "src/Core/Object/Object.h"
#include "src/Core/Core.h"
#include "src/Resource/Serializable.h"
#include "src/Rendering/Textures/Texture.h"
@@ -8,6 +10,8 @@ namespace Nuake
{
class SpriteComponent
{
NUAKECOMPONENT(SpriteComponent, "Sprite")
public:
bool Billboard;
bool LockYRotation;

View File

@@ -1,6 +1,8 @@
#pragma once
#include <string>
#include <glm/ext/matrix_float4x4.hpp>
#include "src/Core/Logger.h"
#include "../Scene.h"
#include "../Components/BaseComponent.h"
#include "../Resource/Serializable.h"
@@ -31,6 +33,32 @@ namespace Nuake
return m_EntityHandle != (entt::entity)-1 && m_Scene->m_Registry.valid((entt::entity)GetHandle());
}
void AddComponent(entt::meta_type& enttMetaType)
{
if (!enttMetaType)
{
Logger::Log("Meta data empty/invalid", "Entity", WARNING);
return;
}
entt::meta_any newComponent = enttMetaType.construct();
if (!newComponent)
{
Logger::Log("Could not create a component from the meta type", "Entity", CRITICAL);
return;
}
auto func = enttMetaType.func(HashedFnName::AddToEntity);
// TODO: [WiggleWizard] Needs a lot more validation
if (!func)
{
Logger::Log("No such function exists or is registered on component", "Entity", CRITICAL);
return;
}
func.invoke(newComponent, m_EntityHandle, &m_Scene->m_Registry);
}
template<typename T>
T& AddComponent()
{