TazGraph Project v0.1.0
Loading...
Searching...
No Matches
GECSEntityTypes.h
1#pragma once
2
3#include "GECSManager.h"
4#include "../Components.h"
5
6
7class Empty : public EmptyEntity {
8
9public:
10
11 Empty(Manager& mManager) : EmptyEntity(mManager) {
12
13 }
14
15 void addGroup(Group mGroup) override {
16 Entity::addGroup(mGroup);
17 manager.AddToGroup(this, mGroup);
18 }
19
20 virtual ~Empty() {
21
22 }
23
24 void update(float deltaTime)
25 {
26 //cellUpdate();
27
28 Entity::update(deltaTime);
29 }
30
31 void cellUpdate() override {
32 if (this->ownerCell) {
33 Cell* newCell = manager.grid->getCell(*this, manager.grid->getGridLevel());
34 if (newCell != this->ownerCell) {
35 // Need to shift the entity
36 removeEntity();
37 manager.grid->addEmpty(this, newCell);
38 }
39 }
40 }
41
42
43
44 void imgui_print() override {
45 glm::vec2 position = this->GetComponent<TransformComponent>().getPosition(); // Make sure Entity class has a getPosition method
46 ImGui::Text("Position: (%.2f, %.2f)", position.x, position.y);
47 }
48
49 void destroy() {
50 Entity::destroy();
51 manager.aboutTo_updateActiveEntities(); // cant have it at destroy in baseclass
52 // may need to also update Visible Entities
53 }
54};
55
56class Node: public NodeEntity {
57private:
58
59
60 std::vector<std::string> messageLog;
61public:
62
63 Node(Manager& mManager) : NodeEntity(mManager) {
64
65
66 }
67
68 void addGroup(Group mGroup) override {
69 Entity::addGroup(mGroup);
70 manager.AddToGroup(this, mGroup);
71 }
72
73 virtual ~Node() {
74
75 }
76
77 void update(float deltaTime)
78 {
79 //cellUpdate();
80
81 Entity::update(deltaTime);
82 }
83
84 void updatePorts(float deltaTime) override {
85 // first set the new position of port based on parent size
86 // then set its bodyPosition through the transformComponent
87
88 TransformComponent* tr = &GetComponent<TransformComponent>();
89
90 glm::vec3 m_position = glm::vec3(-tr->size.x / 2, 0.0f, 0.0f);
91
92 if (children[NodePorts::LEFT]) {
93 children[NodePorts::LEFT]->GetComponent<TransformComponent>().position = m_position;
94 children[NodePorts::LEFT]->update(deltaTime);
95 for (auto& portSlots : children[NodePorts::LEFT]->GetComponent<PortComponent>().portSlots) {
96 portSlots->update(deltaTime);
97 }
98 }
99
100 m_position = glm::vec3(tr->size.x / 2, 0.0f, 0.0f);
101
102 if (children[NodePorts::RIGHT]) {
103 children[NodePorts::RIGHT]->GetComponent<TransformComponent>().position = m_position;
104 children[NodePorts::RIGHT]->update(deltaTime);
105 for (auto& portSlots : children[NodePorts::RIGHT]->GetComponent<PortComponent>().portSlots) {
106 portSlots->update(deltaTime);
107 }
108 }
109
110 m_position = glm::vec3(0.0f, -tr->size.y / 2.0f, 0.0f);
111
112 if (children[NodePorts::TOP]) {
113 children[NodePorts::TOP]->GetComponent<TransformComponent>().position = m_position;
114 children[NodePorts::TOP]->update(deltaTime);
115 for (auto& portSlots : children[NodePorts::TOP]->GetComponent<PortComponent>().portSlots) {
116 portSlots->update(deltaTime);
117 }
118 }
119
120 m_position = glm::vec3(0.0f, tr->size.y / 2.0f, 0.0f);
121
122 if (children[NodePorts::BOTTOM]) {
123 children[NodePorts::BOTTOM]->GetComponent<TransformComponent>().position = m_position;
124 children[NodePorts::BOTTOM]->update(deltaTime);
125 for (auto& portSlots : children[NodePorts::BOTTOM]->GetComponent<PortComponent>().portSlots) {
126 portSlots->update(deltaTime);
127 }
128 }
129 }
130
131 void cellUpdate() override{
132 if (this->ownerCell) {
133 updatePorts(0.0f);
134 //this->GetComponent<TransformComponent>().update(0.0f);
135 Cell* newCell = manager.grid->getCell(*this, manager.grid->getGridLevel());
136 if (newCell != this->ownerCell) {
137 std::scoped_lock lock(manager.movedNodesMutex);
138 removeEntity();
139 manager.grid->addNode(this, newCell);
140
141 manager.movedNodes.push_back(this);
142 }
143 for (auto& link : inLinks) {
144 link->updateArrowHeads();
145 }
146 for (auto& link : outLinks) {
147 link->updateArrowHeads();
148 }
149 }
150 }
151
152 void addMessage(std::string mMessage) override{
153 messageLog.push_back(mMessage);
154 }
155
156 void imgui_print() override {
157 glm::vec2 position = this->GetComponent<TransformComponent>().getPosition(); // Make sure Entity class has a getPosition method
158 ImGui::Text("Position: (%.2f, %.2f)", position.x, position.y);
159
160
161 if (ImGui::BeginTable("GroupsTable", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
162 ImGui::TableSetupColumn("Message Log", ImGuiTableColumnFlags_WidthStretch);
163
164 ImGui::TableHeadersRow();
165 for (auto str : messageLog) {
166 ImGui::TableNextRow();
167 ImGui::TableSetColumnIndex(0);
168 ImGui::Text("%s", str.c_str());
169 }
170 }
171 ImGui::EndTable();
172
173
174 }
175
176 void imgui_display() override {
177 ImGui::Text("Display Info Here Node");
178 }
179
180 void destroy() {
181 Entity::destroy();
182 manager.aboutTo_updateActiveEntities();
183 }
184
185 void addPorts() {
186 bool hasChildren = std::all_of(children.begin(), children.end(),
187 [](auto* c) { return c != nullptr; });
188
189 if (hasChildren) {
190 TazGraphEngine::ConsoleLogger::error("Node already has 4 children!");
191 return;
192 }
193
194 TransformComponent* tr = &GetComponent<TransformComponent>();
195
196 auto& leftPort = getManager()->addEntityNoId<Empty>();
197 leftPort.addGroup(Manager::groupPorts);
198 glm::vec3 m_position = glm::vec3(-tr->size.x / 2, 0.0f, 0.0f);
199 leftPort.addComponent<TransformComponent>(m_position, glm::vec3(0), 1.0f);
200 children[NodePorts::LEFT] = &leftPort;
201 children[NodePorts::LEFT]->setParentEntity(this);
202 children[NodePorts::LEFT]->GetComponent<TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
203 children[NodePorts::LEFT]->addComponent<PortComponent>(true);
204
205 auto& rightPort = getManager()->addEntityNoId<Empty>();
206 rightPort.addGroup(Manager::groupPorts);
207 m_position = glm::vec3(tr->size.x / 2 , 0.0f, 0.0f);
208 rightPort.addComponent<TransformComponent>(m_position, glm::vec3(0), 1.0f);
209 children[NodePorts::RIGHT] = &rightPort;
210 children[NodePorts::RIGHT]->setParentEntity(this);
211 children[NodePorts::RIGHT]->GetComponent<TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
212 children[NodePorts::RIGHT]->addComponent<PortComponent>(true);
213
214 // Initialize top port
215 auto& topPort = getManager()->addEntityNoId<Empty>();
216 topPort.addGroup(Manager::groupPorts);
217 m_position = glm::vec3(0.0f, -tr->size.y / 2.0f, 0.0f);
218 topPort.addComponent<TransformComponent>(m_position, glm::vec3(0), 1.0f);
219 children[NodePorts::TOP] = &topPort;
220 children[NodePorts::TOP]->setParentEntity(this);
221 children[NodePorts::TOP]->GetComponent<TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
222 children[NodePorts::TOP]->addComponent<PortComponent>(false);
223
224 // Initialize bottom port
225 auto& bottomPort = getManager()->addEntityNoId<Empty>();
226 bottomPort.addGroup(Manager::groupPorts);
227 m_position = glm::vec3(0.0f, tr->size.y / 2.0f, 0.0f);
228 bottomPort.addComponent<TransformComponent>(m_position, glm::vec3(0), 1.0f);
229 children[NodePorts::BOTTOM] = &bottomPort;
230 children[NodePorts::BOTTOM]->setParentEntity(this);
231 children[NodePorts::BOTTOM]->GetComponent<TransformComponent>().bodyCenter = tr->bodyCenter + m_position;
232 children[NodePorts::BOTTOM]->addComponent<PortComponent>(false);
233
234 /* auto& testSlot = getManager()->addEntityNoId<Empty>();
235 testSlot.addGroup(Manager::groupPortSlots);
236 testSlot.addComponent<TransformComponent>(m_position, glm::vec3(3), 1.0f);
237 testSlot.addComponent<Rectangle_w_Color>();
238 testSlot.GetComponent<Rectangle_w_Color>().setColor(Color(0, 250, 0, 255));
239 testSlot.addComponent<PortSlotComponent>();
240 testSlot.setParentEntity(children[NodePorts::BOTTOM]);
241 children[NodePorts::BOTTOM]->GetComponent<PortComponent>().
242 portSlots.push_back(&testSlot);*/
243
244 }
245
246 void removePorts() override {
247 for (auto portName : { NodePorts::LEFT, NodePorts::RIGHT, NodePorts::TOP, NodePorts::BOTTOM }) {
248 if (children[portName]) {
249 children[portName]->destroy();
250 for (auto slot : children[portName]->GetComponent<PortComponent>().portSlots)
251 {
252 slot->destroy();
253 }
254 children[portName]->GetComponent<PortComponent>().portSlots.clear();
255 children[portName] = nullptr;
256 }
257 }
258 }
259
260 void removeSlots() override {
261 for (auto portName : { NodePorts::LEFT, NodePorts::RIGHT, NodePorts::TOP, NodePorts::BOTTOM }) {
262 if (children[portName]) {
263 for (auto slot : children[portName]->GetComponent<PortComponent>().portSlots)
264 {
265 slot->destroy();
266 }
267 children[portName]->GetComponent<PortComponent>().portSlots.clear();
268 }
269 }
270 }
271
272};
273
274
275class Link : public LinkEntity {
276private:
277
278
279
280public:
281
282
283 Color color = {};
284
285 Link(Manager& mManager) : LinkEntity(mManager) {
286 }
287
288 Link(Manager& mManager, unsigned int mfromId, unsigned int mtoId)
289 : LinkEntity(mManager, mfromId, mtoId)
290 {
291 from = dynamic_cast<NodeEntity*>(mManager.getEntityFromId(fromId));
292 from->addOutLink(this);
293 to = dynamic_cast<NodeEntity*>(mManager.getEntityFromId(toId));
294 to->addInLink(this);
295 }
296
297 Link(Manager& mManager, Entity* mfrom, Entity* mto)
298 : LinkEntity(mManager,
299 dynamic_cast<NodeEntity*>(mfrom), // it is node but cant see it due to getParentEntity
300 dynamic_cast<NodeEntity*>(mto))
301 {
302 fromId = from->getId();
303 toId = to->getId();
304 }
305
306 Link(Manager& mManager, NodeEntity* mfrom, NodeEntity* mto)
307 : LinkEntity(mManager,
308 mfrom,
309 mto)
310 {
311 fromId = from->getId();
312 toId = to->getId();
313 }
314
315 Link(Manager& mManager,
316 unsigned int mfromId, unsigned int mtoId,
317 NodeEntity* mfrom, NodeEntity* mto
318 )
319 : LinkEntity(mManager,
320 mfromId, mtoId,
321 mfrom, mto)
322 {
323
324 }
325
326 Link(
327 Manager& mManager,
328 NodeEntity* mfrom, NodeEntity* mto,
329 int m_fromPort, int m_toPort, int m_fromSlot, int m_toSlot
330 )
331 : LinkEntity(mManager,
332 mfrom, mto,
333 m_fromPort, m_toPort,
334 m_fromSlot, m_toSlot)
335 {
336
337 }
338
339 void addGroup(Group mGroup) override {
340 Entity::addGroup(mGroup);
341 manager.AddLinkToGroup(this, mGroup);
342 }
343
344 virtual ~Link() {
345
346 }
347
348 void update(float deltaTime) override
349 {
350 Entity::update(deltaTime);
351
352
353 }
354
355 void cellUpdate() override {
356 // if cell(or position) of fromNode or cell(or position) of toNode is different than
357 // the saved cells in ownerCells then update it
358 if (!ownerCells.empty()) {
359 auto level = manager.grid->getGridLevel();
360 const auto& fromCell = manager.grid->getCell(*getFromNode(), level);
361 const auto& toCell = manager.grid->getCell(*getToNode(), level);
362
363 const auto& ownerFront = ownerCells.front();
364 const auto& ownerBack = ownerCells.back();
365
366 if (fromCell != ownerFront
367 || toCell != ownerBack)
368 {
369 removeFromCells();
370
371 manager.grid->addLink(this, manager.grid->getGridLevel());
372 }
373 }
374
375 }
376
377 void updateArrowHeads() override {
378 if (children[LinkPorts::ARROWHEAD]) {
379 TransformComponent* tr = &children[LinkPorts::ARROWHEAD]->GetComponent<TransformComponent>();
380
381 children[LinkPorts::ARROWHEAD]->update(0.0f);
382
383 // set position of arrowHead
384 TransformComponent* ch_tr = &to->children[toPort]->GetComponent<TransformComponent>();
385
386 TransformComponent* toPortTR = ch_tr;
387 TransformComponent* fromPortTR = &from->children[fromPort]->GetComponent<TransformComponent>();
388
389 glm::vec3 direction = toPortTR->getCenterTransform() - fromPortTR->getCenterTransform();
390
391 glm::vec3 unitDirection = glm::normalize(direction);
392 float offset = 10.0f;
393
394 glm::vec3 arrowHeadPos = toPortTR->getCenterTransform() - unitDirection * offset;
395
396 // Calculate the angle in radians, and convert it to degrees
397 float angleRadians = -atan2(direction.y, direction.x);
398 float angleDegrees = glm::degrees(angleRadians);
399
400 glm::ivec3 arrowSize(10, 20, 0);
401 glm::vec3 farrowSize(10.0f, 20.0f, 0.0f);
402
403 glm::vec3 newArrowHeadPosition = arrowHeadPos - (farrowSize / 2.0f);
404 children[LinkPorts::ARROWHEAD]->GetComponent<TransformComponent>().position = newArrowHeadPosition;
405
406 children[LinkPorts::ARROWHEAD]->GetComponent<TransformComponent>().setRotation(glm::vec3(0.0f, 0.0f, angleRadians + glm::half_pi<float>()));
407 }
408 }
409
410 void updateConnectedPorts() override{
411 TransformComponent* toTR = &to->GetComponent<TransformComponent>();
412 TransformComponent* fromTR = &from->GetComponent<TransformComponent>();
413
414 int newFromPort = getBestPortForConnection(fromTR->getCenterTransform(), toTR->getCenterTransform());
415 int newToPort = getBestPortForConnection(toTR->getCenterTransform(), fromTR->getCenterTransform());
416
417 fromSlotIndex = assignSlotIndex(from, newFromPort, fromPort, fromSlotIndex);
418 toSlotIndex = assignSlotIndex(to, newToPort, toPort, toSlotIndex);
419
420 fromPort = newFromPort;
421 toPort = newToPort;
422 }
423
424 void addArrowHead() override {
425 TransformComponent* toTR = &to->GetComponent<TransformComponent>();
426 TransformComponent* fromTR = &from->GetComponent<TransformComponent>();
427
428 fromPort = getBestPortForConnection(fromTR->getCenterTransform(), toTR->getCenterTransform());
429 toPort = getBestPortForConnection(toTR->getCenterTransform(), fromTR->getCenterTransform());
430
431 TransformComponent* toPortTR = &to->children[toPort]->GetComponent<TransformComponent>();
432 TransformComponent* fromPortTR = &from->children[fromPort]->GetComponent<TransformComponent>();
433
434 glm::vec3 direction = toPortTR->getCenterTransform() - fromPortTR->getCenterTransform();
435
436 glm::vec3 unitDirection = glm::normalize(direction);
437 float offset = 10.0f;
438
439 glm::vec3 arrowHeadPos = toPortTR->getCenterTransform() - unitDirection * offset;
440
441 auto& temp_arrowHead = getManager()->addEntityNoId<Empty>();
442
443 // Calculate the angle in radians, and convert it to degrees
444 float angleRadians = -atan2(direction.y, direction.x);
445 float angleDegrees = glm::degrees(angleRadians);
446
447 glm::vec3 farrowSize(10.0f, 20.0f, 0.0f);
448
449 temp_arrowHead.addComponent<TransformComponent>(arrowHeadPos - (farrowSize /2.0f), farrowSize, 1);
450 temp_arrowHead.addComponent<Triangle_w_Color>();
451 temp_arrowHead.GetComponent<Triangle_w_Color>().color = Color(0, 0, 0, 255);
452
453 temp_arrowHead.GetComponent<TransformComponent>().setRotation(glm::vec3(0.0f, 0.0f, angleRadians + glm::half_pi<float>()));
454
455 temp_arrowHead.addGroup(Manager::groupArrowHeads_0);
456
457 temp_arrowHead.setParentEntity(this);
458
459 manager.grid->addEmpty(&temp_arrowHead, manager.grid->getGridLevel());
460
461 children[LinkPorts::ARROWHEAD] = &temp_arrowHead;
462 }
463
464 void removeArrowHead() override {
465 if (children[LinkPorts::ARROWHEAD]) {
466 children[LinkPorts::ARROWHEAD]->removeFromCell();
467 children[LinkPorts::ARROWHEAD]->destroy();
468 children[LinkPorts::ARROWHEAD] = nullptr;
469 }
470 }
471
472 void resetPorts() override {
473 fromPort = -1;
474 toPort = -1;
475 }
476
477 int getBestPortForConnection(const glm::vec3& fromPos, const glm::vec3& toPos) {
478 // Simple logic to determine the port based on relative position
479 float deltaX = toPos.x - fromPos.x;
480 float deltaY = toPos.y - fromPos.y;
481
482 if (abs(deltaX) > abs(deltaY)) { // Horizontal distance is greater
483 return deltaX > 0 ? NodePorts::RIGHT : NodePorts::LEFT;
484 }
485 else { // Vertical distance is greater
486 return deltaY > 0 ? NodePorts::BOTTOM : NodePorts::TOP;
487 }
488 }
489
490 int assignSlotIndex(NodeEntity* node, int newPort, int oldPort, int oldSlotIndex) {
491 // If port changed, remove link from old port's slots
492 if (oldPort != -1 && oldPort != newPort && oldPort < (int)node->children.size()) {
493 Entity* oldPortEntity = node->children[oldPort];
494 if (oldPortEntity && oldPortEntity->hasComponent<PortComponent>()) {
495 auto& oldSlots = oldPortEntity->GetComponent<PortComponent>().portSlots;
496
497 if (oldSlotIndex >= 0 && oldSlotIndex < (int)oldSlots.size()) {
498 EmptyEntity* slotToRemove = oldSlots[oldSlotIndex];
499
500 oldSlots.erase(oldSlots.begin() + oldSlotIndex); // Remove from vector first
501 slotToRemove->destroy();
502
503 updateLinksSlotIndices(node, oldPort, oldSlotIndex);
504 }
505 }
506 }
507
508 if (oldPort != newPort) {
509 if (newPort < 0 || newPort >= (int)node->children.size()) {
510 return -1; // Invalid port
511 }
512
513 Entity* newPortEntity = node->children[newPort];
514 if (!newPortEntity || !newPortEntity->hasComponent<PortComponent>()) {
515 return -1; // Port doesn't exist or doesn't have PortComponent
516 }
517
518 auto& newSlots = newPortEntity->GetComponent<PortComponent>().portSlots;
519
520 auto& newSlot = node->getManager()->addEntityNoId<Empty>();
521 newSlot.addGroup(Manager::groupPortSlots);
522 TransformComponent& portTransform = newPortEntity->GetComponent<TransformComponent>();
523 newSlot.addComponent<TransformComponent>(
524 portTransform.bodyCenter,
525 glm::vec3(3),
526 1.0f
527 );
528 newSlot.addComponent<Rectangle_w_Color>();
529 newSlot.GetComponent<Rectangle_w_Color>().setColor(Color(0, 250, 0, 255)); // Green for connected
530 newSlot.addComponent<PortSlotComponent>();
531 // Store reference to the link (you might want to add this field to PortSlotComponent)
532 // newSlot.GetComponent<PortSlotComponent>().linkedEntity = link;
533 newSlot.setParentEntity(newPortEntity);
534 newSlots.push_back(&newSlot);
535
536 return static_cast<int>(newSlots.size() - 1);
537 }
538
539 return oldSlotIndex;
540 }
541
542 void updateLinksSlotIndices(NodeEntity* node, int portIndex, int removedSlotIndex) {
543 for (auto& linkEntity : node->getOutLinks()) {
544
545 if (linkEntity->fromPort == portIndex &&
546 linkEntity->fromSlotIndex > removedSlotIndex) {
547 linkEntity->fromSlotIndex--;
548 }
549 }
550
551 for (auto& linkEntity : node->getInLinks()) {
552
553 if (linkEntity->toPort == portIndex &&
554 linkEntity->toSlotIndex > removedSlotIndex) {
555 linkEntity->toSlotIndex--;
556 }
557 }
558 }
559
560 void imgui_print() override {
561 glm::vec2 fromNodePosition = this->getFromNode()->GetComponent<TransformComponent>().getCenterTransform();
562 glm::vec2 toNodePosition = this->getToNode()->GetComponent<TransformComponent>().getCenterTransform();
563
564 ImGui::Text("From Node Position: (%.2f, %.2f)", fromNodePosition.x, fromNodePosition.y);
565 ImGui::Text("To Node Position: (%.2f, %.2f)", toNodePosition.x, toNodePosition.y);
566
567 ImGui::Text("Bounding boxes of intercepted cells:");
568
569 for (auto cell : ownerCells) {
570 ImGui::Text("- %.2f , %.2f , %.2f", cell->boundingBox_origin.x, cell->boundingBox_origin.y, cell->boundingBox_origin.z);
571 }
572 }
573
574 void imgui_display() override {
575 ImGui::Text("Display Info Here Link");
576 }
577
578 void destroy() {
579 Entity::destroy();
580
581 if (children[LinkPorts::ARROWHEAD]) {
582 children[LinkPorts::ARROWHEAD]->destroy();
583 }
584
585 manager.aboutTo_updateActiveEntities();
586 }
587
588};
Definition GECSEntity.h:7
Definition GECSEntityTypes.h:7
Definition GECS.h:152
Definition GECSEntity.h:107
Definition GECSManager.h:14
Definition GECSEntity.h:43
Definition GECSEntityTypes.h:56
Definition PortComponent.h:7
Definition PortSlotComponent.h:7
Definition Rectangle_w_Color.h:6
Definition TransformComponent.h:6
Definition Triangle_w_Color.h:6
Definition CellEntity.h:5
Definition Vertex.h:47