#pragma once #include "component.h" #include #include #include #include #include #include #include #include "camera_class.h" #include namespace ecs { /** * Type alias for a unique identifier for an entity. */ using EntityID = uint32_t; class Entity : public std::enable_shared_from_this { public: /** * Builder for an Entity with a unique ID. */ explicit Entity(EntityID id) : m_ID(id) {} ~Entity() = default; /** * No copy constructor or assignment operator to prevent copying. */ Entity(const Entity&) = delete; Entity& operator=(const Entity&) = delete; /** * Move constructor and assignment operator to allow moving entities. */ Entity(Entity&&) = default; Entity& operator=(Entity&&) = default; /** * Get the unique identifier for the entity. * @return The unique ID of the entity. */ EntityID GetID() const { return m_ID; } /** * Add a component of type T to the entity. * If the component already exists, it returns the existing component. * @tparam T * @param args Arguments to construct the component. * @return A shared pointer to the added or existing component. */ template std::shared_ptr AddComponent(Args&&... args) { static_assert(std::is_base_of::value, "T must derive from Component"); ComponentTypeID typeID = GetComponentTypeID(); // Vérifier si le composant existe déjà if (m_Components.find(typeID) != m_Components.end()) { return std::static_pointer_cast(m_Components[typeID]); } // Créer et ajouter le composant auto component = std::make_shared(std::forward(args)...); m_Components[typeID] = component; component->SetParent(shared_from_this()); // Initialiser le composant component->Initialize(); return component; } /** * Get a component of type T from the entity. * @tparam T * @return A shared pointer to the component if it exists, nullptr otherwise. */ template std::shared_ptr GetComponent() { static_assert(std::is_base_of::value, "T must derive from Component"); ComponentTypeID typeID = GetComponentTypeID(); auto it = m_Components.find(typeID); if (it != m_Components.end()) { return std::static_pointer_cast(it->second); } return nullptr; } /** * Check if the entity has a component of type T. * @tparam T * @return true if the entity has the component, false otherwise. */ template bool HasComponent() const { static_assert(std::is_base_of::value, "T must derive from Component"); ComponentTypeID typeID = GetComponentTypeID(); return m_Components.find(typeID) != m_Components.end(); } /** * Remove a component of type T from the entity. * @tparam T */ template void RemoveComponent() { static_assert(std::is_base_of::value, "T must derive from Component"); ComponentTypeID typeID = GetComponentTypeID(); auto it = m_Components.find(typeID); if (it != m_Components.end()) { m_Components.erase(it); } } /** * Update all components of the entity. * @param deltaTime */ void UpdateComponents(float deltaTime) { for (auto& [typeID, component] : m_Components) { component->Update(deltaTime); } } /** * Get all components of the entity. * @return A constant reference to the map of components. */ const std::unordered_map& GetAllComponents() const { return m_Components; } /** * Set the main camera of the scene to be used by components like AudioComponent. * @param camera */ void SetCamera(camera_class* camera) {m_camera = camera; } /** * Get the main camera of the scene. * @return A pointer to the main camera. */ camera_class* GetCamera() const { return m_camera; } /** * Set the FMOD sound system to be used by components like AudioComponent. * @param soundSystem */ void SetSoundSystem(FMOD::System* soundSystem) {m_soundSystem = soundSystem; } /** * Get the FMOD sound system. * @return A pointer to the FMOD sound system. */ FMOD::System* GetSoundSystem() const { return m_soundSystem; } /** * Release all data associated with the entity. * This includes clearing all components and resetting the camera and sound system pointers. */ void release() { // call shutdown on all components if needed for (auto& [typeID, component] : m_Components) { // If components had a shutdown method, we would call it here component->Shutdown(); } m_Components.clear(); m_camera = nullptr; m_soundSystem = nullptr; } void SetDevice (ID3D11Device* dev) { device = dev; } void SetContext(ID3D11DeviceContext* ctx) { context = ctx; } ID3D11Device* GetDevice() const { return device; } ID3D11DeviceContext* GetContext() const { return context; } private: /** * Unique identifier for the entity. */ EntityID m_ID; /** * Map to hold components associated with the entity. * The key is the type ID of the component, and the value is a shared pointer to the component. */ std::unordered_map m_Components; // camera camera_class* m_camera = nullptr; // FMOD sound system FMOD::System* m_soundSystem = nullptr; ID3D11Device* device; ID3D11DeviceContext* context; }; } // namespace ecs