DeerEngine/Deer/Include/Deer/Enviroment.h

166 lines
4.6 KiB
C++
Executable File

#pragma once
#include <algorithm>
#include <array>
#include <string>
#include <unordered_map>
#include <vector>
#include "Deer/Components.h"
#include "Deer/Log.h"
#include "Deer/Memory.h"
#include "entt/entt.hpp"
#ifdef DEER_RENDER
#include "DeerRender/Render/FrameBuffer.h"
#include "DeerRender/SceneCamera.h"
#endif
#define ENVIRONMENT_MAX_ENTITIES 2048
namespace Deer {
class Entity;
class Environment {
///////// NOTES ///////////
// - The entity id means the position in a array defined in Environment
// - The entity id is relative to a Environment 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 Environment
///////// NOTES ///////////
public:
Environment();
~Environment();
// This class can not be copyed
Environment(const Environment&) = delete;
Environment& operator=(Environment&) = delete;
// Clears all entities
void clear();
// Obtains the entity
Entity& getEntity(uint16_t id) const;
bool entityExists(uint16_t id) const;
uint16_t getEntityCount() const { return m_entityCount; }
// Creates a entity child at root
Entity& createEntity(const std::string& name = "");
Entity& createEntityWithId(uint16_t id, const std::string& name = "");
void destroyEntity(uint16_t id);
// Special behaviour
Entity createEmptyEntity();
// FEO
uint16_t tryGetMainCamera();
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(SceneCamera& camera);
#endif
entt::registry m_registry;
private:
uint16_t m_mainCamera = 0;
// To avoid inecessary loop we set this variable that means that smaller
// id's than this numbers are not null, empty or used
uint16_t m_idCreationOffset = 0;
// Since we don't initialize Entity in the big array for performance we
// want to keep track the ones we initialized defined by this value, it
// the id is greater it means that any information that it has can't be
// seen as valid
uint16_t m_maxIdValue = 0;
// Number of entities that exists inside
uint16_t m_entityCount = 0;
// This is where we save the entities, in a const list defined by
// ENVIRONMENT_MAX_ENTITIES, we have to make sure this system is as fast
// as possible
Scope<std::array<Entity, ENVIRONMENT_MAX_ENTITIES>> entities;
inline uint16_t pullEntityID() {
m_idCreationOffset++;
if (m_idCreationOffset > m_maxIdValue)
m_maxIdValue = m_idCreationOffset;
return m_idCreationOffset;
}
friend class Entity;
};
// Warning: This calss does not initialize for performance
class Entity {
public:
// This class can not be copied
Entity(const Entity&) = delete;
Entity() {}
template <typename T, typename... Args>
T& addComponent(Args&&... args) const {
DEER_CORE_ASSERT(
!m_environment->m_registry.all_of<T>(m_entityHandle),
"Entity already have component {0}", typeid(T).name());
return m_environment->m_registry.emplace<T>(
m_entityHandle, std::forward<Args>(args)...);
}
template <typename T>
T& getComponent() const {
DEER_CORE_ASSERT(
m_environment->m_registry.all_of<T>(m_entityHandle),
"Entity has no component {0}", typeid(T).name());
return m_environment->m_registry.get<T>(m_entityHandle);
}
template <typename T>
bool hasComponent() const {
return m_environment->m_registry.all_of<T>(m_entityHandle);
}
template <typename T>
void removeComponent() const {
DEER_CORE_ASSERT(
m_environment->m_registry.all_of<T>(m_entityHandle),
"Entity does not have component {0}", typeid(T).name());
m_environment->m_registry.remove<T>(m_entityHandle);
}
Entity& duplicate();
void destroy();
uint16_t getId() const { return m_entityID; }
Entity& getParent() const;
inline uint16_t getParentId() const { return m_parentID; }
// TODO, enable transfer entitys from difrent enviroments
void setParent(Entity& parent);
bool isDescendantOf(Entity& parent) const;
Environment* getEnvironment() const { return m_environment; }
bool isRoot() const { return m_entityID == 0; }
glm::mat4 getWorldMatrix();
glm::mat4 getRelativeMatrix();
void updateInternalVars();
inline bool isValid() const { return m_exists; }
private:
Environment* m_environment = nullptr;
entt::entity m_entityHandle = entt::null;
uint16_t m_entityID = 0;
uint16_t m_parentID = 0;
bool m_exists = false;
Entity(entt::entity handle, Environment* scene, uint16_t entityID);
friend class Environment;
};
} // namespace Deer