CoriEngine
Loading...
Searching...
No Matches
Scene.hpp
Go to the documentation of this file.
1#pragma once
2#include "Entity.hpp"
5#include "Physics/Physics.hpp"
6#include "EntityView.hpp"
7#include "Core/Time.hpp"
8#include "Systems/Concept.hpp"
9#include <ska_sort.hpp>
10
11namespace Cori {
12 namespace Core {
13 class Layer;
14 }
15 namespace World {
20 class Scene : public Profiling::Trackable<Scene> {
21 public:
22 ~Scene();
23
25
26 template<typename... T>
27 Entity CreateEntity(const std::string& name) {
28 entt::entity entity = m_Registry.create();
29 auto& nameComp = m_Registry.emplace<Components::Entity::Name>(entity);
30 nameComp.m_Name = name;
32 ((m_Registry.emplace<T>(entity)), ...);
33 const auto& uuidComp = m_Registry.emplace<Components::Entity::UUID>(entity);
34 m_UUIDToEntity.insert({ uuidComp.m_UUID, entity });
35 CORI_CORE_TRACE_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "Created Entity With ID: {}, Version: {}, Name: {}", entt::to_integral(entity), entt::to_version(entity), name);
36 Entity e = entt::handle{m_Registry, entity};
38 e.AddComponent<Internal::SceneID>(m_SceneID);
39 return e;
40 }
41
42 void DestroyEntity(Entity entity);
43
44 std::expected<void, Core::CoriError<>> AddEntityToCache(const Entity entity, const Utility::StringHash32 key);
45 [[nodiscard]] std::expected<Entity, Core::CoriError<>> GetEntityFromCache(const Utility::StringHash32 key);
47
48 template<typename... T>
49 [[nodiscard]] std::expected<Entity, Core::CoriError<>> FindEntity(const std::string& name) {
50 CORI_CORE_WARN_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "Performing slow scene-wide search for entity named: '{}'. Consider caching it. This shouldn't be called every frame! Be aware.", name);
51 const auto view = m_Registry.view<Components::Entity::Name, T...>();
52 for (auto entity : view) {
53 if (name == view.template get<Components::Entity::Name>(entity).m_Name) {
54 return Entity{ { m_Registry, entity } };
55 }
56 }
57 return std::unexpected(Core::CoriError("No entity found with the specified name."));
58 }
59
60 template<typename... T>
61 [[nodiscard]] auto StaticView() {
62 auto view = m_Registry.view<T...>();
63 return StaticEntityView(view, m_Registry);
64 }
65
66 template<typename... T, typename... ExcludeT>
67 [[nodiscard]] auto StaticView(Exclude<ExcludeT...>) {
68 auto view = m_Registry.view<T...>(entt::exclude<ExcludeT...>);
69 return StaticEntityView(view, m_Registry);
70 }
71
74 }
75
76 // untested and unused for now
77 //template<typename... T, typename Func>
78 //void ForEach(Func func) {
79 // m_Registry.view<T...>().each(func);
80 //}
81
82 template<typename T, typename... Args>
83 T& AddContextComponent(Args&&... args) {
84 return m_Registry.ctx().emplace<T>(std::forward<Args>(args)...);
85 }
86
87 template<typename T>
88 [[nodiscard]] T& GetContextComponent() {
90 CORI_CORE_FATAL_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "Failed to get context component '{}' from scene '{}'.", CORI_CLEAN_TYPE_NAME(T), m_Name);
91 }
92 return m_Registry.ctx().get<T>();
93 }
94
95 template<typename T>
96 [[nodiscard]] const T& GetContextComponent() const {
98 CORI_CORE_FATAL_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "Failed to get const context component '{}' from scene '{}'.", CORI_CLEAN_TYPE_NAME(T), m_Name);
99 }
100 return m_Registry.ctx().get<const T>();
101 }
102
103 template<typename T>
104 [[nodiscard]] bool HasContextComponent() const {
105 return m_Registry.ctx().contains<T>();
106 }
107
108 template<typename T>
110 m_Registry.ctx().erase<T>();
111 }
112
113 template <typename T, typename... Args> requires IsSystem<T>
114 void RegisterSystem(Args&&... args) {
115 if (m_RegisteredSystems.contains(std::type_index(typeid(T)))) {
116 CORI_CORE_WARN_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "Trying to register '{}' twice for scene '{}', you can't register a system twice.", CORI_CLEAN_TYPE_NAME(T), m_Name);
117 return;
118 }
119
120 std::shared_ptr<T> system = std::make_shared<T>();
121 system->SetOwnerScene(this);
122 const bool success = system->Create(std::forward<Args>(args)...);
123 if (success) {
124 auto systemType = std::type_index(typeid(T));
125 m_SystemPriority.emplace_back(T::Priority, systemType);
126 ska_sort(
127 m_SystemPriority.begin(),
128 m_SystemPriority.end(),
129 [](const std::pair<SystemPriority, std::type_index>& entry) -> SystemPriority {
130 return entry.first;
131 });
132
133 m_RegisteredSystems.insert({ systemType, std::move(system) });
134 CORI_CORE_DEBUG_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "System '{}' has been registered for scene '{}'", CORI_CLEAN_TYPE_NAME(T), m_Name);
135 return;
136 }
137
138 CORI_CORE_DEBUG_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "Failed to register System '{}' with scene '{}', Create returned false.", CORI_CLEAN_TYPE_NAME(T), m_Name);
139 }
140
141 template <typename T> requires IsSystem<T>
143 if (m_RegisteredSystems.contains(std::type_index(typeid(T)))) {
144 m_RegisteredSystems.erase(std::type_index(typeid(T)));
145 CORI_CORE_DEBUG_TAGGED({ Logger::Tags::World::Self, Logger::Tags::World::Scene::Self }, "System '{}' has been unregistered for scene '{}'", CORI_CLEAN_TYPE_NAME(T), m_Name);
146 }
147 }
148
149 template <typename T> requires IsSystem<T>
150 std::expected<std::weak_ptr<T>, Core::CoriError<>> GetSystem() {
151 if (m_RegisteredSystems.contains(std::type_index(typeid(T)))) {
152 return std::weak_ptr<T>(std::static_pointer_cast<T>(m_RegisteredSystems[std::type_index(typeid(T))]));
153 }
154
155 return std::unexpected(Core::CoriError("Failed to get system, system is not registered."));
156 }
157
159 return m_ActiveCamera;
160 }
161
162 [[nodiscard]] const Graphics::CameraController& GetCameraController() const {
163 return m_ActiveCamera;
164 }
165
166 [[nodiscard]] std::string_view GetName() const {
167 return m_Name;
168 }
169
170 [[nodiscard]] uint32_t GetSceneID() const {
171 return m_SceneID;
172 }
173
174 void BeginRender();
175
176 void EndRender();
177
178 protected:
179 //friend Core::Layer;
180 friend class SceneHandle;
181 friend class SceneManager;
182 [[nodiscard]] bool OnBind();
183 [[nodiscard]] bool OnUnbind();
184
185 void OnUpdate(Core::GameTimer& gameTimer);
186
187 void OnTickUpdate(Core::GameTimer& gameTimer);
188
189 void OnImGuiRender(Core::GameTimer& gameTimer);
190
191 [[nodiscard]] static std::shared_ptr<Scene> Create(std::string name);
192
193 entt::registry m_Registry;
194 private:
195 //friend class Entity;
196 explicit Scene(std::string name);
197
198 uint32_t m_SceneID;
199
200 Graphics::CameraController m_ActiveCamera;
201
202 std::string m_Name;
203
204 std::unordered_map<std::type_index, std::shared_ptr<System>> m_RegisteredSystems;
205 std::vector<std::pair<SystemPriority, std::type_index>> m_SystemPriority;
206
207 std::unordered_map<Core::UUID, entt::entity> m_UUIDToEntity;
208 std::unordered_map<Utility::StringHash32, entt::entity> m_EntityCache;
209
210 };
211 }
212}
#define CORI_CLEAN_TYPE_NAME(tn)
#define CORI_CORE_DEBUG_TAGGED(...)
Definition Logger.hpp:1026
#define CORI_CORE_FATAL_TAGGED(...)
Definition Logger.hpp:1040
#define CORI_CORE_TRACE_TAGGED(...)
Definition Logger.hpp:1025
#define CORI_CORE_WARN_TAGGED(...)
Definition Logger.hpp:1038
Custom error class mainly used in std::expected.
Definition Error.hpp:27
A GameTimer is responsible for managing everything that is connected with time, ticks,...
Definition Time.hpp:8
An abstract class that is ment to be used as a template for defining layers.
Definition Layer.hpp:13
A class that is used to manipulate Camera of the Scene. Each Scene has one of those.
For InstanceMetrics to work with a type it should derive from this.
Definition Trackable.hpp:29
A wrapper for an EnTT runtime view that provides an iterator to access Entity instances directly.
Entities are the essential part of WorldSystem.
Definition Entity.hpp:25
T & AddComponent(Args &&... args)
Adds a component to the entity.
Definition Entity.hpp:39
friend class SceneHandle
Definition Scene.hpp:180
void RegisterSystem(Args &&... args)
Definition Scene.hpp:114
std::expected< void, Core::CoriError<> > AddEntityToCache(const Entity entity, const Utility::StringHash32 key)
Definition Scene.cpp:31
T & AddContextComponent(Args &&... args)
Definition Scene.hpp:83
static std::shared_ptr< Scene > Create(std::string name)
Definition Scene.cpp:9
std::expected< std::weak_ptr< T >, Core::CoriError<> > GetSystem()
Definition Scene.hpp:150
friend class SceneManager
Definition Scene.hpp:181
std::expected< Entity, Core::CoriError<> > FindEntity(const std::string &name)
Definition Scene.hpp:49
auto StaticView(Exclude< ExcludeT... >)
Definition Scene.hpp:67
entt::registry m_Registry
Definition Scene.hpp:193
void OnTickUpdate(Core::GameTimer &gameTimer)
Definition Scene.cpp:81
T & GetContextComponent()
Definition Scene.hpp:88
DynamicEntityView DynamicView()
Definition Scene.hpp:72
Entity CreateEntity(const std::string &name)
Definition Scene.hpp:27
void RemoveEntityFromCache(const Utility::StringHash32 key)
Definition Scene.cpp:52
Entity CreateBlankEntity()
Definition Scene.cpp:24
std::string_view GetName() const
Definition Scene.hpp:166
Graphics::CameraController & GetCameraController()
Definition Scene.hpp:158
void UnregisterSystem()
Definition Scene.hpp:142
void BeginRender()
Definition Scene.cpp:93
void RemoveContextComponent()
Definition Scene.hpp:109
void DestroyEntity(Entity entity)
Definition Scene.cpp:61
void OnUpdate(Core::GameTimer &gameTimer)
Definition Scene.cpp:71
const T & GetContextComponent() const
Definition Scene.hpp:96
auto StaticView()
Definition Scene.hpp:61
std::expected< Entity, Core::CoriError<> > GetEntityFromCache(const Utility::StringHash32 key)
Definition Scene.cpp:41
void OnImGuiRender(Core::GameTimer &gameTimer)
Definition Scene.cpp:87
bool HasContextComponent() const
Definition Scene.hpp:104
const Graphics::CameraController & GetCameraController() const
Definition Scene.hpp:162
uint32_t GetSceneID() const
Definition Scene.hpp:170
A wrapper for an EnTT compile-time view that provides an iterator to access Entity instances directly...
Core systems of the engine are here.
entt::hashed_string::hash_type StringHash32
Anything connected to WorldSystem (ECS) is in this namespace.
uint16_t SystemPriority
Definition Concept.hpp:5
Global engine namespace.
static constexpr char Self[]
Definition Logger.hpp:122
static constexpr char Self[]
Definition Logger.hpp:119
Every Entity has a hierarchy component by default, it's essential for entity hierarchy system.
Every Entity by default has a name component, it holds a non-unique entity name. Just holds the data,...
Every Entity has a transform component by default, essential for rendering.
Every Entity by default has a UUID component, mostly unused for now.
Helper to exclude certain components from a static view.