154 lines
4.1 KiB
C++
Executable File
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
|