TazGraph Project v0.1.0
Loading...
Searching...
No Matches
GECS.h
1#pragma once
2
3#include "../../../pch.h"
4
5#include "../../Window/Window.h"
6
7#include "../../PythonEngine/PythonEngine.h"
8
9inline PythonInterpreter& pythonInter = PythonInterpreter::getInstance();
10
11#define CULLING_OFFSET 100
12
13class BaseComponent;
14class Entity;
15class EmptyEntity;
16class NodeEntity;
17class LinkEntity;
18
19class Manager;
20class Window;
21struct Cell;
22
23using ComponentID = std::size_t;
24using Group = std::size_t;
25
26using layer = std::size_t;
27
28namespace Layer {
29 enum layerIndexes : std::size_t
30 {
31 action,
32 menubackground
33 };
34}
35
36namespace Taz {
37 enum EntityType
38 {
39 Unknown,
40 Empty,
41 Node,
42 Link,
44 };
45}
46
47
48const std::unordered_map<layer, float> layerNames = {
49 {Layer::action, 0.0f},
50 {Layer::menubackground, -100.0f}
51
52};
53
54inline float getLayerDepth(layer mLayer) {
55 return layerNames.at(mLayer);
56}
57
58
59inline ComponentID getNewComponentTypeID()
60{
61 static ComponentID lastID = 0u;
62 return lastID++;
63}
64
65inline ComponentID getNewNodeComponentTypeID()
66{
67 static ComponentID lastID_nodeC = 0u;
68 return lastID_nodeC++;
69}
70
71inline ComponentID getNewLinkComponentTypeID()
72{
73 static ComponentID lastID_linkC = 0u;
74 return lastID_linkC++;
75}
76
77
78template <typename T> inline ComponentID GetComponentTypeID() noexcept
79{
80 static ComponentID typeID = getNewComponentTypeID(); // typeID is unique for each function type T and only initialized once.
81 return typeID;
82}
83
84template <typename T> inline ComponentID GetNodeComponentTypeID() noexcept
85{
86 static ComponentID typeID = getNewNodeComponentTypeID(); // typeID is unique for each function type T and only initialized once.
87 return typeID;
88}
89
90template <typename T> inline ComponentID GetLinkComponentTypeID() noexcept
91{
92 static ComponentID typeID = getNewLinkComponentTypeID(); // typeID is unique for each function type T and only initialized once.
93 return typeID;
94}
95
96constexpr std::size_t maxComponents = 24;
97constexpr std::size_t maxGroups = 32;
98
99using ComponentBitSet = std::bitset<maxComponents>;
100using GroupBitSet = std::bitset<maxGroups>;
101
102using ComponentArray = std::array<BaseComponent*, maxComponents>;
103
105{
106public:
107 bool modifyPosition = false;
108
109 ComponentID id = 0u;
110
111 virtual void init() {}
112 virtual void update(float deltaTime) {}
113 virtual void draw(size_t e_index, PlaneModelRenderer& batch, TazGraphEngine::Window& window) {}
114 virtual void draw(size_t e_index, LineRenderer& batch, TazGraphEngine::Window& window) {}
115 virtual void draw(size_t e_index, PlaneColorRenderer& batch, TazGraphEngine::Window& window) {}
116 virtual void draw(size_t e_index, LightRenderer& batch, TazGraphEngine::Window& window) {}
117
118 virtual std::string GetComponentName() { return ""; };
119
120 virtual void showGUI(std::vector<BaseComponent*> otherComponents = {}) {
121 ImGui::Text("MyComponent Properties:");
122 };
123
124 virtual void showGUI(std::vector<BaseComponent*> otherComponents, std::vector<Entity*> otherEntities) {
125 ImGui::Text("MyComponent Properties:");
126 };
127
128 virtual ~BaseComponent() {}
129};
130
131class Component : public BaseComponent {
132public:
133 Entity* entity = nullptr;
134};
135
137public:
138 NodeEntity* entity = nullptr;
139};
140
142public:
143 LinkEntity* entity = nullptr;
144};
145
146using EntityID = std::variant<int, std::string>;
147
148namespace EntityIDUtils {
149
150 template<typename>
151 struct always_false : std::false_type {};
152
153
154 inline std::string toString(const EntityID& id) {
155 return std::visit([](auto&& v) -> std::string {
156 using T = std::decay_t<decltype(v)>;
157 if constexpr (std::is_same_v<T, int>) {
158 return std::to_string(v);
159 }
160 else if constexpr (std::is_same_v<T, std::string>) {
161 return v;
162 }
163 else {
164 static_assert(always_false<T>::value, "Unhandled type in EntityID");
165 return {}; // satisfies compiler
166 }
167 }, id);
168 }
169
170 inline EntityID fromString(const std::string& str) {
171 try {
172 // Check if the string consists only of digits (and optional sign)
173 if (!str.empty() && (std::isdigit(str[0]) || (str.size() > 1 && (str[0] == '-') && std::isdigit(str[1])))) {
174 bool allDigits = true;
175 for (size_t i = (str[0] == '-') ? 1 : 0; i < str.size(); ++i) {
176 if (!std::isdigit(static_cast<unsigned char>(str[i]))) {
177 allDigits = false;
178 break;
179 }
180 }
181
182 if (allDigits) {
183 int value = std::stoi(str);
184 return EntityID{ value };
185 }
186 }
187 }
188 catch (const std::exception&) {
189 }
190
191 // If not a valid integer or conversion failed, treat as string
192 return EntityID{ str };
193 }
194
195 inline bool areEqual(const EntityID& a, const EntityID& b) {
196 // If both hold the same type
197 if (a.index() == b.index()) {
198 if (std::holds_alternative<int>(a))
199 return std::get<int>(a) == std::get<int>(b);
200 else
201 return std::get<std::string>(a) == std::get<std::string>(b);
202 }
203
204 // If types differ (int vs string), try numeric-string conversion
205 try {
206 if (std::holds_alternative<int>(a) && std::holds_alternative<std::string>(b)) {
207 return std::to_string(std::get<int>(a)) == std::get<std::string>(b) ||
208 std::stoi(std::get<std::string>(b)) == std::get<int>(a);
209 }
210 if (std::holds_alternative<std::string>(a) && std::holds_alternative<int>(b)) {
211 return std::get<std::string>(a) == std::to_string(std::get<int>(b)) ||
212 std::stoi(std::get<std::string>(a)) == std::get<int>(b);
213 }
214 }
215 catch (const std::exception&) {
216 // Conversion failed — treat as not equal
217 }
218
219 return false;
220 }
221}
222
224{
225private:
226 EntityID id = 0;
227protected:
228
229 bool active = true; // false if about to delete
230 bool hidden = false; // true if not do updates
231 ComponentArray componentArray = {};//create 2 arrays, this is for the fast access
232
233 ComponentBitSet componentBitSet;
234 GroupBitSet groupBitSet;
235
236 std::optional<ComponentArray> nodeComponentArray;
237 std::optional<ComponentBitSet> nodeComponentBitSet;
238
239 Entity* parent_entity = nullptr;
240
242public:
243 bool isVertical = false;
244
245 float slotSpacing = 0.0f;
246
248 std::map < EntityID, EntityID> children;
249
250 //? IT IS FORBIDDEN TO USE setId!!!!!!!!!!!!!!!!!!!!!!
251 void setId(EntityID m_id) { id = m_id; }
252
253 EntityID getId() { return id; }
254
255 void hide() {
256 hidden = true;
257 }
258
259 void reveal() {
260 hidden = false;
261 }
262
263 bool isHidden() {
264 return hidden;
265 }
266
267 std::vector<std::unique_ptr<BaseComponent>> components; //create 2 arrays, this is for the concurrent access
268
269 Entity(Manager& mManager) : manager(mManager) {}
270 virtual ~Entity() {}
271
272 virtual void update(float deltaTime)
273 {
274
275 for (auto& c : components) {
276 c->update(deltaTime); // start from which was added first
277 }
278 }
279
280 virtual void cellUpdate() {};
281
282 virtual Cell* getOwnerCell() const { return nullptr; };
283
284 void draw(size_t e_index, PlaneModelRenderer& batch, TazGraphEngine::Window& window)
285 {
286 for (auto& c : components) {
287 c->draw(e_index, batch, window);
288 }
289 }
290 void draw(size_t e_index, LineRenderer& batch, TazGraphEngine::Window& window)
291 {
292 for (auto& c : components) {
293 c->draw(e_index, batch, window);
294 }
295 }
296 void draw(size_t e_index, PlaneColorRenderer& batch, TazGraphEngine::Window& window)
297 {
298 for (auto& c : components) {
299 c->draw(e_index, batch, window);
300 }
301 }
302 void draw(size_t e_index, LightRenderer& batch, TazGraphEngine::Window& window)
303 {
304 for (auto& c : components) {
305 c->draw(e_index, batch, window);
306 }
307 }
308
309 virtual void onCreation() {
310 }
311
312 Entity* getParentEntity() {
313 return parent_entity;
314 }
315
316 void setParentEntity(Entity* pEntity) {
317 parent_entity = pEntity;
318 }
319
320 bool isActive() { return active; }
321 virtual void destroy() {
322 active = false;
323 } // destroy happens relative to the group referencing
324
325 bool hasGroup(Group mGroup)
326 {
327 return groupBitSet[mGroup];
328 }
329
330 virtual void addToGroup(Group mGroup);
331 virtual void removeGroup(Group mGroup);
332
333 template <typename T> bool hasComponent() const
334 {
335 if constexpr (std::is_base_of_v<LinkComponent, T>) {
336 return this && componentBitSet[GetLinkComponentTypeID<T>()];
337 }
338 else if constexpr (std::is_base_of_v<NodeComponent, T>) {
339 return this && nodeComponentBitSet.has_value() && (*nodeComponentBitSet)[GetNodeComponentTypeID<T>()];
340 }
341 return this && componentBitSet[GetComponentTypeID<T>()];
342 }
344 template <typename T, typename... TArgs>
345 T& addComponent(TArgs&&... mArgs)
346 {
347 T* c(new T(std::forward<TArgs>(mArgs)...));
348 if constexpr (std::is_base_of_v<LinkComponent, T>) {
349 std::unique_ptr<LinkComponent> uPtr{ c };
350 components.emplace_back(std::move(uPtr));
351
352 setComponentEntity(c);
353 componentArray[GetLinkComponentTypeID<T>()] = c;
354 componentBitSet[GetLinkComponentTypeID<T>()] = true;
355
356 c->id = GetLinkComponentTypeID<T>();
357
358 c->init();
359 return *c;
360 }
361 else if constexpr (std::is_base_of_v<NodeComponent, T>) {
362 std::unique_ptr<NodeComponent> uPtr{ c };
363 components.emplace_back(std::move(uPtr));
364
365 setComponentEntity(c);
366 (*nodeComponentArray)[GetNodeComponentTypeID<T>()] = c;
367 (*nodeComponentBitSet)[GetNodeComponentTypeID<T>()] = true;
368
369 c->id = GetNodeComponentTypeID<T>();
370
371 c->init();
372 return *c;
373 }
374 else {
375 std::unique_ptr<Component> uPtr{ c };
376 components.emplace_back(std::move(uPtr));
377
378 setComponentEntity(c);
379 componentArray[GetComponentTypeID<T>()] = c;
380 componentBitSet[GetComponentTypeID<T>()] = true;
381
382 c->id = GetComponentTypeID<T>();
383
384 c->init();
385 return *c;
386 }
387
388
389 }
390
391 template <typename T>
392 void removeComponent()
393 {
394 if constexpr (std::is_base_of_v<LinkComponent, T>)
395 {
396 size_t id = GetLinkComponentTypeID<T>();
397 auto it = std::remove_if(components.begin(), components.end(),
398 [id](const std::unique_ptr<BaseComponent>& comp) {
399 return typeid(*comp).hash_code() == typeid(T).hash_code();
400 });
401
402 if (it != components.end())
403 {
404 components.erase(it, components.end());
405 componentArray[id] = nullptr;
406 componentBitSet[id] = false;
407 }
408 }
409 else if constexpr (std::is_base_of_v<NodeComponent, T>)
410 {
411 size_t id = GetNodeComponentTypeID<T>();
412 auto it = std::remove_if(components.begin(), components.end(),
413 [id](const std::unique_ptr<BaseComponent>& comp) {
414 return typeid(*comp).hash_code() == typeid(T).hash_code();
415 });
416
417 if (it != components.end())
418 {
419 components.erase(it, components.end());
420 (*nodeComponentArray)[id] = nullptr;
421 (*nodeComponentBitSet)[id] = false;
422 }
423 }
424 else
425 {
426 size_t id = GetComponentTypeID<T>();
427 auto it = std::remove_if(components.begin(), components.end(),
428 [id](const std::unique_ptr<BaseComponent>& comp) {
429 return typeid(*comp).hash_code() == typeid(T).hash_code();
430 });
431
432 if (it != components.end())
433 {
434 components.erase(it, components.end());
435 componentArray[id] = nullptr;
436 componentBitSet[id] = false;
437 }
438 }
439 }
440
441 virtual void setComponentEntity(Component* c) {
442
443 }
444 virtual void setComponentEntity(NodeComponent* c) {
445
446 }
447 virtual void setComponentEntity(LinkComponent* c) {
448
449 }
450
451 template<typename T> T& GetComponent() const
452 {
453 if constexpr (std::is_base_of_v<LinkComponent, T>) {
454 auto ptr(componentArray[GetLinkComponentTypeID<T>()]);
455 return *static_cast<T*>(ptr);
456 }
457 else if constexpr (std::is_base_of_v<NodeComponent, T>) {
458 auto ptr((*nodeComponentArray)[GetNodeComponentTypeID<T>()]);
459 return *static_cast<T*>(ptr);
460 }
461 else {
462 auto ptr(componentArray[GetComponentTypeID<T>()]);
463 return *static_cast<T*>(ptr);
464 }
465 }
466
467 template<typename T> T* GetComponentPtr()
468 {
469 if constexpr (std::is_base_of_v<LinkComponent, T>) {
470 auto ptr(componentArray[GetLinkComponentTypeID<T>()]);
471 return static_cast<T*>(ptr);
472 }
473 else if constexpr (std::is_base_of_v<NodeComponent, T>) {
474 auto ptr((*nodeComponentArray)[GetNodeComponentTypeID<T>()]);
475 return static_cast<T*>(ptr);
476 }
477 else {
478 auto ptr(componentArray[GetComponentTypeID<T>()]);
479 return static_cast<T*>(ptr);
480 }
481 }
482
483 bool hasComponentByName(const std::string& componentName) {
484 for (auto& component : components) {
485 if (component &&
486 component->GetComponentName() == componentName) {
487 return true;
488 }
489 }
490 return false;
491 }
492
493
494
495 // for when wanting to add new entities from components
496 Manager* getManager() {
497 return &manager;
498 }
499
500 virtual void imgui_print() {}
501
502 virtual void imgui_display() {}
503
504 virtual void removeEntityFromCell() {}
505 virtual void removeFromCell() {};
506 virtual void removeFromCells() {};
507
508};
509
Definition GECS.h:105
Definition GECS.h:131
Definition GECSEntity.h:7
Definition GECSEntityTypesEmpty.h:5
Definition GECS.h:224
std::map< EntityID, EntityID > children
child_index(id) -> real_entity_id
Definition GECS.h:248
Manager & manager
the object doesnt move, so we can have pointer
Definition GECS.h:241
T & addComponent(TArgs &&... mArgs)
have addScript function
Definition GECS.h:345
Definition LightRenderer.h:15
Definition LineRenderer.h:6
Definition GECS.h:141
Definition GECSEntity.h:108
Definition GECSManager.h:20
Definition Minimap.h:14
Definition GECS.h:136
Definition GECSEntity.h:40
Definition GECSEntityTypesNode.h:5
Definition PlaneColorRenderer.h:14
Definition PlaneModelRenderer.h:15
Definition PythonEngine.h:6
Definition Window.h:12
Definition CellEntity.h:6
Definition GECS.h:151