Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // Created by enoc on 14/1/20.
- //
- #include <EddieECS/Components/EntityLabel.hpp>
- #include <EddieGraphics/Keyboard/Keyboard.hpp>
- #include <EddieECS/TagFunctions.hpp>
- #include "UI/TaggedEntityList.hpp"
- namespace {
- std::vector<std::string> GetAllTags(const ECS::Entity& e) {
- if(e.IsAlive()) {
- if(e.HasComponent<ECS::Comp::EntityLabel>()) {
- return e.GetComponentHandler<ECS::Comp::EntityLabel>()->mTags;
- }
- }
- return std::vector<std::string>();
- }
- bool TagExists(const std::vector<std::string>& tags, const std::string& tag) {
- return std::find(tags.begin(), tags.end(), tag) != tags.end();
- }
- }
- EddieUI::TaggedEntityList::TaggedEntityList() { }
- void EddieUI::TaggedEntityList::AdditionalKeyHandlers() {
- // TODO: Para cuando haya que meter keys y tal...
- }
- void EddieUI::TaggedEntityList::Prepare() noexcept {
- if (gContext == nullptr) {
- FATAL_ERROR("GameContext Need to be linked before prepare!");
- }
- this->mSGSystem = gContext->GetEcsSystem<ECS::SceneGraphSystem>();
- this->mRegisterSystem = gContext->GetEcsSystem<ECS::EntityRegister>();
- }
- void EddieUI::TaggedEntityList::RenderFrameUI(EddieUI::UIContext &context) {
- if(!isSubscribed) {
- FATAL_ERROR("Not subscribed.");
- }
- ImGui::ShowDemoWindow();
- // TODO: Esto tendrá que tener dos Trees por ejemplo, uno para añadir tags y el otro para borrarlos...
- auto EntityContextualMenu = [&](ECS::Entity& entity) {
- auto name = entity.GetComponentHandler<ECS::Comp::EntityLabel>()->NameHolder.name;
- auto tags = GetAllTags(entity);
- // Add tags
- ImGui::Text("Add TAG to the entity %s", name.c_str());
- ImGui::Separator();
- ImGui::SetNextItemWidth(200);
- static char newTag[64] = "";
- ImGui::InputText("TAG", newTag, 64, ImGuiInputTextFlags_None);
- if (ImGui::Button("Add new tag")) {
- if (!TagExists(tags, newTag)) {
- ECS::AddEntityTag(entity, newTag);
- memset(newTag, 0, sizeof newTag);
- }
- }
- ImGui::Separator();
- ImGui::Separator();
- // Remove tags
- ImGui::Text("Remove TAG to the entity %s", name.c_str());
- ImGui::Separator();
- int32_t id = 0;
- for (auto& tag: tags) {
- if (tag != UNNAMED_TAG) {
- ImGui::Text("\t%s", tag.c_str()); ImGui::SameLine(125);
- ImGui::PushID(id++);
- if (ImGui::Button("Remove")) {
- std::cout << "Remove TAG: " << tag << std::endl;
- ECS::RemoveEntityTag(entity, tag);
- }
- ImGui::PopID();
- }
- }
- // Exit
- if (ImGui::Button("Exit")) {
- ImGui::CloseCurrentPopup();
- }
- };
- auto PrintTaggedList = [&](const std::string& tag, std::vector<ECS::Entity> entities) {
- if (ImGui::TreeNode(tag.c_str())) {
- ImGui::Columns(3);
- ImGui::Text("Name");
- ImGui::NextColumn();
- ImGui::Text("Object Type");
- ImGui::NextColumn();
- ImGui::Text("Visible");
- ImGui::NextColumn();
- ImGui::Separator();
- int counter = 0;
- for (auto &entity : entities) {
- auto name = entity.GetComponentHandler<ECS::Comp::EntityLabel>()->NameHolder.name;
- bool isItemSelected = (itemSelected == counter && tagSelected == tag);
- if (ImGui::Selectable(name.c_str(), isItemSelected, ImGuiSelectableFlags_SpanAllColumns)) {
- itemSelected = counter;
- tagSelected = tag;
- }
- if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(Mouse::RCLICK)) {
- itemSelected = counter;
- tagSelected = tag;
- ImGui::OpenPopup("tag-menu-popup");
- }
- ImGui::NextColumn();
- ImGui::Text("---");
- ImGui::NextColumn();
- ImGui::Text("---");
- ImGui::NextColumn();
- counter++;
- }
- ImGui::Columns(1);
- ImGui::Separator();
- ImGui::Separator();
- if (ImGui::BeginPopup("tag-menu-popup")) {
- EntityContextualMenu(entities[itemSelected]);
- ImGui::EndPopup();
- }
- ImGui::TreePop();
- }
- };
- for (auto& entityTag : entityTags) {
- if (entityTag.first != UNNAMED_TAG) {
- PrintTaggedList(entityTag.first, entityTag.second);
- }
- }
- if (!entityTags[UNNAMED_TAG].empty()) PrintTaggedList(UNNAMED_TAG, entityTags[UNNAMED_TAG]);
- // TODO: Actualizar el map con los elementos a añadir o borrar después de pintar todo...
- MakeChanges();
- }
- void EddieUI::TaggedEntityList::Subscribe(Game::Context* context) {
- if(context != nullptr) {
- isSubscribed = true;
- }
- auto& eventManager = context->GetInternalEcs().GetEventsManager();
- eventManager.Subscribe<ECS::ComponentReplacedEvent<ECS::Comp::EntityLabel>>(this);
- eventManager.Subscribe<ECS::ComponentAddedEvent<ECS::Comp::EntityLabel>>(this);
- eventManager.Subscribe<ECS::ComponentRemovedEvent<ECS::Comp::EntityLabel>>(this);
- eventManager.Subscribe<ECS::SystemResetEvent>(this);
- eventManager.Subscribe<ECS::EntityNameChange>(this);
- eventManager.Subscribe<::ECS::EntityTagAdded>(this);
- eventManager.Subscribe<::ECS::EntityTagRemoved>(this);
- this->mSGSystem = context->GetEcsSystem<ECS::SceneGraphSystem>();
- this->mRegisterSystem = context->GetEcsSystem<ECS::EntityRegister>();
- }
- // TODO: Se ha modificado la entity
- void EddieUI::TaggedEntityList::HandleEvent(const ECS::ComponentReplacedEvent<ECS::Comp::EntityLabel> & event) {
- auto name = event.mEntity.GetComponentHandler<ECS::Comp::EntityLabel>()->NameHolder.name;
- std::cout << "ComponentReplacedEvent => " << name << std::endl;
- }
- // TODO: Se ha añadido una nueva entity y hay que meterla en el mapa
- void EddieUI::TaggedEntityList::HandleEvent(const ECS::ComponentAddedEvent<ECS::Comp::EntityLabel> &event) {
- auto tags = GetAllTags(event.mEntity);
- if (tags.empty()) entityTags[UNNAMED_TAG].emplace_back(event.mEntity);
- else {
- for (auto& tag : tags) {
- entityTags[tag].emplace_back(event.mEntity);
- }
- }
- std::cout << "ComponentAddedEvent" << std::endl;
- }
- // TODO: Se ha eliminado la entity o el tag y por lo tanto hay que eliminarlo del map de grupos
- void EddieUI::TaggedEntityList::HandleEvent(const ECS::ComponentRemovedEvent<ECS::Comp::EntityLabel> &event) {
- std::cout << "ComponentRemovedEvent " << std::endl;
- }
- // TODO: Cuando se cammbia de escena y se cambian todas las entities
- void EddieUI::TaggedEntityList::HandleEvent(const ECS::SystemResetEvent &event) {
- entityTags.clear();
- std::cout << "SystemResetEvent => " << std::endl;
- }
- // TODO: Se ha cambiado el nombre de la entity, por lo que hay que modificar el nombre dentro del map...
- void EddieUI::TaggedEntityList::HandleEvent(const ECS::EntityNameChange &event) {
- auto prevName = event.prevName;
- auto newName = event.newName;
- auto e = this->mRegisterSystem->FindEntity(newName);
- if(e) {
- auto tags = GetAllTags(e.value());
- }
- std::cout << "EntityNameChange => " << newName << std::endl;
- }
- // TODO: Se ha añadido un tag a una entity existente
- void EddieUI::TaggedEntityList::HandleEvent(const ECS::EntityTagAdded &event) {
- std::cout << "EntityTagAdded => " << event.mTag << std::endl;
- addeds.emplace_back(event);
- }
- // TODO: Se ha eliminado un tag de una entity existente
- void EddieUI::TaggedEntityList::HandleEvent(const ECS::EntityTagRemoved &event) {
- std::cout << "EntityTagRemoved => " << event.mTag << std::endl;
- removeds.emplace_back(event);
- }
- void EddieUI::TaggedEntityList::SetGameContext(Game::Context &context) {
- this->gContext = &context;
- }
- void EddieUI::TaggedEntityList::MakeChanges() {
- if (!addeds.empty()) {
- for (auto& added : addeds) {
- auto erase = std::remove_if(entityTags[UNNAMED_TAG].begin(), entityTags[UNNAMED_TAG].end(), [entity=added.mEntity](const ECS::Entity& e){
- return e == entity;
- });
- entityTags[UNNAMED_TAG].erase(erase, entityTags[UNNAMED_TAG].end());
- entityTags[added.mTag].emplace_back(added.mEntity);
- }
- addeds.clear();
- }
- if (!removeds.empty()) {
- for (auto& removed : removeds) {
- auto erase = std::remove_if(entityTags[removed.mTag].begin(), entityTags[removed.mTag].end(), [entity=removed.mEntity](const ECS::Entity& e){
- return e == entity;
- });
- entityTags[removed.mTag].erase(erase, entityTags[removed.mTag].end());
- auto tags = GetAllTags(removed.mEntity);
- if (tags.empty()) entityTags[UNNAMED_TAG].emplace_back(removed.mEntity);
- }
- removeds.clear();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement