diff --git a/Editor/src/Windows/EditorSelectionPanel.cpp b/Editor/src/Windows/EditorSelectionPanel.cpp index eddec7e0..1e7316dc 100644 --- a/Editor/src/Windows/EditorSelectionPanel.cpp +++ b/Editor/src/Windows/EditorSelectionPanel.cpp @@ -13,6 +13,8 @@ #include #include +#include + 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(); + if (ImGui::MenuItem(className.c_str())) + { + entity.AddComponent(t); + } + } + } + ImGui::EndPopup(); } diff --git a/Nuake/src/Core/Object/Object.h b/Nuake/src/Core/Object/Object.h new file mode 100644 index 00000000..8c065dc6 --- /dev/null +++ b/Nuake/src/Core/Object/Object.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#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(entity); \ + } \ + \ + inline static auto ComponentFactory = entt::meta() \ + .type(entt::hashed_string(#klass)) \ + .func<&klass::ComponentName>(HashedFnName::GetComponentName) \ + .func<&klass::AddToEntity>(HashedFnName::AddToEntity); diff --git a/Nuake/src/Scene/Components/AudioEmitterComponent.h b/Nuake/src/Scene/Components/AudioEmitterComponent.h index 52d609b7..bebfd6fb 100644 --- a/Nuake/src/Scene/Components/AudioEmitterComponent.h +++ b/Nuake/src/Scene/Components/AudioEmitterComponent.h @@ -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; diff --git a/Nuake/src/Scene/Components/BoneComponent.h b/Nuake/src/Scene/Components/BoneComponent.h index 824484b9..f1c9a8b8 100644 --- a/Nuake/src/Scene/Components/BoneComponent.h +++ b/Nuake/src/Scene/Components/BoneComponent.h @@ -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; diff --git a/Nuake/src/Scene/Components/BoxCollider.h b/Nuake/src/Scene/Components/BoxCollider.h index 44223399..80c84d60 100644 --- a/Nuake/src/Scene/Components/BoxCollider.h +++ b/Nuake/src/Scene/Components/BoxCollider.h @@ -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 Box; Vector3 Size = Vector3(0.5f, 0.5f, 0.5f); diff --git a/Nuake/src/Scene/Components/CameraComponent.h b/Nuake/src/Scene/Components/CameraComponent.h index 6bd1ede6..b62b7cf8 100644 --- a/Nuake/src/Scene/Components/CameraComponent.h +++ b/Nuake/src/Scene/Components/CameraComponent.h @@ -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 CameraInstance; TransformComponent* transformComponent; diff --git a/Nuake/src/Scene/Components/CapsuleColliderComponent.h b/Nuake/src/Scene/Components/CapsuleColliderComponent.h index 4e2170ea..a0114945 100644 --- a/Nuake/src/Scene/Components/CapsuleColliderComponent.h +++ b/Nuake/src/Scene/Components/CapsuleColliderComponent.h @@ -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 Capsule; diff --git a/Nuake/src/Scene/Components/CharacterControllerComponent.h b/Nuake/src/Scene/Components/CharacterControllerComponent.h index 621f7f66..7d39bec1 100644 --- a/Nuake/src/Scene/Components/CharacterControllerComponent.h +++ b/Nuake/src/Scene/Components/CharacterControllerComponent.h @@ -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 m_CharacterController; diff --git a/Nuake/src/Scene/Components/CylinderColliderComponent.h b/Nuake/src/Scene/Components/CylinderColliderComponent.h index d9a71217..3aa31b29 100644 --- a/Nuake/src/Scene/Components/CylinderColliderComponent.h +++ b/Nuake/src/Scene/Components/CylinderColliderComponent.h @@ -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 Cylinder; diff --git a/Nuake/src/Scene/Components/LightComponent.h b/Nuake/src/Scene/Components/LightComponent.h index e4cc77fc..95204b52 100644 --- a/Nuake/src/Scene/Components/LightComponent.h +++ b/Nuake/src/Scene/Components/LightComponent.h @@ -1,4 +1,7 @@ #pragma once + +#include "src/Core/Object/Object.h" + #include #include #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; diff --git a/Nuake/src/Scene/Components/MeshCollider.h b/Nuake/src/Scene/Components/MeshCollider.h index 0d93fc86..8c2c32ec 100644 --- a/Nuake/src/Scene/Components/MeshCollider.h +++ b/Nuake/src/Scene/Components/MeshCollider.h @@ -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; diff --git a/Nuake/src/Scene/Components/ModelComponent.h b/Nuake/src/Scene/Components/ModelComponent.h index 2296ba90..d130b677 100644 --- a/Nuake/src/Scene/Components/ModelComponent.h +++ b/Nuake/src/Scene/Components/ModelComponent.h @@ -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 ModelResource; std::string ModelPath; diff --git a/Nuake/src/Scene/Components/NavMeshVolumeComponent.h b/Nuake/src/Scene/Components/NavMeshVolumeComponent.h index 7c8f829e..0b551ca4 100644 --- a/Nuake/src/Scene/Components/NavMeshVolumeComponent.h +++ b/Nuake/src/Scene/Components/NavMeshVolumeComponent.h @@ -1,4 +1,6 @@ #pragma once + +#include "src/Core/Object/Object.h" #include "../Entities/Entity.h" #include "Engine.h" #include @@ -7,6 +9,8 @@ namespace Nuake { struct NavMeshVolumeComponent { + NUAKECOMPONENT(NavMeshVolumeComponent, "Nav Mesh Volume") + Vector3 VolumeSize = { 1.0f, 1.0f, 1.0f }; bool OnlyIncludeMapGeometry = true; diff --git a/Nuake/src/Scene/Components/NetScriptComponent.h b/Nuake/src/Scene/Components/NetScriptComponent.h index 752f7e41..8cd6bcfe 100644 --- a/Nuake/src/Scene/Components/NetScriptComponent.h +++ b/Nuake/src/Scene/Components/NetScriptComponent.h @@ -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 +#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; } }; -} \ No newline at end of file +} diff --git a/Nuake/src/Scene/Components/ParticleEmitterComponent.h b/Nuake/src/Scene/Components/ParticleEmitterComponent.h index 7a046fa4..fb309038 100644 --- a/Nuake/src/Scene/Components/ParticleEmitterComponent.h +++ b/Nuake/src/Scene/Components/ParticleEmitterComponent.h @@ -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; diff --git a/Nuake/src/Scene/Components/QuakeMap.h b/Nuake/src/Scene/Components/QuakeMap.h index 4fe0c250..9d9169b0 100644 --- a/Nuake/src/Scene/Components/QuakeMap.h +++ b/Nuake/src/Scene/Components/QuakeMap.h @@ -2,6 +2,7 @@ #include #include +#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> m_Meshes; std::vector m_Brushes; diff --git a/Nuake/src/Scene/Components/RigidbodyComponent.h b/Nuake/src/Scene/Components/RigidbodyComponent.h index 240fbc70..06ad21f6 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.h +++ b/Nuake/src/Scene/Components/RigidbodyComponent.h @@ -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; diff --git a/Nuake/src/Scene/Components/SkinnedModelComponent.h b/Nuake/src/Scene/Components/SkinnedModelComponent.h index b0abed18..b33c9a07 100644 --- a/Nuake/src/Scene/Components/SkinnedModelComponent.h +++ b/Nuake/src/Scene/Components/SkinnedModelComponent.h @@ -1,6 +1,7 @@ #pragma once #include +#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 ModelResource; std::string ModelPath; diff --git a/Nuake/src/Scene/Components/SphereCollider.h b/Nuake/src/Scene/Components/SphereCollider.h index 52f44786..bd79f3d6 100644 --- a/Nuake/src/Scene/Components/SphereCollider.h +++ b/Nuake/src/Scene/Components/SphereCollider.h @@ -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 Sphere; diff --git a/Nuake/src/Scene/Components/SpriteComponent.h b/Nuake/src/Scene/Components/SpriteComponent.h index e22dc0ff..f5b06c19 100644 --- a/Nuake/src/Scene/Components/SpriteComponent.h +++ b/Nuake/src/Scene/Components/SpriteComponent.h @@ -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; diff --git a/Nuake/src/Scene/Entities/Entity.h b/Nuake/src/Scene/Entities/Entity.h index 26d75949..2abff3dc 100644 --- a/Nuake/src/Scene/Entities/Entity.h +++ b/Nuake/src/Scene/Entities/Entity.h @@ -1,6 +1,8 @@ #pragma once #include #include + +#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 T& AddComponent() {