diff --git a/core/component/camera.cpp b/core/component/camera.cpp index b42b3d8..038f5da 100644 --- a/core/component/camera.cpp +++ b/core/component/camera.cpp @@ -3,7 +3,7 @@ namespace SpaceEngine { -Camera::Camera(Entity* owner) : Component(owner) { +Camera::Camera(std::weak_ptr owner) : Component(owner) { front = glm::vec3(0.0f, 0.0f, -1.0f); zoom = 45.0f; worldUp = glm::vec3(0.0f, 1.0f, 0.0f); @@ -12,11 +12,14 @@ Camera::Camera(Entity* owner) : Component(owner) { updateCameraVectors(); } -Camera::~Camera() {} - glm::mat4 Camera::getViewMatrix() { - Transform* tf = this->owner->getComponent(); - return glm::lookAt(glm::vec3(tf->position.x, tf->position.y, tf->position.z), position + front, up); + auto lockedOwner = owner.lock(); + if (!lockedOwner) { + return glm::mat4(1.0f); + } else { + auto tf = lockedOwner->getComponent(); + return glm::lookAt(glm::vec3(tf->position.x, tf->position.y, tf->position.z), position + front, up); + } } void Camera::updateCameraVectors() { diff --git a/core/component/camera.hpp b/core/component/camera.hpp index f3daf85..4389834 100644 --- a/core/component/camera.hpp +++ b/core/component/camera.hpp @@ -27,14 +27,9 @@ class Camera : public Component { /** * @brief Default constructor: Initializes a new empty Camera component. - * @param owner (Entity*): A pointer to the entity that store the component. + * @param owner (std::weak_ptr): A pointer to the entity that store the component. */ - Camera(Entity* owner); - - /** - * @brief Destructor: Destroys the Camera component. Note: May not have additional functionality in this case. - */ - ~Camera(); + Camera(std::weak_ptr owner); /** * @brief Get the view matrix of the camera. diff --git a/core/component/component.cpp b/core/component/component.cpp index 55b807f..0941ed0 100644 --- a/core/component/component.cpp +++ b/core/component/component.cpp @@ -2,7 +2,7 @@ namespace SpaceEngine { -Component::Component(Entity* owner) { this->owner = owner; } +Component::Component(std::weak_ptr owner) { this->owner = owner; } Component::~Component() {} } diff --git a/core/component/component.hpp b/core/component/component.hpp index 9cffc99..d02cc90 100644 --- a/core/component/component.hpp +++ b/core/component/component.hpp @@ -1,5 +1,7 @@ #pragma once +#include + namespace SpaceEngine { class Entity; // Forward declaration of Entity class to avoid circular dependencies. @@ -8,7 +10,7 @@ class Entity; // Forward declaration of Entity class to avoid circular dependenc * The Component class serves as a base class for components in the entity-component system. * * Attributes - * - owner (Entity*): A pointer to the entity owning the component. + * - owner (std::weak_ptr): A pointer to the entity owning the component. * * Methods: * - Component(): Default constructor. @@ -16,14 +18,14 @@ class Entity; // Forward declaration of Entity class to avoid circular dependenc */ class Component { protected: - Entity* owner = nullptr; // Pointer to the entity owning the component. + std::weak_ptr owner; // Pointer to the entity owning the component. public: /** * @brief Default constructor. - * @param owner (Entity*): A pointer to the entity that store the component. + * @param owner (std::weak_ptr): A pointer to the entity that store the component. */ - Component(Entity* owner); + Component(std::weak_ptr owner); /** * @brief Virtual destructor to allow proper cleanup in derived classes. diff --git a/core/component/light.cpp b/core/component/light.cpp index 426da22..874eb45 100644 --- a/core/component/light.cpp +++ b/core/component/light.cpp @@ -2,11 +2,7 @@ namespace SpaceEngine { -Light::Light(Entity* owner) : Component(owner) { - -} - -Light::~Light() { +Light::Light(std::weak_ptr owner) : Component(owner) { } diff --git a/core/component/light.hpp b/core/component/light.hpp index 6c1acc1..d0e3275 100644 --- a/core/component/light.hpp +++ b/core/component/light.hpp @@ -20,14 +20,10 @@ class Light : public Component { /** * @brief Default constructor: Initializes a new Light component with default values. - * @param owner (Entity*): A pointer to the entity that store the component. + * @param owner (weak_ptr): A pointer to the entity that store the component. */ - Light(Entity* owner); + Light(std::weak_ptr owner); - /** - * @brief Destructor: Destroys the Light component. Note: May not have additional functionality in this case. - */ - ~Light(); }; } diff --git a/core/component/model_renderer.cpp b/core/component/model_renderer.cpp index faba165..e5c659b 100644 --- a/core/component/model_renderer.cpp +++ b/core/component/model_renderer.cpp @@ -2,7 +2,7 @@ namespace SpaceEngine { -ModelRenderer::ModelRenderer(Entity* owner) : Component(owner) { +ModelRenderer::ModelRenderer(std::weak_ptr owner) : Component(owner) { model = nullptr; } diff --git a/core/component/model_renderer.hpp b/core/component/model_renderer.hpp index c0ae4ac..1ef042f 100644 --- a/core/component/model_renderer.hpp +++ b/core/component/model_renderer.hpp @@ -17,13 +17,13 @@ namespace SpaceEngine { */ class ModelRenderer : public Component { public: - Model* model = nullptr; /* The 3D model to be rendered. */ + std::shared_ptr model; /* The 3D model to be rendered. */ /** * @brief Default constructor: Initializes a new empty ModelRenderer component. - * @param owner (Entity*): A pointer to the entity that store the component. + * @param owner (std::weak_ptr): A pointer to the entity that store the component. */ - ModelRenderer(Entity* owner); + ModelRenderer(std::weak_ptr owner); /** * @brief Destructor: Destroys the ModelRenderer component. Note: May not have additional functionality in this case. diff --git a/core/component/physic.cpp b/core/component/physic.cpp index 1e6b2ec..cfa0362 100644 --- a/core/component/physic.cpp +++ b/core/component/physic.cpp @@ -2,7 +2,7 @@ namespace SpaceEngine { -Physic::Physic(Entity* owner) : Component(owner) { +Physic::Physic(std::weak_ptr owner) : Component(owner) { this->mass = 1.0; this->drag = 0; this->angularDrag = 0; diff --git a/core/component/physic.hpp b/core/component/physic.hpp index 8090654..a7e5159 100644 --- a/core/component/physic.hpp +++ b/core/component/physic.hpp @@ -26,9 +26,9 @@ class Physic : public Component { /** * @brief Default constructor: Initializes a new Physic component with default values. - * @param owner (Entity*): A pointer to the entity that store the component. + * @param owner (std::weak_ptr): A pointer to the entity that store the component. */ - Physic(Entity* owner); + Physic(std::weak_ptr owner); /** * @brief Destructor: Destroys the Physic component. Note: May not have additional functionality in this case. diff --git a/core/component/transform.cpp b/core/component/transform.cpp index 50c009d..4184edb 100644 --- a/core/component/transform.cpp +++ b/core/component/transform.cpp @@ -2,7 +2,7 @@ namespace SpaceEngine { -Transform::Transform(Entity* owner, std::string name) : Component(owner) { +Transform::Transform(std::weak_ptr owner, std::string name) : Component(owner) { this->name = name; this->position = Vector3(); this->scale = Vector3(1.0f, 1.0f, 1.0f); diff --git a/core/component/transform.hpp b/core/component/transform.hpp index e6eb63d..8d27840 100644 --- a/core/component/transform.hpp +++ b/core/component/transform.hpp @@ -29,10 +29,10 @@ class Transform : public Component { /** * @brief Default constructor: Initializes a new transform component with default values. - * @param owner (Entity*): A pointer to the entity that store the component. + * @param owner (std::weak_ptr): A pointer to the entity that store the component. * @param name: The name of the object. */ - Transform(Entity* owner, std::string name); + Transform(std::weak_ptr owner, std::string name); /** * @brief Destructor: Destroys the transform component. Note: May not have additional functionality in this case. diff --git a/core/entity/entity.cpp b/core/entity/entity.cpp index 83f9d8a..2a63c5e 100644 --- a/core/entity/entity.cpp +++ b/core/entity/entity.cpp @@ -6,12 +6,16 @@ Entity::Entity(std::string name) { this->addComponent(name); } -void Entity::addChildren(Entity* child) { - childs.push_back(child); +void Entity::addChild(std::unique_ptr child) { + children.push_back(std::move(child)); } -void Entity::removeChildren(Entity* child) { - childs.erase(std::remove(childs.begin(), childs.end(), child), childs.end()); +void Entity::removeChild(int index) { + if (index >= 0 && static_cast(index) < children.size()) { + children.erase(children.begin() + index); + } else { + std::cerr << "Attempted to remove a child with an invalid index: " << index << std::endl; + } } } diff --git a/core/entity/entity.hpp b/core/entity/entity.hpp index 241f739..df2b911 100644 --- a/core/entity/entity.hpp +++ b/core/entity/entity.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -14,12 +15,12 @@ namespace SpaceEngine { -class Entity { +class Entity : public std::enable_shared_from_this { public: /* Map of components an Entity has. */ - std::map components; + std::map> components; /* Vector listing all the children entities. */ - std::vector childs; + std::vector> children; /* Default constructor: Initializes a new Entity with default values. */ Entity(std::string name); @@ -33,7 +34,7 @@ class Entity { */ template void addComponent(Args&&... args) { - T* component = new T(this, std::forward(args)...); + auto component = std::make_shared(shared_from_this(), std::forward(args)...); components[typeid(T)] = component; } @@ -44,10 +45,10 @@ class Entity { * @note Declared in .hpp to avoid massive template declaration. */ template - T* getComponent() const { + std::shared_ptr getComponent() const { auto it = components.find(typeid(T)); if (it != components.end()) { - return dynamic_cast(it->second); + return std::dynamic_pointer_cast(it->second); } return nullptr; } @@ -74,13 +75,13 @@ class Entity { * Add a child to children vector of the entity. * @param child: A reference to an Entity. */ - void addChildren(Entity* child); + void addChild(std::unique_ptr child); - /* + /* TODO: UPDATE AND CHECK IF INDEX IS GOOD * Remove a child from children vector of the entity. * @param child: A reference to an Entity. */ - void removeChildren(Entity* child); + void removeChild(int index); }; } diff --git a/core/scene/scene.cpp b/core/scene/scene.cpp index 866c8e9..7fac80d 100644 --- a/core/scene/scene.cpp +++ b/core/scene/scene.cpp @@ -4,18 +4,22 @@ namespace SpaceEngine { Scene::Scene() { this->name = "New Scene"; - Entity* defaultCamera = new Entity("Default Camera"); + auto defaultCamera = std::make_shared("Default Camera"); defaultCamera->addComponent(); this->addEntity(defaultCamera); this->selectedCamera = defaultCamera->getComponent(); } -void Scene::addEntity(Entity* ent) { +void Scene::addEntity(std::shared_ptr ent) { entities.push_back(ent); } -void Scene::removeEntity(Entity* ent) { - entities.erase(std::remove(entities.begin(), entities.end(), ent), entities.end()); +void Scene::removeEntity(int index) { + if (index >= 0 && static_cast(index) < entities.size()) { + entities.erase(entities.begin() + index); + } else { + std::cerr << "Error: Attempted to remove entity with invalid index: " << index << std::endl; + } } } diff --git a/core/scene/scene.hpp b/core/scene/scene.hpp index fff881c..6f5d0df 100644 --- a/core/scene/scene.hpp +++ b/core/scene/scene.hpp @@ -1,8 +1,9 @@ #pragma once -#include "string" -#include "vector" -#include "algorithm" +#include +#include +#include +#include #include "entity/entity.hpp" #include "component/camera.hpp" @@ -28,10 +29,10 @@ class Scene{ std::string name; // Vector of pointers to Entity contained within the scene - std::vector entities; + std::vector> entities; // Main camera component in the scene. Used to render game. - Camera* selectedCamera = nullptr; + std::weak_ptr selectedCamera; /** * @brief Initialize a Scene with default name. @@ -42,13 +43,13 @@ class Scene{ * @brief Add an Entity to the scene. * @param ent: Reference to the entity. */ - void addEntity(Entity* ent); + void addEntity(std::shared_ptr ent); - /** + /** TODO CHECK IF INDEX IS GOOD AND REWORK IF NEEDED * @brief Remove an Entity from the scene. - * @param ent: Reference to the entity. + * @param index: index of the entity. */ - void removeEntity(Entity* ent); + void removeEntity(int index); }; } diff --git a/editor/main.cpp b/editor/main.cpp index 2a0837f..693021c 100644 --- a/editor/main.cpp +++ b/editor/main.cpp @@ -157,12 +157,12 @@ int main() { //TODO : Remove too // Scene creation Scene scene = Scene(); - scene.addEntity(new Entity("Backpack")); + scene.addEntity(std::make_shared("Backpack")); scene.entities[1]->addComponent(); - scene.entities[1]->getComponent()->model = new Model("../../models/backpack/backpack.obj"); + scene.entities[1]->getComponent()->model = std::make_shared("../../models/backpack/backpack.obj"); // Menu creation - Menu menu = Menu(&scene); + Menu menu = Menu(std::make_shared()); menu.selectedEntity = scene.entities[1]; // TODO: REMOVE OPENGL TESTS @@ -198,9 +198,9 @@ int main() { shader.setMat4("view", view); for (auto& entity : scene.entities) { - ModelRenderer* modelRenderer = entity->getComponent(); - if (modelRenderer != nullptr) { - Transform* tf = entity->getComponent(); + auto modelRenderer = entity->getComponent(); + if (modelRenderer && modelRenderer->model) { + auto tf = entity->getComponent(); glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(tf->position.x, tf->position.y, tf->position.z)); model = glm::scale(model, glm::vec3(tf->scale.x, tf->scale.y, tf->scale.z)); diff --git a/editor/menu/component_viewer.cpp b/editor/menu/component_viewer.cpp index d773ac5..beb4537 100644 --- a/editor/menu/component_viewer.cpp +++ b/editor/menu/component_viewer.cpp @@ -3,8 +3,8 @@ namespace SpaceEditor { void Menu::initComponentViewers() { - this->componentViewers[std::type_index(typeid(Transform))] = [](Component* component) { - auto* transform = static_cast(component); + this->componentViewers[std::type_index(typeid(Transform))] = [](std::shared_ptr component) { + auto transform = std::static_pointer_cast(component); if (ImGui::CollapsingHeader("Transform")) { ImGui::Text("Name"); ImGui::SameLine(100); @@ -36,8 +36,8 @@ void Menu::initComponentViewers() { } }; - this->componentViewers[std::type_index(typeid(Physic))] = [](Component* component) { - auto* physic = static_cast(component); + this->componentViewers[std::type_index(typeid(Physic))] = [](std::shared_ptr component) { + auto physic = std::static_pointer_cast(component); if (ImGui::CollapsingHeader("Physic")) { ImGui::Text("Mass"); ImGui::SameLine(100); @@ -54,8 +54,8 @@ void Menu::initComponentViewers() { } }; - this->componentViewers[std::type_index(typeid(ModelRenderer))] = [](Component* component) { - auto* modelRenderer = static_cast(component); + this->componentViewers[std::type_index(typeid(ModelRenderer))] = [](std::shared_ptr component) { + auto modelRenderer = std::static_pointer_cast(component); if (ImGui::CollapsingHeader("Component")) { ImGui::Text("Model"); ImGui::SameLine(100); diff --git a/editor/menu/menu.cpp b/editor/menu/menu.cpp index 85ed5d2..6203282 100644 --- a/editor/menu/menu.cpp +++ b/editor/menu/menu.cpp @@ -2,7 +2,7 @@ namespace SpaceEditor { -Menu::Menu(Scene* scene) { +Menu::Menu(std::shared_ptr scene) { this->scene = scene; initComponentViewers(); cherryTheme(); @@ -82,12 +82,14 @@ void Menu::displayMenuBar() { void Menu::displayInspector() { if (ImGui::Begin("Inspector")) { if (selectedEntity == nullptr) { + // TODO : enbable when compiling again after shared_ptr rework.. + // ImGui::End(); return; } for (const auto& componentPair : selectedEntity->components) { std::type_index typeIndex = componentPair.first; - Component* component = componentPair.second; + auto component = componentPair.second; auto viewerIt = componentViewers.find(typeIndex); if (viewerIt != componentViewers.end()) { viewerIt->second(component); diff --git a/editor/menu/menu.hpp b/editor/menu/menu.hpp index 9419f63..8b1dbbf 100644 --- a/editor/menu/menu.hpp +++ b/editor/menu/menu.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "imgui/imgui_impl_glfw.h" #include "imgui/imgui_stdlib.h" @@ -53,7 +54,7 @@ class Menu { bool showScene = false; // Scene section visiblity flag. bool showRender = false; // Render section visiblity flag. - std::unordered_map> componentViewers; + std::unordered_map)>> componentViewers; /* Display a transform component section. */ void initComponentViewers(); @@ -78,16 +79,16 @@ class Menu { public: /* Reference to the actual Scene. */ - Scene* scene; + std::shared_ptr scene; /* Reference to the selected Entity. */ - Entity* selectedEntity = nullptr; + std::shared_ptr selectedEntity = nullptr; /* * Main constructor that use default flags. * @param scene: Reference to a scene. */ - Menu(Scene* scene); + Menu(std::shared_ptr scene); /* Display the whole menu. */ void display();