#pragma once #include "DeerCore/Components.h" #include "DeerCore/Log.h" #include "DeerCore/Resource.h" #include "DeerCore/Tools/Memory.h" #include "entt/entt.hpp" #ifdef DEER_RENDER #include "DeerRender/Render/FrameBuffer.h" #include "DeerRender/Scene.h" #endif #include #include #include #include #include namespace Deer { class Entity; class EntityEnvironment { // Note: Outdated note ///////// NOTES /////////// // - The entity id means the position in a array defined in EntityEnvironment // - The entity id is relative to a EntityEnvironment so it can be a complete // diferent entity in other environments // - The entity number 0 is allways the root // - There is a limit defined by ENVIRONMENT_MAX_ENTITIES of how many // entities can be in an EntityEnvironment ///////// NOTES /////////// public: EntityEnvironment(); ~EntityEnvironment(); // This class can not be copyed EntityEnvironment(const EntityEnvironment&) = delete; EntityEnvironment& operator=(EntityEnvironment&) = delete; // Clears all entities void clear(); // Obtains the entity Entity& getEntity(uint16_t id); bool entityExists(uint16_t id) const; uint16_t getEntityCount() const; // Creates a entity child at root // WARNING: This method can change internal pointers and invalidate entitiy references Entity& createEntity(const std::string& name = ""); // Can be slow! This has to empty the stack of empty entities in case its necessary so use it in ascendent order! // WARNING: This method can change internal pointers and invalidate entitiy references Entity& createEntityWithId(uint16_t id, const std::string& name = ""); void destroyEntity(uint16_t id); // Special behaviour // WARNING: This method can change internal pointers and invalidate entitiy references Entity createEmptyEntity(); // FEO uint16_t tryGetMainCamera() const; void setMainCamera(Entity& entity); // Obtains the entity that is on the root of the environment inline Entity& getRoot() { return getEntity(0); } #ifdef DEER_RENDER void render(const SceneCamera& camera); #endif Scope m_registry; private: uint16_t m_mainCamera = 0; std::stack unused_entities_spaces; std::vector entities; friend class Entity; }; struct EntityData { int toDo; }; struct EntityEnvironmentData { std::vector entities; }; template <> class ResourceBuilder { public: using BaseDataType = EntityEnvironmentData; static Scope buildResource(const BaseDataType& baseData); }; // Warning: This calss does not initialize for performance class Entity { public: Entity() {} Entity(const Entity&) = delete; Entity(Entity&&) noexcept; Entity& operator=(Entity&&) noexcept; Entity& duplicate(); void destroy(); uint16_t getId() const { return entId; } Entity& getParent() const; inline uint16_t getParentId() const { return parentId; } // TODO, enable transfer entitys from difrent environments void setParent(Entity& parent); bool isDescendantOf(Entity& parent) const; EntityEnvironment* getEntityEnvironment() const { return environment; } bool isRoot() const { return entId == 0; } glm::mat4 getWorldMatrix() const; glm::mat4 getRelativeMatrix() const; void tickExecution(); void clear(); bool isValid() const; private: EntityEnvironment* environment = nullptr; entt::entity entHandle = entt::null; uint16_t entId = 0; uint16_t parentId = 0; Entity(entt::entity handle, EntityEnvironment* scene, uint16_t entityID); friend class EntityEnvironment; public: template T& addComponent(Args&&... args) const { DEER_CORE_ASSERT( !environment->m_registry->all_of(entHandle), "Entity already have component {0}", typeid(T).name()); return environment->m_registry->emplace( entHandle, std::forward(args)...); } template T& getComponent() const { DEER_CORE_ASSERT( environment->m_registry->all_of(entHandle), "Entity has no component {0}", typeid(T).name()); return environment->m_registry->get(entHandle); } template bool hasComponent() const { return environment->m_registry->all_of(entHandle); } template void removeComponent() const { DEER_CORE_ASSERT( environment->m_registry->all_of(entHandle), "Entity does not have component {0}", typeid(T).name()); environment->m_registry->remove(entHandle); } }; } // namespace Deer