Advertisement
Guest User

Untitled

a guest
Jan 20th, 2020
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.11 KB | None | 0 0
  1. //
  2. // Created by enoc on 14/1/20.
  3. //
  4.  
  5. #include <EddieECS/Components/EntityLabel.hpp>
  6. #include <EddieGraphics/Keyboard/Keyboard.hpp>
  7. #include <EddieECS/TagFunctions.hpp>
  8. #include "UI/TaggedEntityList.hpp"
  9.  
  10.  
  11. namespace {
  12.     std::vector<std::string> GetAllTags(const ECS::Entity& e) {
  13.         if(e.IsAlive()) {
  14.             if(e.HasComponent<ECS::Comp::EntityLabel>()) {
  15.                 return e.GetComponentHandler<ECS::Comp::EntityLabel>()->mTags;
  16.             }
  17.         }
  18.         return std::vector<std::string>();
  19.     }
  20.  
  21.     bool TagExists(const std::vector<std::string>& tags, const std::string& tag) {
  22.         return std::find(tags.begin(), tags.end(), tag) != tags.end();
  23.     }
  24. }
  25.  
  26. EddieUI::TaggedEntityList::TaggedEntityList() { }
  27.  
  28. void EddieUI::TaggedEntityList::AdditionalKeyHandlers() {
  29.     // TODO: Para cuando haya que meter keys y tal...
  30. }
  31.  
  32. void EddieUI::TaggedEntityList::Prepare() noexcept {
  33.     if (gContext == nullptr) {
  34.         FATAL_ERROR("GameContext Need to be linked before prepare!");
  35.     }
  36.     this->mSGSystem = gContext->GetEcsSystem<ECS::SceneGraphSystem>();
  37.     this->mRegisterSystem = gContext->GetEcsSystem<ECS::EntityRegister>();
  38. }
  39.  
  40. void EddieUI::TaggedEntityList::RenderFrameUI(EddieUI::UIContext &context) {
  41.     if(!isSubscribed) {
  42.         FATAL_ERROR("Not subscribed.");
  43.     }
  44.  
  45.     ImGui::ShowDemoWindow();
  46.  
  47.     // TODO: Esto tendrá que tener dos Trees por ejemplo, uno para añadir tags y el otro para borrarlos...
  48.     auto EntityContextualMenu = [&](ECS::Entity& entity) {
  49.         auto name = entity.GetComponentHandler<ECS::Comp::EntityLabel>()->NameHolder.name;
  50.         auto tags = GetAllTags(entity);
  51.  
  52.         // Add tags
  53.         ImGui::Text("Add TAG to the entity %s", name.c_str());
  54.         ImGui::Separator();
  55.         ImGui::SetNextItemWidth(200);
  56.         static char newTag[64] = "";
  57.         ImGui::InputText("TAG", newTag, 64, ImGuiInputTextFlags_None);
  58.         if (ImGui::Button("Add new tag")) {
  59.             if (!TagExists(tags, newTag)) {
  60.                 ECS::AddEntityTag(entity, newTag);
  61.                 memset(newTag, 0, sizeof newTag);
  62.             }
  63.         }
  64.  
  65.         ImGui::Separator();
  66.         ImGui::Separator();
  67.  
  68.         // Remove tags
  69.         ImGui::Text("Remove TAG to the entity %s", name.c_str());
  70.         ImGui::Separator();
  71.         int32_t id = 0;
  72.         for (auto& tag: tags) {
  73.             if (tag != UNNAMED_TAG) {
  74.                 ImGui::Text("\t%s", tag.c_str()); ImGui::SameLine(125);
  75.                 ImGui::PushID(id++);
  76.                 if (ImGui::Button("Remove")) {
  77.                     std::cout << "Remove TAG: " << tag << std::endl;
  78.                     ECS::RemoveEntityTag(entity, tag);
  79.                 }
  80.                 ImGui::PopID();
  81.             }
  82.         }
  83.  
  84.         // Exit
  85.         if (ImGui::Button("Exit")) {
  86.             ImGui::CloseCurrentPopup();
  87.         }
  88.     };
  89.  
  90.     auto PrintTaggedList = [&](const std::string& tag, std::vector<ECS::Entity> entities) {
  91.         if (ImGui::TreeNode(tag.c_str())) {
  92.             ImGui::Columns(3);
  93.             ImGui::Text("Name");
  94.             ImGui::NextColumn();
  95.             ImGui::Text("Object Type");
  96.             ImGui::NextColumn();
  97.             ImGui::Text("Visible");
  98.             ImGui::NextColumn();
  99.             ImGui::Separator();
  100.  
  101.             int counter = 0;
  102.             for (auto &entity : entities) {
  103.                 auto name = entity.GetComponentHandler<ECS::Comp::EntityLabel>()->NameHolder.name;
  104.  
  105.                 bool isItemSelected = (itemSelected == counter && tagSelected == tag);
  106.                 if (ImGui::Selectable(name.c_str(), isItemSelected, ImGuiSelectableFlags_SpanAllColumns)) {
  107.                     itemSelected = counter;
  108.                     tagSelected = tag;
  109.                 }
  110.  
  111.                 if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(Mouse::RCLICK)) {
  112.                     itemSelected = counter;
  113.                     tagSelected = tag;
  114.                     ImGui::OpenPopup("tag-menu-popup");
  115.                 }
  116.  
  117.                 ImGui::NextColumn();
  118.                 ImGui::Text("---");
  119.                 ImGui::NextColumn();
  120.                 ImGui::Text("---");
  121.                 ImGui::NextColumn();
  122.  
  123.                 counter++;
  124.             }
  125.  
  126.             ImGui::Columns(1);
  127.             ImGui::Separator();
  128.             ImGui::Separator();
  129.  
  130.             if (ImGui::BeginPopup("tag-menu-popup")) {
  131.                 EntityContextualMenu(entities[itemSelected]);
  132.                 ImGui::EndPopup();
  133.             }
  134.             ImGui::TreePop();
  135.         }
  136.     };
  137.  
  138.     for (auto& entityTag : entityTags) {
  139.         if (entityTag.first != UNNAMED_TAG) {
  140.             PrintTaggedList(entityTag.first, entityTag.second);
  141.         }
  142.     }
  143.     if (!entityTags[UNNAMED_TAG].empty()) PrintTaggedList(UNNAMED_TAG, entityTags[UNNAMED_TAG]);
  144.  
  145.     // TODO: Actualizar el map con los elementos a añadir o borrar después de pintar todo...
  146.     MakeChanges();
  147. }
  148.  
  149. void EddieUI::TaggedEntityList::Subscribe(Game::Context* context) {
  150.     if(context != nullptr) {
  151.         isSubscribed = true;
  152.     }
  153.  
  154.     auto& eventManager = context->GetInternalEcs().GetEventsManager();
  155.     eventManager.Subscribe<ECS::ComponentReplacedEvent<ECS::Comp::EntityLabel>>(this);
  156.     eventManager.Subscribe<ECS::ComponentAddedEvent<ECS::Comp::EntityLabel>>(this);
  157.     eventManager.Subscribe<ECS::ComponentRemovedEvent<ECS::Comp::EntityLabel>>(this);
  158.     eventManager.Subscribe<ECS::SystemResetEvent>(this);
  159.     eventManager.Subscribe<ECS::EntityNameChange>(this);
  160.     eventManager.Subscribe<::ECS::EntityTagAdded>(this);
  161.     eventManager.Subscribe<::ECS::EntityTagRemoved>(this);
  162.  
  163.     this->mSGSystem = context->GetEcsSystem<ECS::SceneGraphSystem>();
  164.     this->mRegisterSystem = context->GetEcsSystem<ECS::EntityRegister>();
  165. }
  166.  
  167. // TODO: Se ha modificado la entity
  168. void EddieUI::TaggedEntityList::HandleEvent(const ECS::ComponentReplacedEvent<ECS::Comp::EntityLabel> & event) {
  169.     auto name = event.mEntity.GetComponentHandler<ECS::Comp::EntityLabel>()->NameHolder.name;
  170.     std::cout << "ComponentReplacedEvent => " << name << std::endl;
  171. }
  172.  
  173. // TODO: Se ha añadido una nueva entity y hay que meterla en el mapa
  174. void EddieUI::TaggedEntityList::HandleEvent(const ECS::ComponentAddedEvent<ECS::Comp::EntityLabel> &event) {
  175.     auto tags = GetAllTags(event.mEntity);
  176.     if (tags.empty()) entityTags[UNNAMED_TAG].emplace_back(event.mEntity);
  177.     else {
  178.         for (auto& tag : tags) {
  179.             entityTags[tag].emplace_back(event.mEntity);
  180.         }
  181.     }
  182.     std::cout << "ComponentAddedEvent"  << std::endl;
  183. }
  184.  
  185. // TODO: Se ha eliminado la entity o el tag y por lo tanto hay que eliminarlo del map de grupos
  186. void EddieUI::TaggedEntityList::HandleEvent(const ECS::ComponentRemovedEvent<ECS::Comp::EntityLabel> &event) {
  187.     std::cout << "ComponentRemovedEvent " << std::endl;
  188. }
  189.  
  190. // TODO: Cuando se cammbia de escena y se cambian todas las entities
  191. void EddieUI::TaggedEntityList::HandleEvent(const ECS::SystemResetEvent &event) {
  192.     entityTags.clear();
  193.     std::cout << "SystemResetEvent => " << std::endl;
  194. }
  195.  
  196. // TODO: Se ha cambiado el nombre de la entity, por lo que hay que modificar el nombre dentro del map...
  197. void EddieUI::TaggedEntityList::HandleEvent(const ECS::EntityNameChange &event) {
  198.     auto prevName = event.prevName;
  199.     auto newName = event.newName;
  200.     auto e = this->mRegisterSystem->FindEntity(newName);
  201.     if(e) {
  202.         auto tags = GetAllTags(e.value());
  203.     }
  204.  
  205.     std::cout << "EntityNameChange => " << newName << std::endl;
  206. }
  207.  
  208. // TODO: Se ha añadido un tag a una entity existente
  209. void EddieUI::TaggedEntityList::HandleEvent(const ECS::EntityTagAdded &event) {
  210.     std::cout << "EntityTagAdded => " << event.mTag << std::endl;
  211.     addeds.emplace_back(event);
  212. }
  213.  
  214. // TODO: Se ha eliminado un tag de una entity existente
  215. void EddieUI::TaggedEntityList::HandleEvent(const ECS::EntityTagRemoved &event) {
  216.     std::cout << "EntityTagRemoved => " << event.mTag << std::endl;
  217.     removeds.emplace_back(event);
  218. }
  219.  
  220. void EddieUI::TaggedEntityList::SetGameContext(Game::Context &context) {
  221.     this->gContext = &context;
  222. }
  223.  
  224. void EddieUI::TaggedEntityList::MakeChanges() {
  225.     if (!addeds.empty()) {
  226.         for (auto& added : addeds) {
  227.             auto erase = std::remove_if(entityTags[UNNAMED_TAG].begin(), entityTags[UNNAMED_TAG].end(), [entity=added.mEntity](const ECS::Entity& e){
  228.                 return e == entity;
  229.             });
  230.             entityTags[UNNAMED_TAG].erase(erase, entityTags[UNNAMED_TAG].end());
  231.  
  232.             entityTags[added.mTag].emplace_back(added.mEntity);
  233.         }
  234.         addeds.clear();
  235.     }
  236.  
  237.     if (!removeds.empty()) {
  238.         for (auto& removed : removeds) {
  239.             auto erase = std::remove_if(entityTags[removed.mTag].begin(), entityTags[removed.mTag].end(), [entity=removed.mEntity](const ECS::Entity& e){
  240.                 return e == entity;
  241.             });
  242.             entityTags[removed.mTag].erase(erase, entityTags[removed.mTag].end());
  243.  
  244.             auto tags = GetAllTags(removed.mEntity);
  245.             if (tags.empty()) entityTags[UNNAMED_TAG].emplace_back(removed.mEntity);
  246.         }
  247.         removeds.clear();
  248.     }
  249. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement