174 lines
4.8 KiB
C++
Executable File
174 lines
4.8 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
|
|
#define MAX_ENVIRONMENT_COUNT 64
|
|
|
|
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 environments
|
|
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 tickExecution();
|
|
|
|
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 EnvironmentManager {
|
|
uint16_t createEnvironment();
|
|
Environment& getEnvironment(uint16_t);
|
|
|
|
void clearAllEnvironments();
|
|
}
|
|
} // namespace Deer
|