#pragma once #include "tinyengine/pch.hpp" #include "tinyengine/pool.hpp" #include "component.hpp" #include "context.hpp" class Entity final { public: friend class Pool; template void Add(Args... args) { if (!alive_) { std::cout << "Entity::Add(): entity is die, can't add component." << std::endl; } else { T* comp = context_->CreateComponent(args...); components_[ComponentIdx::Get()] = comp; } } inline void Init(Context* context) { context_ = context; } inline void Release() { components_.clear(); } template const T* Get() const { if constexpr (!std::is_base_of_v) { std::cout << "Entity::Get() const: the type T is not inherit from Component" << std::endl; return nullptr; } else { return (T*)Get(ComponentIdx::Get()); } } Component* Get(ComponentId id) const { if (!alive_) { std::cout << "Entity::Get(id) const: entity is die, can't get anything from it." << std::endl; return nullptr; } auto it = components_.find(id); if (it == components_.end()) { return nullptr; } else { return it->second; } } template T* Use() { if (!alive_) { std::cout << "Entity::Use() const: entity is die, can't get anything from it." << std::endl; return nullptr; } auto it = components_.find(ComponentIdx::Get()); if (it == components_.end()) { return nullptr; } else { return (T*)it->second; } } template void Replace(Args... args) { if (!alive_) { std::cout << "Entity::Replace() const: entity is die, can't replace component." << std::endl; } else { auto it = components_.find(ComponentIdx::Get()); if (it != components_.end()) { T* c = (T*)it->second; c->Init(args...); } else { Add(args...); } } } template void Remove() { Remove(ComponentIdx::Get()); } inline void Remove(ComponentId id) { if (!alive_) { std::cout << "Entity::Remove() const: entity is die, can't remove anything from it." << std::endl; } else { auto it = components_.find(id); if (it != components_.end()) { context_->DestroyComponentById(it->second, id); components_.erase(it); } } } template bool Has() const { if (!alive_) { std::cout << "Entity::Has() const: entity is die, can't query." << std::endl; return false; } return hasIter(); } inline bool Has(ComponentId id) const { return components_.find(id) != components_.end(); } inline void Reset() { for (ComponentId i = 0; i < ComponentIdx::GetCount(); i++) { auto it = components_.find(i); if (it != components_.end()) { components_.erase(it); } } } inline bool IsAlive() const { return alive_; } private: std::unordered_map components_; bool alive_; Context* context_ = nullptr; template bool hasIter() const { if constexpr (sizeof...(Types) == 0) { return Get(); } else { return Get() && hasIter(); } } };