DeerEngine/Deer/Include/Deer/Enviroment.h

154 lines
4.1 KiB
C++
Executable File

#pragma once
#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
#include <algorithm>
#include <string>
#include <unordered_map>
#include <vector>
#include <stack>
namespace Deer {
class Entity;
class Environment {
// Note: Outdated note
///////// 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);
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(SceneCamera& camera);
#endif
Scope<entt::registry> m_registry;
private:
uint16_t m_mainCamera = 0;
std::stack<u_int16_t> unused_entities_spaces;
std::vector<Entity> entities;
friend class Entity;
};
// 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;
Environment* getEnvironment() 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:
Environment* environment = nullptr;
entt::entity entHandle = entt::null;
uint16_t entId = 0;
uint16_t parentId = 0;
Entity(entt::entity handle, Environment* scene, uint16_t entityID);
friend class Environment;
public:
template <typename T, typename... Args>
T& addComponent(Args&&... args) const {
DEER_CORE_ASSERT(
!environment->m_registry->all_of<T>(entHandle),
"Entity already have component {0}", typeid(T).name());
return environment->m_registry->emplace<T>(
entHandle, std::forward<Args>(args)...);
}
template <typename T>
T& getComponent() const {
DEER_CORE_ASSERT(
environment->m_registry->all_of<T>(entHandle),
"Entity has no component {0}", typeid(T).name());
return environment->m_registry->get<T>(entHandle);
}
template <typename T>
bool hasComponent() const {
return environment->m_registry->all_of<T>(entHandle);
}
template <typename T>
void removeComponent() const {
DEER_CORE_ASSERT(
environment->m_registry->all_of<T>(entHandle),
"Entity does not have component {0}", typeid(T).name());
environment->m_registry->remove<T>(entHandle);
}
};
} // namespace Deer