70 lines
1.8 KiB
C++
70 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#include <entt/entt.hpp>
|
|
#include <sophia/scene.hpp>
|
|
#include <sophia/types.hpp>
|
|
#include <sophia/util/assert.hpp>
|
|
|
|
namespace sophia {
|
|
|
|
class Entity {
|
|
public:
|
|
Entity(const Entity&) = default;
|
|
Entity& operator=(const Entity&) = default;
|
|
|
|
Entity() = default;
|
|
Entity(entt::entity handle, Scene* scene);
|
|
|
|
template <typename T, typename... Args>
|
|
T& addComponent(Args&&... args) {
|
|
SOPHIA_ASSERT(!hasComponent<T>(), "Entity already has component!");
|
|
T& component =
|
|
scene->registry.emplace<T>(handle, std::forward<Args>(args)...);
|
|
// scene->OnComponentAdded<T>(*this, component);
|
|
return component;
|
|
}
|
|
|
|
template <typename T>
|
|
T& getComponent() {
|
|
SOPHIA_ASSERT(hasComponent<T>(), "Entity does not have component!");
|
|
return scene->registry.get<T>(handle);
|
|
}
|
|
|
|
template <typename T>
|
|
bool hasComponent() {
|
|
return scene->registry.all_of<T>(handle);
|
|
}
|
|
|
|
template <typename T>
|
|
void removeComponent() {
|
|
SOPHIA_ASSERT(hasComponent<T>(), "Entity does not have component!");
|
|
scene->registry.remove<T>(handle);
|
|
}
|
|
|
|
operator bool() const { return handle != entt::null; }
|
|
operator entt::entity() const { return handle; }
|
|
operator u32() const { return (u32)handle; }
|
|
|
|
// UUID GetUUID() { return GetComponent<IDComponent>().ID; }
|
|
// const std::string& GetName() { return GetComponent<TagComponent>().Tag; }
|
|
|
|
bool operator==(const Entity& other) const {
|
|
return handle == other.handle && scene == other.scene;
|
|
}
|
|
|
|
bool operator!=(const Entity& other) const { return !(*this == other); }
|
|
|
|
private:
|
|
entt::entity handle{entt::null};
|
|
Scene* scene = nullptr;
|
|
};
|
|
|
|
template <typename Fn>
|
|
void Scene::forEachEntity(Fn&& fn) {
|
|
for (auto [handle] : registry.storage<entt::entity>().each()) {
|
|
fn(Entity{handle, this});
|
|
}
|
|
}
|
|
|
|
} // namespace sophia
|