TazGraph Project v0.1.0
Loading...
Searching...
No Matches
GECSManager.h
1#pragma once
2
3#include "GECS.h"
4#include "../../Grid/Grid.h"
5//#include "../../DataManager/DataManager.h"
6
7#include "../../Threader/Threader.h"
8
9#include "./SimulationStep.h"
10
11#include <regex>
12#include <filesystem>
13#include <shared_mutex>
14#include "Command.h"
15
16namespace fs = std::filesystem;
17
18
20{
21private:
22 mutable std::shared_mutex entities_mtx;
23 std::mutex refresh_mtx;
24
25 Threader* _threader = nullptr;
26 int lastEntityId = 0;
27 int negativeEntityId = -1;
30 std::unordered_map<EntityID, std::unique_ptr<Entity>> entities;
31
32 std::array<std::vector<Entity*>, maxGroups> groupedEmptyEntities;
33 std::array<std::vector<Entity*>, maxGroups> groupedNodeEntities;
34 std::array<std::vector<Entity*>, maxGroups> groupedLinkEntities;
35
36 std::vector<Entity*> visible_emptyEntities;
37 std::vector<Entity*> visible_nodes;
38 std::vector<Entity*> visible_links;
39
40 std::array<std::vector<Entity*>, maxGroups> visible_groupedEmptyEntities;
41 std::array<std::vector<Entity*>, maxGroups> visible_groupedNodeEntities;
42 std::array<std::vector<Entity*>, maxGroups> visible_groupedLinkEntities;
43
44 bool _update_active_entities = false;
45public:
46 // Simdump
47 std::list<SimulationStep> steps;
48 int currentStep = 0;
49
50 // Command Pattern
51 std::stack<std::unique_ptr<Command>> undoStack;
52
53 std::vector<EntityID> movedNodes;
54 std::mutex movedNodesMutex;
55
56 bool idTextEnabled = false;
57
58 bool arrowheadsEnabled = false;
59 bool last_arrowheadsEnabled = false;
60
61 std::unordered_map<std::string, std::vector<std::string>> componentNames;
62
63 std::unique_ptr<Grid> grid;
64
65 Manager() {}
66
67 ~Manager() { _threader = nullptr; }
68
69 void setThreader(Threader& mthreader) {
70 _threader = &mthreader;
71 }
72
73 void update(float deltaTime = 1.0f)
74 {
76
77 if (_threader && !_threader->t_queue.shuttingDown) {
78
80 //? THIS MAY CAUSE ERRORS, IF REMOVE LINK FROM CELL AND OTHER LINK THAT HAS THAT CELL IN SEARCH
81 //? WILL PUMP IN AN EMPTY ELEMENT OR THE SIZE WILL BE SMALLER FOR THAT LINK TO FIND ELEMENT
82 for (auto& e : movedNodes) {
83 auto* ent = dynamic_cast<NodeEntity*>(getEntityFromId(e));
84
85 for (auto& linkId : ent->getInLinks()) {
86 auto* linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(linkId));
87
88 linkEntity->cellUpdate();
89 }
90 for (auto& link : ent->getOutLinks()) {
91 auto* linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(link));
92
93 linkEntity->cellUpdate();
94 }
95 }
96
97 _threader->parallel(movedNodes.size(), [&](int start, int end) {
98 for (int i = start; i < end; i++) {
99 auto* ent = dynamic_cast<NodeEntity*>(getEntityFromId(movedNodes[i]));
100
101 for (auto& link : ent->getInLinks()) {
102 auto* linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(link));
103
104 linkEntity->updateConnection();
105 }
106 }
107 });
108
109 _threader->parallel(movedNodes.size(), [&](int start, int end) {
110 for (int i = start; i < end; i++) {
111 auto* ent = dynamic_cast<NodeEntity*>(getEntityFromId(movedNodes[i]));
112
113 for (auto& link : ent->getOutLinks()) {
114 auto* linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(link));
115
116 // skip inner links for now
117 if (arrowheadsEnabled &&
118 linkEntity->type == LinkEntity::ConnectionType::GHOST_PORT_TO_PORT)
119 continue;
120
121 linkEntity->updateConnection();
122 }
123 }
124 });
125
126 _threader->parallel(movedNodes.size(), [&](int start, int end) {
127 for (int i = start; i < end; i++) {
128 auto* ent = dynamic_cast<NodeEntity*>(getEntityFromId(movedNodes[i]));
129
130 if (arrowheadsEnabled) {
131 // loop through inner links
132 // also loop through innner links of adjacent nodes
133 for (auto& link : ent->getOutLinks()) {
134 auto* linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(link));
135
136 if (
137 linkEntity->type == LinkEntity::ConnectionType::GHOST_PORT_TO_PORT)
138 {
139 linkEntity->updateConnection();
140 }
141 else {
142 NodeEntity* toNode = dynamic_cast<NodeEntity*>(getEntityFromId(linkEntity->toId));
143
144 for (auto& link : toNode->getOutLinks()) {
145 auto* adjacent_linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(link));
146
147 if (
148 adjacent_linkEntity->type == LinkEntity::ConnectionType::GHOST_PORT_TO_PORT)
149 {
150 adjacent_linkEntity->updateConnection();
151 }
152 }
153 }
154 }
155 // also loop through innner links of adjacent nodes
156 for (auto& link : ent->getInLinks()) {
157 auto* linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(link));
158
159 if (
160 linkEntity->type != LinkEntity::ConnectionType::GHOST_PORT_TO_PORT)
161 {
162 NodeEntity* fromNode = dynamic_cast<NodeEntity*>(getEntityFromId(linkEntity->fromId));
163
164 for (auto& link : fromNode->getOutLinks()) {
165 auto* adjacent_linkEntity = dynamic_cast<LinkEntity*>(getEntityFromId(link));
166
167 if (
168 adjacent_linkEntity->type == LinkEntity::ConnectionType::GHOST_PORT_TO_PORT)
169 {
170 adjacent_linkEntity->updateConnection();
171 }
172 }
173 }
174 }
175 }
176 }
177 });
178
179 movedNodes.clear();
180
182 _threader->parallel(visible_emptyEntities.size(), [&](int start, int end) {
183 for (int i = start; i < end; i++) {
184 if (visible_emptyEntities[i]) {
185 visible_emptyEntities[i]->update(deltaTime);
186 }
187 }
188 });
189
190
191 _threader->parallel(visible_nodes.size(), [&](int start, int end) {
192 for (int i = start; i < end; i++) {
193 if (visible_nodes[i]) {
194 visible_nodes[i]->update(deltaTime);
195 }
196 }
197
198 });
199
200
201 _threader->parallel(visible_links.size(), [&](int start, int end) {
202
203 for (int i = start; i < end; i++) {
204 if (visible_links[i]) {
205 visible_links[i]->update(deltaTime);
206 }
207 }
208 });
209 }
210
212 else {
213
214 for (auto& e : visible_emptyEntities) {
215 if (!e->isActive()) continue;
216
217 e->update(deltaTime);
218 }
219
220 for (auto& e : visible_nodes) {
221 if (!e->isActive()) continue;
222
223 e->update(deltaTime);
224
225 }
226
227
228 for (auto& e : visible_links) {
229 if (!e->isActive()) continue;
230
231 e->update(deltaTime);
232 }
233 }
234 }
235
236 // update fully will update all nodes and links in the world
237 void updateFully(float deltaTime = 1.0f)
238 {
239 // the links are updating once since after first update we check wether the nodes are aligned with the ownerCells
240 for (auto& e : entities) {
241 if (!e.second || !e.second->isActive()) continue;
242
243 e.second->update(deltaTime);
244 }
245 update(deltaTime);
246 }
247
248 void refresh(ICamera* camera = nullptr)
249 {
250
251 if (grid && (camera->hasChanged() || grid->gridLevelChanged())) {
252 bool interceptedCellsChanged = grid->setIntersectedCameraCells(*camera);
253
254 if (interceptedCellsChanged) {
255 aboutTo_updateActiveEntities();
256 }
257 camera->refreshCamera();
258 }
259
260 if (_update_active_entities) {
261 std::scoped_lock lock(refresh_mtx);
262
263 _update_active_entities = false;
264
265 updateVisibleEntities();
266 updateActiveEntities();
267 }
268
269 }
270
271 void aboutTo_updateActiveEntities() {
272 std::scoped_lock lock(refresh_mtx);
273 _update_active_entities = true;
274 }
275
276 void updateActiveEntities();
277
278 void updateVisibleEntities();
279
280 void AddToGroup(EmptyEntity* mEntity, Group mGroup)
281 {
282 groupedEmptyEntities[mGroup].emplace_back(mEntity);
283 aboutTo_updateActiveEntities();
284 }
285
286 void AddToGroup(NodeEntity* mEntity, Group mGroup)
287 {
288 groupedNodeEntities[mGroup].emplace_back(mEntity);
289 aboutTo_updateActiveEntities();
290 }
291
292 void AddLinkToGroup(LinkEntity* mEntity, Group mGroup)
293 {
294 groupedLinkEntities[mGroup].emplace_back(mEntity);
295 aboutTo_updateActiveEntities();
296 }
297
298 const std::unordered_map<EntityID, std::unique_ptr<Entity>>& getEntities() const {
299 return entities;
300 }
301
302 template <typename T>
303 std::vector<Entity*> getVisible() {
304 if constexpr (std::is_same_v<T, EmptyEntity>) {
305 return visible_emptyEntities;
306 }
307 else if constexpr (std::is_same_v<T, NodeEntity>) {
308 return visible_nodes;
309 }
310 else if constexpr (std::is_same_v<T, LinkEntity>) {
311 return visible_links;
312 }
313 else {
314 static_assert(sizeof(T) == 0, "Unsupported entity type.");
315 }
316 }
317
318 template <typename T>
319 std::vector<Entity*>& getVisibleGroup(Group mGroup) {
320 if constexpr (std::is_same_v<T, EmptyEntity>) {
321 return visible_groupedEmptyEntities[mGroup];
322 }
323 else if constexpr (std::is_same_v<T, NodeEntity>) {
324 return visible_groupedNodeEntities[mGroup];
325 }
326 else if constexpr (std::is_same_v<T, LinkEntity>) {
327 return visible_groupedLinkEntities[mGroup];
328 }
329 else {
330 static_assert(sizeof(T) == 0, "Unsupported entity type.");
331 }
332 }
333
334 template <typename T>
335 void getAllTypeEntities(std::vector<Entity*>& output) {
336 output.clear();
337
338 if constexpr (std::is_same_v<T, EmptyEntity>) {
339 for (auto& groupPair : groupedEmptyEntities) {
340 output.insert(output.end(), groupPair.begin(), groupPair.end());
341 }
342 }
343 else if constexpr (std::is_same_v<T, NodeEntity>) {
344 for (auto& groupPair : groupedNodeEntities) {
345 output.insert(output.end(), groupPair.begin(), groupPair.end());
346 }
347 }
348 else if constexpr (std::is_same_v<T, LinkEntity>) {
349 for (auto& groupPair : groupedLinkEntities) {
350 output.insert(output.end(), groupPair.begin(), groupPair.end());
351 }
352 }
353 else {
354 static_assert(sizeof(T) == 0, "Unsupported entity type.");
355 }
356 }
357
358 template <typename T>
359 std::vector<Entity*>& getGroup(Group mGroup) {
360 if constexpr (std::is_same_v<T, EmptyEntity>) {
361 return groupedEmptyEntities[mGroup];
362 }
363 else if constexpr (std::is_same_v<T, NodeEntity>) {
364 return groupedNodeEntities[mGroup];
365 }
366 else if constexpr (std::is_same_v<T, LinkEntity>) {
367 return groupedLinkEntities[mGroup];
368 }
369 else if constexpr (std::is_same_v<T, Entity>) {
370 return groupedLinkEntities[mGroup];
371 }
372 else {
373 static_assert(sizeof(T) == 0, "Unsupported entity type.");
374 }
375 }
376
377 inline std::vector<Entity*> getGroup_All(Group mGroup) {
378 std::vector<Entity*> result;
379
380 auto& empties = groupedEmptyEntities[mGroup];
381 auto& nodes = groupedNodeEntities[mGroup];
382 auto& links = groupedLinkEntities[mGroup];
383
384 result.reserve(empties.size() + nodes.size() + links.size());
385
386 result.insert(result.end(), empties.begin(), empties.end());
387 result.insert(result.end(), nodes.begin(), nodes.end());
388 result.insert(result.end(), links.begin(), links.end());
389
390 return result;
391 }
392
393 template <typename T, typename... TArgs>
394 T& addEntityNoId(TArgs&&... mArgs)
395 {
396 T* e(new T(*this, std::forward<TArgs>(mArgs)...));
397 {
398 std::unique_lock lock(entities_mtx);
399 e->setId(negativeEntityId--);
400 std::unique_ptr<T> uPtr{ e };
401 entities.emplace(e->getId(), std::move(uPtr));
402 }
403
404 e->onCreation(); //? dont change its position, huge loading times
405
406 aboutTo_updateActiveEntities();
407
408 return *e;
409 }
410
411 template <typename T, typename... TArgs>
412 T& addEntity(TArgs&&... mArgs)
413 {
414 T* e(new T(*this, std::forward<TArgs>(mArgs)...));
415 {
416 std::unique_lock lock(entities_mtx);
417 e->setId(lastEntityId++);
418 std::unique_ptr<T> uPtr{ e };
419 entities.emplace(e->getId(), std::move(uPtr));
420 }
421
422 e->onCreation();
423
424 aboutTo_updateActiveEntities();
425
426 return *e;
427 }
428
429 template <typename T, typename... TArgs>
430 T& addEntityWithId(EntityID customId, TArgs&&... mArgs)
431 {
432 T* e(new T(*this, std::forward<TArgs>(mArgs)...));
433
434 {
435 std::unique_lock lock(entities_mtx);
436 e->setId(customId);
437 std::unique_ptr<T> uPtr{ e };
438 entities.emplace(customId, std::move(uPtr));
439 }
440
441 e->onCreation();
442
443 aboutTo_updateActiveEntities();
444 return *e;
445 }
446
447 template <typename T, typename... TArgs>
448 T& addEntityFromParent(Entity* pEntity, const char* newID = "", TArgs&&... mArgs)
449 {
450 T* e(new T(*this, std::forward<TArgs>(mArgs)...));
451 {
452 std::unique_lock lock(entities_mtx);
453
454 if ((newID != NULL) && (newID[0] != '\0')) {
455 e->setId((pEntity ?
456 EntityIDUtils::toString(pEntity->getId())
457 : "")
458 + "-" + newID
459 );
460 }
461 else {
462 e->setId((pEntity ?
463 EntityIDUtils::toString(pEntity->getId())
464 : "")
465 + "-" + EntityIDUtils::toString(negativeEntityId--)
466 );
467 }
468
469 std::unique_ptr<T> uPtr{ e };
470 entities.emplace(e->getId(), std::move(uPtr));
471 }
472
473 aboutTo_updateActiveEntities();
474
475 return *e;
476 }
477
478 void resetEntityId() {
479 lastEntityId = 0;
480 }
481
482 void setNewLastEntityId() {
483 std::unique_lock lock(entities_mtx);
484
485 int maxIntId = std::numeric_limits<int>::min();
486 bool foundInt = false;
487
488 for (const auto& [id, ptr] : entities)
489 {
490 if (std::holds_alternative<int>(id)) {
491 int value = std::get<int>(id);
492 if (value > maxIntId) {
493 maxIntId = value;
494 foundInt = true;
495 }
496 }
497 }
498
499 if (foundInt)
500 lastEntityId = maxIntId + 1;
501 else
502 lastEntityId = 0; // or whatever default you want
503 }
504
505 inline Entity* getEntityFromId(EntityID mId) {
506 std::shared_lock lock(entities_mtx);
507 return entities[mId].get();
508 }
509
510 inline std::vector<Entity*> getEntities_FromIds(std::vector<EntityID> mIds) {
511 std::shared_lock lock(entities_mtx);
512
513 std::vector<Entity*> result;
514 result.reserve(mIds.size());
515
516 for (EntityID id : mIds) {
517 if (entities.contains(id)) {
518 result.push_back(entities[id].get());
519 }
520 }
521
522 return result;
523 }
524
525 //? Probably dont need this
526 //inline std::vector<EntityID> getIds_FromEntities(std::vector<Entity*> mEntities) {
527 // std::shared_lock lock(entities_mtx);
528
529 // std::vector<EntityID> result;
530 // result.reserve(mEntities.size());
531
532 // for (Entity* e : mEntities) {
533 // result.push_back(e->getId());
534 // }
535
536 // return result;
537 //}
538
539 bool hasEntity(EntityID mId) {
540 std::shared_lock lock(entities_mtx);
541 return entities.contains(mId);
542 }
543
544 void clearAllEntities() {
545 for (auto& group : groupedNodeEntities) {
546 group.clear();
547 }
548 for (auto& group : groupedLinkEntities) {
549 group.clear();
550 }
551 {
552 std::unique_lock lock(entities_mtx);
553 entities.clear();
554 }
555 }
556
557 void removeAllEntites() {
558 for (auto group : groupNames) {
559 removeAllEntitiesFromGroup(group.first);
560 removeAllEntitiesFromLinkGroup(group.first);
561 }
562 }
563
564 void removeAllEntitiesFromGroup(Group mGroup) {
565 auto& entitiesInGroup = groupedNodeEntities[mGroup];
566
567 for (auto& entity : entitiesInGroup) {
568 entity->destroy();
569 }
570 }
571
572 void removeAllEntitiesFromEmptyGroup(Group mGroup) {
573 auto& entitiesInGroup = groupedEmptyEntities[mGroup];
574
575 for (auto& entity : entitiesInGroup) {
576 entity->destroy();
577 }
578 }
579
580 void removeAllEntitiesFromLinkGroup(Group mGroup) {
581 auto& entitiesInGroup = groupedLinkEntities[mGroup];
582
583 for (auto& entity : entitiesInGroup) {
584 entity->destroy();
585 }
586 }
587
588 std::vector<EntityID> adjacentEntities(Entity* mainEntity, Group group) {
589 std::vector<EntityID> nearbyEntities;
590
591 auto adjacentCells = grid->getAdjacentCells(*mainEntity, grid->getGridLevel());
592
593 for (Cell* adjCell : adjacentCells) {
594 for (auto& neighbor : adjCell->nodes) {
595 if (getEntityFromId(neighbor)->hasGroup(group) && (getEntityFromId(neighbor) != mainEntity)) {
596 nearbyEntities.push_back(neighbor);
597 }
598 }
599 }
600
601 return nearbyEntities;
602 }
603
604 enum groupLabels : std::size_t
605 {
606 //back
607 groupBackgroundLayer,
608 panelBackground,
609
610 groupGridLinks,
611
612 groupSelectedEntities,
613
614 groupDebugBoxEntities,
615 groupDebugRectangleEntities,
616 //action
617 groupLinks_0,
618 groupGroupLinks_0,
619 groupGroupLinks_1,
620
621 groupPathLinks,
622
623 groupPathInnerLinks,
624
625 groupPathLinksHolder,
626
627 groupArrowHeads_0,
628
629 groupNodes_0,
630 groupGroupNodes_0,
631 groupGroupNodes_1,
632
633 groupMinimapNodes,
634
635 groupColliders,
636
637 groupEmpties,
638 groupSphereEmpties,
639
640 groupWireframeSphereEmpties,
641
642 groupRenderSprites,
643
644 groupPorts,
645 groupPortSlots,
646
647 //fore
648 textLabels,
649 __COUNT__
650 };
651
652
653 std::unordered_map<Group, std::string> groupNames = {
654 {groupBackgroundLayer, "groupBackgroundLayer" },
655 {panelBackground, "panelBackground"},
656
657 { groupGridLinks,"groupGridLinks" },
658
659 { groupSelectedEntities, "groupSelectedEntities" },
660
661 {groupDebugBoxEntities, "groupDebugBoxEntities"},
662 {groupDebugRectangleEntities, "groupDebugRectangleEntities"},
663 //action
664 { groupLinks_0,"groupLinks_0" },
665 {groupGroupLinks_0, "groupGroupLinks_0"},
666 {groupGroupLinks_1, "groupGroupLinks_1"},
667
668 {groupPathLinks, "groupPathLinks"},
669
670 {groupPathInnerLinks, "groupPathInnerLinks"},
671
672 {groupPathLinksHolder, "groupPathLinksHolder"},
673
674 {groupArrowHeads_0, "groupArrowHeads_0"},
675
676 { groupNodes_0,"groupNodes_0" },
677 { groupGroupNodes_0, "groupGroupNodes_0"},
678 { groupGroupNodes_1, "groupGroupNodes_1"},
679
680 { groupMinimapNodes,"groupMinimapNodes" },
681
682 { groupEmpties,"groupEmpties" },
683 { groupSphereEmpties,"groupSphereEmpties" },
684
685 { groupWireframeSphereEmpties,"groupWireframeSphereEmpties" },
686
687 { groupColliders,"groupColliders" },
688 { groupRenderSprites,"groupRenderSprites" },
689 { groupPorts,"groupPorts" },
690 { groupPortSlots,"groupPortSlots" },
691
692 //fore
693 { textLabels,"textLabels" },
694 };
695
697 std::size_t nextGroup = groupLabels::__COUNT__;
698
699 void addGroup(std::string groupName) {
700 auto newGroup = nextGroup++;
701 groupNames.insert(std::make_pair(newGroup, groupName));
702 }
703
704 std::string getGroupName(Group mGroup) const;
705
706 void scanComponentNames(const std::string& folderPath);
707
708 void setComponentNames();
709
710 std::vector<Entity*> collectVisibleEntities(
711 std::initializer_list<Manager::groupLabels> groupNames,
712 Taz::EntityType type);
713
714 std::vector<Entity*> collectEntities(
715 std::initializer_list<Manager::groupLabels> groupNames,
716 Taz::EntityType type);
717
718 bool entities_AllSameType(std::vector<Entity*> entities);
719
720};
Definition GECSEntity.h:7
Definition GECS.h:224
Definition ICamera.h:10
Definition GECSEntity.h:108
Definition GECSManager.h:20
std::size_t nextGroup
dynamically add groups with Enum!
Definition GECSManager.h:697
void update(float deltaTime=1.0f)
Definition GECSManager.h:73
Definition GECSEntity.h:40
Definition CellEntity.h:6
Definition Threader.h:84