Vulkan Schnee 0.0.1
High-performance rendering engine
Loading...
Searching...
No Matches
Entity.h
Go to the documentation of this file.
1#pragma once
2#include <Engine/Core/Tick.h>
3#include <vector>
4#include <memory>
5#include <algorithm>
6#include <cstdint>
7#include <type_traits>
8#include <plog/Log.h>
9#include <entt/entt.hpp>
10#include "uuid/uuid.h"
12
13namespace Engine::Entities{
17 class Entity : public Core::ITickable, protected std::enable_shared_from_this<Entity> {
18 public:
20 ~Entity() override;
21
26 void enableTick(bool enable);
27
28 void setTickPriority(int32_t priority);
29 [[nodiscard]] int32_t getTickPriority() const { return tickPriority_; }
30
35 void tick(double deltaTime) override;
36
45 template<typename T, typename... Args>
46 requires std::is_base_of_v<Components::Logic, T> && std::is_constructible_v<T, Args...>
47 T* addComponent(Args&&... args) {
48
49 if constexpr (T::IsUnique) {
50 T* existing = getComponent<T>();
51 if (existing) {
52 PLOGW << "Attempted to add unique component " << typeid(T).name() << " which already exists on entity.";
53 return existing;
54 }
55 }
56
57 auto component = std::make_unique<T>(std::forward<Args>(args)...);
58 component->setOwningEntity(this);
59 T* rawComponent = component.get();
60 components_.push_back(std::move(component));
61
62 // If the entity is already initialized (e.g. gameplay started), we might want to call beginPlay immediately?
63 // For now, we assume standard flow where components are added before play or beginPlay handles late init if needed.
64 // But typical pattern is to call beginPlay() if the actor has already begun play.
65 // We will leave that responsibility to the caller or Actor subclass for now to keep Entity simple.
66 // Note: Actor implementation will need to ensure new components get initialized.
67
68 return rawComponent;
69 }
70
75 template<typename T>
76 requires std::is_base_of_v<Components::Logic, T>
77 T* getComponent() const {
78 for (const auto& component : components_) {
79 if (auto typed = dynamic_cast<T*>(component.get())) {
80 return typed;
81 }
82 }
83 return nullptr;
84 }
85
90 template<typename T>
91 requires std::is_base_of_v<Components::Logic, T>
92 std::vector<T*> getComponents() const {
93 std::vector<T*> result;
94 for (const auto& component : components_) {
95 if (auto typed = dynamic_cast<T*>(component.get())) {
96 result.push_back(typed);
97 }
98 }
99 return result;
100 }
101
107 auto it = std::ranges::find_if(components_, [component](const auto& ptr) {
108 return ptr.get() == component;
109 });
110
111 if (it != components_.end()) {
112 (*it)->endPlay(); // Ensure cleanup
113 components_.erase(it);
114 }
115 }
116
121 template<typename T>
122 requires std::is_base_of_v<Components::Logic, T>
124 auto it = std::ranges::find_if(components_, [](const auto& ptr) {
125 return dynamic_cast<T*>(ptr.get()) != nullptr;
126 });
127
128 if (it != components_.end()) {
129 (*it)->endPlay();
130 components_.erase(it);
131 return true;
132 }
133 return false;
134 }
135
140 template<typename T>
141 requires std::is_base_of_v<Components::Logic, T>
142 bool hasComponent() const {
143 return getComponent<T>() != nullptr;
144 }
145
150 [[nodiscard]] const std::vector<std::unique_ptr<Components::Logic>>& getAllComponents() const {
151 return components_;
152 }
153
158 [[nodiscard]] bool canTick() const;
159
164 [[nodiscard]] bool canEverTick() const;
165
170 [[nodiscard]] entt::entity getEcsEntity() const { return data_; }
171
172 protected:
177 uuids::uuid getUUID() const { return uuid_; }
178
183 std::string getUuidString() const;
184
188 std::vector<std::unique_ptr<Components::Logic>> components_;
189
190 entt::entity data_ = entt::null;
191
192 bool allowTicking_ = false;
193 int32_t tickPriority_ = 0;
194 private:
195 uuids::uuid uuid_;
196 };
197
198}
Base class for all logic components that can be attached to an actor. Provides access to the scene,...
This is the interface which is used to call a tick function on an object. Everything which should be ...
Definition Tick.h:24
entt::entity getEcsEntity() const
Gets the ECS entity handle for this Entity.
Definition Entity.h:170
void enableTick(bool enable)
Enables or disables ticking for this entity.
T * addComponent(Args &&... args)
Adds a component to the entity. Checks for uniqueness if the component defines 'static constexpr bool...
Definition Entity.h:47
bool removeFirstComponent()
Removes the first component of type T found.
Definition Entity.h:123
int32_t getTickPriority() const
Definition Entity.h:29
std::string getUuidString() const
Getter for the UUID of this entity as a string.
bool canTick() const
Tells you if the entity can execute its tick function.
std::vector< std::unique_ptr< Components::Logic > > components_
List of all logical components.
Definition Entity.h:188
bool hasComponent() const
Checks if a component of type T exists.
Definition Entity.h:142
const std::vector< std::unique_ptr< Components::Logic > > & getAllComponents() const
Gets all components on this entity.
Definition Entity.h:150
void tick(double deltaTime) override
Executes every frame if tick is enabled.
entt::entity data_
Definition Entity.h:190
void removeComponent(Components::Logic *component)
Removes a specific component instance.
Definition Entity.h:106
bool canEverTick() const
Tells if this entity can ever tick.
uuids::uuid getUUID() const
Getter for the UUID of this entity.
Definition Entity.h:177
std::vector< T * > getComponents() const
Returns all components of type T.
Definition Entity.h:92
T * getComponent() const
Returns the first component of type T found.
Definition Entity.h:77
void setTickPriority(int32_t priority)