diff --git a/editor/editor.app.json b/editor/editor.app.json index 508477f09..1463514e2 100644 --- a/editor/editor.app.json +++ b/editor/editor.app.json @@ -20,7 +20,7 @@ } }, "InputSystem": { - "height": 991, + "height": 793, "inputSchemes": { "Editor": { "bools": [ @@ -74,7 +74,7 @@ } }, "startScheme": "Editor", - "width": 1920 + "width": 1536 }, "ParticleSystem": { "culling": { @@ -91,8 +91,8 @@ }, "PhysicsSystem": {}, "UISystem": { - "height": 991, - "width": 1920 + "height": 793, + "width": 1536 } }, "version": 1.0, diff --git a/imgui.ini b/imgui.ini index 37d35e982..d1f2a1e66 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,223 +1,223 @@ -[Window][Rootex Editor] -Pos=0,0 -Size=1920,991 -Collapsed=0 - -[Window][Output] -Pos=0,620 -Size=1114,371 -Collapsed=0 -DockId=0x00000003,0 - -[Window][Debug##Default] -Pos=256,142 -Size=400,400 -Collapsed=0 - -[Window][File System] -Pos=0,844 -Size=321,543 -Collapsed=0 -DockId=0x0000000E,0 - -[Window][Hierarchy] -Pos=0,866 -Size=321,521 -Collapsed=0 -DockId=0x0000000D,0 - -[Window][Entities] -Pos=0,626 -Size=388,285 -Collapsed=0 -DockId=0x0000000D,0 - -[Window][Toolbar] -Pos=1116,620 -Size=333,371 -Collapsed=0 -DockId=0x00000004,0 - -[Window][Viewport] -Pos=0,28 -Size=1449,590 -Collapsed=0 -DockId=0x00000008,0 - -[Window][Inspector] -Pos=1451,409 -Size=469,582 -Collapsed=0 -DockId=0x00000009,0 - -[Window][File Viewer] -Pos=1451,28 -Size=469,379 -Collapsed=0 -DockId=0x00000007,1 - -[Window][Gizmo] -Pos=31,186 -Size=251,86 -Collapsed=0 - -[Window][Classes] -Pos=0,646 -Size=265,411 -Collapsed=0 -DockId=0x0000000E,1 - -[Window][Test] -Pos=60,60 -Size=79,66 -Collapsed=0 - -[Window][Viewport Tools] -Pos=0,626 -Size=388,285 -Collapsed=0 -DockId=0x0000000D,1 - -[Window][Choose Model File##ChooseModelComponentModel] -Pos=924,383 -Size=755,526 -Collapsed=0 - -[Window][Choose Specular texture##ChooseSpecularTexture] -Pos=1015,477 -Size=534,321 -Collapsed=0 - -[Window][Normal Texture ##Normal Texture ] -Pos=959,393 -Size=700,461 -Collapsed=0 - -[Window][Diffuse Texture ##Diffuse Texture ] -Pos=1022,405 -Size=627,471 -Collapsed=0 - -[Window][Choose File##ChooseFileDlgKey] -Pos=60,60 -Size=338,380 -Collapsed=0 - -[Window][Choose File2##ChooseFileDlgKey2] -Pos=963,447 -Size=539,437 -Collapsed=0 - -[Window][Specular Texture ##Specular Texture ] -Pos=939,429 -Size=711,477 -Collapsed=0 - -[Window][Sky Texture##Sky Texture] -Pos=923,377 -Size=666,443 -Collapsed=0 - -[Window][Choose Material##rootex/assets/materials/default.basic.rmat] -Pos=879,268 -Size=800,574 -Collapsed=0 - -[Window][Choose Material##Material] -Pos=1049,371 -Size=730,503 -Collapsed=0 - -[Window][Choose Material##game/assets/materials/handgunhandg.000.rmat] -Pos=60,60 -Size=528,156 -Collapsed=0 - -[Window][Choose Material##game/assets/materials/material.001.rmat] -Pos=60,60 -Size=528,156 -Collapsed=0 - -[Window][Choose Script##Script] -Pos=973,483 -Size=549,308 -Collapsed=0 - -[Window][Choose Music##Music] -Pos=875,299 -Size=747,545 -Collapsed=0 - -[Window][Choose RML Document##Document] -Pos=1347,342 -Size=745,480 -Collapsed=0 - -[Window][Scene] -Pos=1451,28 -Size=469,379 -Collapsed=0 -DockId=0x00000007,0 - -[Window][Choose Font##Font] -Pos=1053,427 -Size=587,403 -Collapsed=0 - -[Window][Debug Scene] -Pos=1754,65 -Size=750,643 -Collapsed=0 - -[Window][Load Scene] -Pos=1117,620 -Size=30,58 -Collapsed=0 - -[Window][Save] -Pos=1233,626 -Size=262,110 -Collapsed=0 - -[Window][Style Editor] -Pos=761,148 -Size=460,808 -Collapsed=0 - -[Window][Lua API Documentation] -Pos=653,347 -Size=1280,693 -Collapsed=0 - -[Window][File Editor] -Pos=0,28 -Size=1449,590 -Collapsed=0 -DockId=0x00000008,1 - -[Window][Content Browsers] -Pos=60,60 -Size=241,158 -Collapsed=0 - -[Window][Content Browser] -Pos=0,620 -Size=1114,371 -Collapsed=0 -DockId=0x00000003,1 - -[Docking][Data] -DockSpace ID=0x654E7FDC Window=0xDC8952A0 Pos=0,28 Size=1920,963 Split=X - DockNode ID=0x00000001 Parent=0x654E7FDC SizeRef=1932,1359 Split=Y Selected=0x995B0CF8 - DockNode ID=0x00000008 Parent=0x00000001 SizeRef=1932,596 Selected=0x995B0CF8 - DockNode ID=0x0000000A Parent=0x00000001 SizeRef=1932,375 Split=X Selected=0xCB7211A8 - DockNode ID=0x00000003 Parent=0x0000000A SizeRef=1114,226 Selected=0x371352B7 - DockNode ID=0x00000004 Parent=0x0000000A SizeRef=333,226 Selected=0x507852CA - DockNode ID=0x00000002 Parent=0x654E7FDC SizeRef=626,1359 Split=X - DockNode ID=0x00000005 Parent=0x00000002 SizeRef=291,1038 Split=Y Selected=0xCD504759 - DockNode ID=0x0000000D Parent=0x00000005 SizeRef=353,818 Selected=0x8988DF52 - DockNode ID=0x0000000E Parent=0x00000005 SizeRef=353,543 Selected=0xEA4A1D17 - DockNode ID=0x00000006 Parent=0x00000002 SizeRef=1627,1038 Split=Y Selected=0x18B8C0DE - DockNode ID=0x00000007 Parent=0x00000006 SizeRef=465,379 CentralNode=1 Selected=0x18B8C0DE - DockNode ID=0x00000009 Parent=0x00000006 SizeRef=465,582 Selected=0xF02CD328 - +[Window][Rootex Editor] +Pos=0,0 +Size=1536,793 +Collapsed=0 + +[Window][Output] +Pos=0,498 +Size=891,295 +Collapsed=0 +DockId=0x00000003,0 + +[Window][Debug##Default] +Pos=256,142 +Size=400,400 +Collapsed=0 + +[Window][File System] +Pos=0,844 +Size=321,543 +Collapsed=0 +DockId=0x0000000E,0 + +[Window][Hierarchy] +Pos=0,866 +Size=321,521 +Collapsed=0 +DockId=0x0000000D,0 + +[Window][Entities] +Pos=0,626 +Size=388,285 +Collapsed=0 +DockId=0x0000000D,0 + +[Window][Toolbar] +Pos=893,498 +Size=266,295 +Collapsed=0 +DockId=0x00000004,0 + +[Window][Viewport] +Pos=0,28 +Size=1159,468 +Collapsed=0 +DockId=0x00000008,0 + +[Window][Inspector] +Pos=1161,211 +Size=375,582 +Collapsed=0 +DockId=0x00000009,0 + +[Window][File Viewer] +Pos=1451,28 +Size=469,379 +Collapsed=0 +DockId=0x00000007,1 + +[Window][Gizmo] +Pos=31,186 +Size=251,86 +Collapsed=0 + +[Window][Classes] +Pos=0,646 +Size=265,411 +Collapsed=0 +DockId=0x0000000E,1 + +[Window][Test] +Pos=60,60 +Size=79,66 +Collapsed=0 + +[Window][Viewport Tools] +Pos=0,626 +Size=388,285 +Collapsed=0 +DockId=0x0000000D,1 + +[Window][Choose Model File##ChooseModelComponentModel] +Pos=924,383 +Size=755,526 +Collapsed=0 + +[Window][Choose Specular texture##ChooseSpecularTexture] +Pos=1015,477 +Size=534,321 +Collapsed=0 + +[Window][Normal Texture ##Normal Texture ] +Pos=959,393 +Size=700,461 +Collapsed=0 + +[Window][Diffuse Texture ##Diffuse Texture ] +Pos=1022,405 +Size=627,471 +Collapsed=0 + +[Window][Choose File##ChooseFileDlgKey] +Pos=60,60 +Size=338,380 +Collapsed=0 + +[Window][Choose File2##ChooseFileDlgKey2] +Pos=963,447 +Size=539,437 +Collapsed=0 + +[Window][Specular Texture ##Specular Texture ] +Pos=939,429 +Size=711,477 +Collapsed=0 + +[Window][Sky Texture##Sky Texture] +Pos=923,377 +Size=666,443 +Collapsed=0 + +[Window][Choose Material##rootex/assets/materials/default.basic.rmat] +Pos=879,268 +Size=800,574 +Collapsed=0 + +[Window][Choose Material##Material] +Pos=1049,371 +Size=730,503 +Collapsed=0 + +[Window][Choose Material##game/assets/materials/handgunhandg.000.rmat] +Pos=60,60 +Size=528,156 +Collapsed=0 + +[Window][Choose Material##game/assets/materials/material.001.rmat] +Pos=60,60 +Size=528,156 +Collapsed=0 + +[Window][Choose Script##Script] +Pos=973,483 +Size=549,308 +Collapsed=0 + +[Window][Choose Music##Music] +Pos=875,299 +Size=747,545 +Collapsed=0 + +[Window][Choose RML Document##Document] +Pos=1347,342 +Size=745,480 +Collapsed=0 + +[Window][Scene] +Pos=1161,28 +Size=375,181 +Collapsed=0 +DockId=0x00000007,0 + +[Window][Choose Font##Font] +Pos=1053,427 +Size=587,403 +Collapsed=0 + +[Window][Debug Scene] +Pos=1754,65 +Size=750,643 +Collapsed=0 + +[Window][Load Scene] +Pos=1117,620 +Size=30,58 +Collapsed=0 + +[Window][Save] +Pos=1234,626 +Size=231,110 +Collapsed=0 + +[Window][Style Editor] +Pos=761,148 +Size=460,808 +Collapsed=0 + +[Window][Lua API Documentation] +Pos=653,347 +Size=1280,693 +Collapsed=0 + +[Window][File Editor] +Pos=0,28 +Size=1159,468 +Collapsed=0 +DockId=0x00000008,1 + +[Window][Content Browsers] +Pos=60,60 +Size=241,158 +Collapsed=0 + +[Window][Content Browser] +Pos=0,498 +Size=891,295 +Collapsed=0 +DockId=0x00000003,1 + +[Docking][Data] +DockSpace ID=0x654E7FDC Window=0xDC8952A0 Pos=0,28 Size=1536,765 Split=X + DockNode ID=0x00000001 Parent=0x654E7FDC SizeRef=1932,1359 Split=Y Selected=0x995B0CF8 + DockNode ID=0x00000008 Parent=0x00000001 SizeRef=1932,596 Selected=0x995B0CF8 + DockNode ID=0x0000000A Parent=0x00000001 SizeRef=1932,375 Split=X Selected=0xCB7211A8 + DockNode ID=0x00000003 Parent=0x0000000A SizeRef=1114,226 Selected=0x371352B7 + DockNode ID=0x00000004 Parent=0x0000000A SizeRef=333,226 Selected=0x507852CA + DockNode ID=0x00000002 Parent=0x654E7FDC SizeRef=626,1359 Split=X + DockNode ID=0x00000005 Parent=0x00000002 SizeRef=291,1038 Split=Y Selected=0xCD504759 + DockNode ID=0x0000000D Parent=0x00000005 SizeRef=353,818 Selected=0x8988DF52 + DockNode ID=0x0000000E Parent=0x00000005 SizeRef=353,543 Selected=0xEA4A1D17 + DockNode ID=0x00000006 Parent=0x00000002 SizeRef=1627,1038 Split=Y Selected=0x18B8C0DE + DockNode ID=0x00000007 Parent=0x00000006 SizeRef=465,379 CentralNode=1 Selected=0x18B8C0DE + DockNode ID=0x00000009 Parent=0x00000006 SizeRef=465,582 Selected=0xF02CD328 + diff --git a/rootex/common/types.h b/rootex/common/types.h index 2bbb2d88a..31b890937 100644 --- a/rootex/common/types.h +++ b/rootex/common/types.h @@ -96,7 +96,12 @@ using Optional = std::optional; #include /// std::vector template -using Vector = std::vector; +using Vector = std::vector; + +#include +/// std::unordered_set +template +using Unordered_set = std::unordered_set; Vector Split(const String& s, char delim); diff --git a/rootex/framework/scene.cpp b/rootex/framework/scene.cpp index 04688f1f5..c71897ec4 100644 --- a/rootex/framework/scene.cpp +++ b/rootex/framework/scene.cpp @@ -1,684 +1,705 @@ -#include "scene.h" - -#include "ecs_factory.h" -#include "resource_loader.h" -#include "scene_loader.h" -#include "systems/script_system.h" -#include "components/visual/camera_component.h" -#include "components/audio/audio_listener_component.h" - -static SceneID NextSceneID = ROOT_SCENE_ID + 1; -Vector Scene::s_Scenes; - -void to_json(JSON::json& j, const SceneSettings& s) -{ - j["preloads"] = s.preloads; - j["camera"] = s.camera; - j["listener"] = s.listener; - j["inputSchemes"] = s.inputSchemes; - j["startScheme"] = s.startScheme; -} - -void from_json(const JSON::json& j, SceneSettings& s) -{ - s.preloads = j.value("preloads", ResourceCollection()); - s.camera = j.value("camera", ROOT_SCENE_ID); - s.listener = j.value("listener", ROOT_SCENE_ID); - if (j["inputSchemes"].is_null()) - { - s.inputSchemes = {}; - } - else - { - s.inputSchemes = j.value("inputSchemes", HashMap()); - } - s.startScheme = j.value("startScheme", String()); -} - -void to_json(JSON::json& j, const Scene::ImportStyle& s) -{ - j = (int)s; -} - -void from_json(const JSON::json& j, Scene::ImportStyle& s) -{ - s = (Scene::ImportStyle)(int)j; -} - -void Scene::ResetNextID() -{ - NextSceneID = ROOT_SCENE_ID + 1; -} - -Ptr Scene::Create(const JSON::json& sceneData, const bool assignNewIDs) -{ - // Decide ID - SceneID thisSceneID; - if (sceneData.contains("ID")) - { - NextSceneID = std::max(NextSceneID, (SceneID)sceneData["ID"]); - if (!assignNewIDs) - { - thisSceneID = sceneData["ID"]; - } - else - { - thisSceneID = NextSceneID; - } - } - else - { - thisSceneID = NextSceneID; - } - NextSceneID++; - - // Decide how to import - if (sceneData.contains("importStyle") && sceneData["importStyle"] != ImportStyle::Local && sceneData.value("sceneFile", "") == "") - { - ERR("Found empty scene file path for an externally imported scene"); - } - - Ptr thisScene(std::make_unique( - thisSceneID, - sceneData.value("name", String("Untitled")), - sceneData.value("settings", SceneSettings()), - sceneData.value("importStyle", ImportStyle::Local), - sceneData.value("sceneFile", ""))); - - // Make entity and children scenes - if (sceneData.contains("entity")) - { - ECSFactory::FillEntity(thisScene->m_Entity, sceneData["entity"]); - } - if (sceneData.contains("children")) - { - for (auto& childScene : sceneData["children"]) - { - if (!thisScene->addChild(Create(childScene, assignNewIDs))) - { - WARN("Could not add child scene to " + thisScene->getName() + " scene"); - } - } - } - thisScene->m_IsScenePaused = sceneData.value("pause", true); - return thisScene; -} - -Ptr Scene::CreateFromFile(const String& sceneFile) -{ - if (Ref t = ResourceLoader::CreateTextResourceFile(sceneFile)) - { - if (t->isDirty()) - { - t->reimport(); - } - JSON::json importedScene = JSON::json::parse(t->getString()); - importedScene["importStyle"] = ImportStyle::External; - importedScene["sceneFile"] = sceneFile; - return Create(importedScene, true); - } - return nullptr; -} - -Ptr Scene::CreateEmpty() -{ - return Create(JSON::json::object(), false); -} - -Ptr Scene::CreateEmptyAtPath(const String& sceneFile) -{ - return Create({ { "entity", {} }, { "sceneFile", sceneFile } }, false); -} - -Ptr Scene::CreateRootScene() -{ - static bool called = false; - if (called) - { - ERR("Denied creating a second root scene. Scene hierarchy may be corrupted."); - return nullptr; - } - - Ptr root = std::make_unique(ROOT_SCENE_ID, "Root", SceneSettings(), ImportStyle::Local, ""); - - ECSFactory::FillRootEntity(root->getEntity()); - - called = true; - return root; -} - -Vector Scene::FindScenesByName(const String& name) -{ - Vector foundScenes; - for (auto& scene : s_Scenes) - { - if (scene->m_Name == name) - { - foundScenes.push_back(scene); - } - } - return foundScenes; -} - -Scene* Scene::FindSceneByID(const SceneID& id) -{ - for (auto& scene : s_Scenes) - { - if (scene->m_ID == id) - { - return scene; - } - } - return nullptr; -} - -const Vector& Scene::FindAllScenes() -{ - return s_Scenes; -} - -Scene* Scene::findScene(SceneID scene) -{ - if (scene == getID()) - { - return this; - } - for (auto& child : m_ChildrenScenes) - { - if (Scene* entityScene = child->findScene(scene)) - { - return entityScene; - } - } - return nullptr; -} - -void Scene::reimport() -{ - if (m_ImportStyle != ImportStyle::External) - { - WARN("Did not reimport local scene. Needs to be external to be reimported."); - return; - } - - Ref t = ResourceLoader::CreateTextResourceFile(m_SceneFile); - t->reimport(); - - const JSON::json& sceneData = JSON::json::parse(t->getString()); - m_Entity.clear(); - if (sceneData.contains("entity")) - { - ECSFactory::FillEntity(m_Entity, sceneData["entity"]); - } - - m_ChildrenScenes.clear(); - if (sceneData.contains("children")) - { - for (auto& childScene : sceneData["children"]) - { - if (!addChild(Create(childScene, false))) - { - WARN("Could not add child scene to " + getName() + " scene"); - } - } - } -} - -void Scene::onLoad() -{ - m_Entity.onAllEntitiesAdded(); - for (auto& child : m_ChildrenScenes) - { - child->onLoad(); - } -} - -bool Scene::snatchChild(Scene* child) -{ - if (!checkCycle(child)) - { - return false; - } - - Vector>& children = child->getParent()->getChildren(); - for (int i = 0; i < children.size(); i++) - { - if (children.at(i).get() == child) - { - m_ChildrenScenes.push_back(std::move(children[i])); - children.erase(children.begin() + i); - } - } - child->m_ParentScene = this; - return true; -} - -bool Scene::checkCycle(Scene* child) -{ - if (child->findScene(m_ID) != nullptr) - { - WARN("Tried to make a scene its own child's child"); - return false; - } - return true; -} - -bool Scene::addChild(Ptr& child) -{ - if (!child) - { - WARN("Tried to add a null scene to: " + getFullName() + ". Denied."); - return false; - } - if (!checkCycle(child.get())) - { - return false; - } - auto& findIt = std::find(m_ChildrenScenes.begin(), m_ChildrenScenes.end(), child); - if (findIt == m_ChildrenScenes.end()) - { - child->m_ParentScene = this; - if (getID() != ROOT_SCENE_ID && getName() != "EditorCamera" && getName() != "EditorGrid") - { - for (auto&& inputScheme : child->getSettings().inputSchemes) - { - m_Settings.inputSchemes.insert(inputScheme); - } - } - m_ChildrenScenes.emplace_back(std::move(child)); - ScriptSystem::GetSingleton()->addEnterScriptEntity(&m_ChildrenScenes.back()->getEntity()); - } - else - { - ERR("Tried to add a duplicate child " + child->getFullName() + " to " + getFullName()); - return false; - } - return true; -} - -bool Scene::removeChild(Scene* toRemove) -{ - for (auto& child = m_ChildrenScenes.begin(); child != m_ChildrenScenes.end(); child++) - { - if ((*child).get() == toRemove) - { - m_ChildrenScenes.erase(child); - return true; - } - } - return false; -} - -bool Scene::isReservedName(const String& sceneName) -{ - static Vector reservedNames { "pause", "pauseUI" }; - for (auto& reservedName : reservedNames) - { - if (reservedName == sceneName) - { - WARN("Cannot use reserved scene names"); - return true; - } - } - return false; -} - -void Scene::setName(const String& name) -{ - m_Name = name; - m_FullName = name + " # " + std::to_string(m_ID); -} - -JSON::json Scene::getJSON() const -{ - JSON::json j; - - j["ID"] = m_ID; - j["name"] = m_Name; - j["importStyle"] = m_ImportStyle; - j["sceneFile"] = m_SceneFile; - j["entity"] = m_Entity.getJSON(); - j["settings"] = m_Settings; - j["pause"] = m_IsScenePaused; - - j["children"] = JSON::json::array(); - for (auto& child : m_ChildrenScenes) - { - j["children"].push_back(child->getJSON()); - } - - return j; -} - -Scene::Scene(SceneID id, const String& name, const SceneSettings& settings, ImportStyle importStyle, const String& sceneFile) - : m_Name(name) - , m_ID(id) - , m_Settings(settings) - , m_ImportStyle(importStyle) - , m_SceneFile(sceneFile) - , m_Entity(this) -{ - setName(m_Name); - s_Scenes.push_back(this); -} - -Scene::~Scene() -{ - int index; - for (int i = 0; i < s_Scenes.size(); i++) - { - if (s_Scenes[i] == this) - { - index = i; - } - } - s_Scenes.erase(s_Scenes.begin() + index); - m_ChildrenScenes.clear(); - PRINT("Deleted scene: " + getFullName()); -} - -void SceneSettings::drawCameraSceneSelectables(Scene* scene, SceneID& toSet) -{ - if (scene->getEntity().getComponent()) - { - if (ImGui::Selectable(scene->getFullName().c_str())) - { - toSet = scene->getID(); - } - } - for (auto& child : scene->getChildren()) - { - drawCameraSceneSelectables(child.get(), toSet); - } -} -void SceneSettings::drawListenerSceneSelectables(Scene* scene, SceneID& toSet) -{ - if (scene->getEntity().getComponent()) - { - if (ImGui::Selectable(scene->getFullName().c_str())) - { - toSet = scene->getID(); - } - } - for (auto& child : scene->getChildren()) - { - drawListenerSceneSelectables(child.get(), toSet); - } -} - -void SceneSettings::draw() -{ - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() * 2.0f / 3.0f); - if (ImGui::ListBoxHeader("Preloads")) - { - int toRemove = -1; - for (int p = 0; p < preloads.size(); p++) - { - ImGui::PushID(p); - - if (ImGui::SmallButton("-")) - { - toRemove = p; - } - ImGui::SameLine(); - ImGui::LabelText(ResourceFile::s_TypeNames.at((ResourceFile::Type)preloads[p].first).c_str(), "%s", preloads[p].second.c_str()); - - ImGui::PopID(); - } - - if (toRemove >= 0) - { - preloads.erase(preloads.begin() + toRemove); - } - - ImGui::ListBoxFooter(); - } - if (ImGui::Button("Add Preload")) - { - ImGui::OpenPopup("Preloads Selection"); - } - - if (ImGui::BeginPopup("Preloads Selection")) - { - int i = 0; - for (auto& [resType, resFiles] : ResourceLoader::GetResources()) - { - for (auto& resFile : resFiles) - { - Ref res = resFile.lock(); - if (!res) - { - continue; - } - - ImGui::PushID(i++); - - String path = res->getPath().generic_string(); - - auto& findIt = std::find(preloads.begin(), preloads.end(), Pair(resType, path)); - - bool enabled = findIt != preloads.end(); - if (ImGui::Checkbox(path.c_str(), &enabled)) - { - if (enabled) - { - preloads.push_back({ resType, path }); - } - else - { - preloads.erase(findIt); - } - } - ImGui::SameLine(); - ImGui::BulletText("%s", ResourceFile::s_TypeNames.at(resType).c_str()); - - ImGui::PopID(); - } - } - - ImGui::EndPopup(); - } - - Scene* cameraScene = SceneLoader::GetSingleton()->getRootScene()->findScene(camera); - if (!cameraScene) - { - cameraScene = SceneLoader::GetSingleton()->getRootScene(); - } - if (ImGui::BeginCombo("Camera", cameraScene->getFullName().c_str())) - { - drawCameraSceneSelectables(SceneLoader::GetSingleton()->getRootScene(), camera); - ImGui::EndCombo(); - } - - Scene* listenerScene = SceneLoader::GetSingleton()->getRootScene()->findScene(listener); - if (!listenerScene) - { - listenerScene = SceneLoader::GetSingleton()->getRootScene(); - } - if (ImGui::BeginCombo("Listener", listenerScene->getFullName().c_str())) - { - drawListenerSceneSelectables(SceneLoader::GetSingleton()->getRootScene(), listener); - ImGui::EndCombo(); - } - - if (ImGui::BeginCombo("Start Scheme", startScheme.c_str())) - { - for (auto& [name, inputScheme] : inputSchemes) - { - if (ImGui::MenuItem(name.c_str())) - { - startScheme = name; - } - } - - ImGui::EndCombo(); - } - - ImGui::Text("Input Schemes:"); - ImGui::Separator(); - int i = 0; - const String* inputSchemeToRemove = nullptr; - for (auto& [name, inputScheme] : inputSchemes) - { - ImGui::PushID(i); - ImGui::Text(name.c_str()); - ImGui::Checkbox("Active", &inputScheme.isActive); - ImGui::SetNextItemWidth(ImGui::GetFontSize() * 100); - if (ImGui::ListBoxHeader(name.c_str())) - { - int boolDeletion = -1; - for (int p = 0; p < inputScheme.bools.size(); p++) - { - InputDescription& boolInput = inputScheme.bools[p]; - ImGui::PushID(i); - - if (ImGui::SmallButton("x")) - { - boolDeletion = p; - } - ImGui::SameLine(); - - drawInputScheme(boolInput); - - ImGui::PopID(); - i++; - } - int floatDeletion = -1; - for (int p = 0; p < inputScheme.floats.size(); p++) - { - InputDescription& floatInput = inputScheme.floats[p]; - ImGui::PushID(i); - - if (ImGui::SmallButton("x")) - { - floatDeletion = p; - } - ImGui::SameLine(); - - drawInputScheme(floatInput); - - ImGui::PopID(); - i++; - } - - if (boolDeletion != -1) - { - inputScheme.bools.erase(inputScheme.bools.begin() + boolDeletion); - } - if (floatDeletion != -1) - { - inputScheme.floats.erase(inputScheme.floats.begin() + floatDeletion); - } - - ImGui::ListBoxFooter(); - } - - static int type = 0; - ImGui::Combo("Type", &type, "Bool\0Float\0"); - ImGui::SameLine(); - if (ImGui::Button("Add Input")) - { - InputDescription inputDesc; - inputDesc.device = Device::Mouse; - inputDesc.button = MouseButton::MouseButtonLeft; - inputDesc.inputEvent = name + "::GameBoolEvent"; - - if (type == 0) - { - inputScheme.bools.push_back(inputDesc); - } - else if (type == 1) - { - inputScheme.floats.push_back(inputDesc); - } - } - if (ImGui::Button("Remove Scheme")) - { - inputSchemeToRemove = &name; - } - ImGui::PopID(); - ImGui::Separator(); - i++; - } - - if (inputSchemeToRemove) - { - inputSchemes.erase(*inputSchemeToRemove); - startScheme = ""; - } - - static String newSchemeName = "New Scheme"; - ImGui::InputText("##New Scheme", &newSchemeName); - ImGui::SameLine(); - if (ImGui::Button("Add Scheme")) - { - inputSchemes.insert({ newSchemeName, InputScheme() }); - } -} - -void SceneSettings::drawInputScheme(InputDescription& inputDesc) -{ - Device originalDevice = inputDesc.device; - int device = (int)originalDevice; - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() / 3.0f); - if (ImGui::Combo("##device", &device, "Mouse\0Keyboard\0Pad1\0Pad2\0")) - { - inputDesc.device = (Device)device; - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() / 3.0f); - if (inputDesc.device == Device::Mouse) - { - inputDesc.button = originalDevice == inputDesc.device ? inputDesc.button : 0; - auto mouseKeys = InputManager::GetMouseButtonNames(); - char buffer[20] = {}; - InputManager::GetSingleton()->getMouse()->GetButtonName(inputDesc.button, buffer, 20); - String key = buffer; - Array mouseKeysBuffer; - int currentKey = 0; - for (int i = 0; i < mouseKeys.size(); i++) - { - mouseKeysBuffer[i] = mouseKeys[i].c_str(); - currentKey = (key == mouseKeys[i]) ? i : currentKey; - } - ImGui::Combo("##mouseInput", ¤tKey, mouseKeysBuffer.data(), mouseKeysBuffer.size()); - inputDesc.button = InputManager::GetSingleton()->getMouse()->GetButtonByName(mouseKeys[currentKey].c_str()); - } - else if (inputDesc.device == Device::Keyboard) - { - inputDesc.button = originalDevice == inputDesc.device ? inputDesc.button : 0; - auto keyboardKeys = InputManager::GetKeyboardButtonNames(); - char buffer[20] = {}; - InputManager::GetSingleton()->getKeyboard()->GetButtonName(inputDesc.button, buffer, 20); - String key = buffer; - Array keyboardKeysBuffer; - int currentKey = 0; - for (int i = 0; i < keyboardKeys.size(); i++) - { - keyboardKeysBuffer[i] = keyboardKeys[i].c_str(); - currentKey = (key == keyboardKeys[i]) ? i : currentKey; - } - ImGui::Combo("", ¤tKey, keyboardKeysBuffer.data(), keyboardKeysBuffer.size()); - inputDesc.button = InputManager::GetSingleton()->getKeyboard()->GetButtonByName(keyboardKeys[currentKey].c_str()); - } - else if (inputDesc.device == Device::Pad1 || inputDesc.device == Device::Pad2) - { - inputDesc.button = originalDevice == inputDesc.device ? inputDesc.button : 0; - auto padKeys = InputManager::GetPadButtonNames(); - char buffer[20] = {}; - InputManager::GetSingleton()->getPad1()->GetButtonName(inputDesc.button, buffer, 20); - String key = buffer; - Array padKeysBuffer; - int currentKey = 0; - for (int i = 0; i < padKeys.size(); i++) - { - padKeysBuffer[i] = padKeys[i].c_str(); - currentKey = (key == padKeys[i]) ? i : currentKey; - } - ImGui::Combo("##padInput", ¤tKey, padKeysBuffer.data(), padKeysBuffer.size()); - inputDesc.button = InputManager::GetSingleton()->getPad1()->GetButtonByName(padKeys[currentKey].c_str()); - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() / 3.0f); - ImGui::InputTextWithHint("##event", "Event", &inputDesc.inputEvent); -} +#include "scene.h" + +#include "ecs_factory.h" +#include "resource_loader.h" +#include "scene_loader.h" +#include "systems/script_system.h" +#include "components/visual/camera_component.h" +#include "components/audio/audio_listener_component.h" + +static SceneID NextSceneID = ROOT_SCENE_ID + 1; +// AARYA +Scene* rootScene; +Scene* editorGrid; +Scene* editorCamera; +Vector Scene::s_Scenes; + +void to_json(JSON::json& j, const SceneSettings& s) +{ + j["preloads"] = s.preloads; + j["camera"] = s.camera; + j["listener"] = s.listener; + j["inputSchemes"] = s.inputSchemes; + j["startScheme"] = s.startScheme; +} + +void from_json(const JSON::json& j, SceneSettings& s) +{ + s.preloads = j.value("preloads", ResourceCollection()); + s.camera = j.value("camera", ROOT_SCENE_ID); + s.listener = j.value("listener", ROOT_SCENE_ID); + if (j["inputSchemes"].is_null()) + { + s.inputSchemes = {}; + } + else + { + s.inputSchemes = j.value("inputSchemes", HashMap()); + } + s.startScheme = j.value("startScheme", String()); +} + +void to_json(JSON::json& j, const Scene::ImportStyle& s) +{ + j = (int)s; +} + +void from_json(const JSON::json& j, Scene::ImportStyle& s) +{ + s = (Scene::ImportStyle)(int)j; +} + +void Scene::ResetNextID() +{ + NextSceneID = ROOT_SCENE_ID + 1; +} + +Ptr Scene::Create(const JSON::json& sceneData, const bool assignNewIDs) +{ + // Decide ID + SceneID thisSceneID; + if (sceneData.contains("ID")) + { + NextSceneID = std::max(NextSceneID, (SceneID)sceneData["ID"]); + if (!assignNewIDs) + { + thisSceneID = sceneData["ID"]; + } + else + { + thisSceneID = NextSceneID; + } + } + else + { + thisSceneID = NextSceneID; + } + NextSceneID++; + + // Decide how to import + if (sceneData.contains("importStyle") && sceneData["importStyle"] != ImportStyle::Local && sceneData.value("sceneFile", "") == "") + { + ERR("Found empty scene file path for an externally imported scene"); + } + + Ptr thisScene(std::make_unique( + thisSceneID, + sceneData.value("name", String("Untitled")), + sceneData.value("settings", SceneSettings()), + sceneData.value("importStyle", ImportStyle::Local), + sceneData.value("sceneFile", ""))); + + // Make entity and children scenes + if (sceneData.contains("entity")) + { + ECSFactory::FillEntity(thisScene->m_Entity, sceneData["entity"]); + } + if (sceneData.contains("children")) + { + for (auto& childScene : sceneData["children"]) + { + if (!thisScene->addChild(Create(childScene, assignNewIDs))) + { + WARN("Could not add child scene to " + thisScene->getName() + " scene"); + } + } + } + thisScene->m_IsScenePaused = sceneData.value("pause", true); + return thisScene; +} + +Ptr Scene::CreateFromFile(const String& sceneFile) +{ + if (Ref t = ResourceLoader::CreateTextResourceFile(sceneFile)) + { + if (t->isDirty()) + { + t->reimport(); + } + JSON::json importedScene = JSON::json::parse(t->getString()); + importedScene["importStyle"] = ImportStyle::External; + importedScene["sceneFile"] = sceneFile; + return Create(importedScene, true); + } + return nullptr; +} + +Ptr Scene::CreateEmpty() +{ + return Create(JSON::json::object(), false); +} + +Ptr Scene::CreateEmptyAtPath(const String& sceneFile) +{ + return Create({ { "entity", {} }, { "sceneFile", sceneFile } }, false); +} + +Ptr Scene::CreateRootScene() +{ + static bool called = false; + if (called) + { + ERR("Denied creating a second root scene. Scene hierarchy may be corrupted."); + return nullptr; + } + + Ptr root = std::make_unique(ROOT_SCENE_ID, "Root", SceneSettings(), ImportStyle::Local, ""); + Ptr editorGrid = std::make_unique(ROOT_SCENE_ID, "EditorGrid", SceneSettings(), ImportStyle::Local, ""); + Ptr editorCamera = std::make_unique(ROOT_SCENE_ID, "EditorCamera", SceneSettings(), ImportStyle::Local, ""); + + // AARYA + + ECSFactory::FillRootEntity(root->getEntity()); + + called = true; + return root; +} + +Vector Scene::FindScenesByName(const String& name) +{ + Vector foundScenes; + for (auto& scene : s_Scenes) + { + if (scene->m_Name == name) + { + foundScenes.push_back(scene); + } + } + return foundScenes; +} + +Scene* Scene::FindSceneByID(const SceneID& id) +{ + for (auto& scene : s_Scenes) + { + if (scene->m_ID == id) + { + return scene; + } + } + return nullptr; +} + +const Vector& Scene::FindAllScenes() +{ + return s_Scenes; +} + +Scene* Scene::findScene(SceneID scene) +{ + if (scene == getID()) + { + return this; + } + for (auto& child : m_ChildrenScenes) + { + if (Scene* entityScene = child->findScene(scene)) + { + return entityScene; + } + } + return nullptr; +} + +void Scene::reimport() +{ + if (m_ImportStyle != ImportStyle::External) + { + WARN("Did not reimport local scene. Needs to be external to be reimported."); + return; + } + + Ref t = ResourceLoader::CreateTextResourceFile(m_SceneFile); + t->reimport(); + + const JSON::json& sceneData = JSON::json::parse(t->getString()); + m_Entity.clear(); + if (sceneData.contains("entity")) + { + ECSFactory::FillEntity(m_Entity, sceneData["entity"]); + } + + m_ChildrenScenes.clear(); + if (sceneData.contains("children")) + { + for (auto& childScene : sceneData["children"]) + { + if (!addChild(Create(childScene, false))) + { + WARN("Could not add child scene to " + getName() + " scene"); + } + } + } +} + +void Scene::onLoad() +{ + m_Entity.onAllEntitiesAdded(); + for (auto& child : m_ChildrenScenes) + { + child->onLoad(); + } +} + +bool Scene::snatchChild(Scene* child) +{ + if (!checkCycle(child)) + { + return false; + } + + Unordered_set>& children = child->getParent()->getChildren(); + for (auto& child_scene : children) + { + if (child_scene.get() == child) + { + m_ChildrenScenes.insert(std::move(child_scene)); + children.erase(child_scene); + } + } + + /* + for (int i = 0; i < children.size(); i++) + { + if (children.at(i).get() == child) + { + m_ChildrenScenes.insert(std::move(children[i])); + children.erase(children.begin() + i); + } + } + */ + child->m_ParentScene = this; + return true; +} + +bool Scene::checkCycle(Scene* child) +{ + if (child->findScene(m_ID) != nullptr) + { + WARN("Tried to make a scene its own child's child"); + return false; + } + return true; +} + +bool Scene::addChild(Ptr& child) +{ + if (!child) + { + WARN("Tried to add a null scene to: " + getFullName() + ". Denied."); + return false; + } + if (!checkCycle(child.get())) + { + return false; + } + auto& findIt = std::find(m_ChildrenScenes.begin(), m_ChildrenScenes.end(), child); + if (findIt == m_ChildrenScenes.end()) + { + child->m_ParentScene = this; + if (getID() != ROOT_SCENE_ID && getName() != "EditorCamera" && getName() != "EditorGrid") + { + for (auto&& inputScheme : child->getSettings().inputSchemes) + { + m_Settings.inputSchemes.insert(inputScheme); + } + } + m_ChildrenScenes.insert(std::move(child)); + + //aarya + //ScriptSystem::GetSingleton()->addEnterScriptEntity(&m_ChildrenScenes.back()->getEntity()); + } + else + { + ERR("Tried to add a duplicate child " + child->getFullName() + " to " + getFullName()); + return false; + } + return true; +} + +bool Scene::removeChild(Scene* toRemove) +{ + for (auto& child = m_ChildrenScenes.begin(); child != m_ChildrenScenes.end(); child++) + { + if ((*child).get() == toRemove) + { + m_ChildrenScenes.erase(child); + return true; + } + } + return false; +} + +bool Scene::isReservedName(const String& sceneName) +{ + static Vector reservedNames { "pause", "pauseUI" }; + for (auto& reservedName : reservedNames) + { + if (reservedName == sceneName) + { + WARN("Cannot use reserved scene names"); + return true; + } + } + return false; +} + +void Scene::setName(const String& name) +{ + m_Name = name; + m_FullName = name + " # " + std::to_string(m_ID); +} + +JSON::json Scene::getJSON() const +{ + JSON::json j; + + j["ID"] = m_ID; + j["name"] = m_Name; + j["importStyle"] = m_ImportStyle; + j["sceneFile"] = m_SceneFile; + j["entity"] = m_Entity.getJSON(); + j["settings"] = m_Settings; + j["pause"] = m_IsScenePaused; + + j["children"] = JSON::json::array(); + for (auto& child : m_ChildrenScenes) + { + j["children"].push_back(child->getJSON()); + } + + return j; +} + +Scene::Scene(SceneID id, const String& name, const SceneSettings& settings, ImportStyle importStyle, const String& sceneFile) + : m_Name(name) + , m_ID(id) + , m_Settings(settings) + , m_ImportStyle(importStyle) + , m_SceneFile(sceneFile) + , m_Entity(this) +{ + setName(m_Name); + s_Scenes.push_back(this); +} + +Scene::~Scene() +{ + int index; + for (int i = 0; i < s_Scenes.size(); i++) + { + if (s_Scenes[i] == this) + { + index = i; + } + } + s_Scenes.erase(s_Scenes.begin() + index); + m_ChildrenScenes.clear(); + PRINT("Deleted scene: " + getFullName()); +} + +void SceneSettings::drawCameraSceneSelectables(Scene* scene, SceneID& toSet) +{ + if (scene->getEntity().getComponent()) + { + if (ImGui::Selectable(scene->getFullName().c_str())) + { + toSet = scene->getID(); + } + } + for (auto& child : scene->getChildren()) + { + drawCameraSceneSelectables(child.get(), toSet); + } +} +void SceneSettings::drawListenerSceneSelectables(Scene* scene, SceneID& toSet) +{ + if (scene->getEntity().getComponent()) + { + if (ImGui::Selectable(scene->getFullName().c_str())) + { + toSet = scene->getID(); + } + } + for (auto& child : scene->getChildren()) + { + drawListenerSceneSelectables(child.get(), toSet); + } +} + +void SceneSettings::draw() +{ + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() * 2.0f / 3.0f); + if (ImGui::ListBoxHeader("Preloads")) + { + int toRemove = -1; + for (int p = 0; p < preloads.size(); p++) + { + ImGui::PushID(p); + + if (ImGui::SmallButton("-")) + { + toRemove = p; + } + ImGui::SameLine(); + ImGui::LabelText(ResourceFile::s_TypeNames.at((ResourceFile::Type)preloads[p].first).c_str(), "%s", preloads[p].second.c_str()); + + ImGui::PopID(); + } + + if (toRemove >= 0) + { + preloads.erase(preloads.begin() + toRemove); + } + + ImGui::ListBoxFooter(); + } + if (ImGui::Button("Add Preload")) + { + ImGui::OpenPopup("Preloads Selection"); + } + + if (ImGui::BeginPopup("Preloads Selection")) + { + int i = 0; + for (auto& [resType, resFiles] : ResourceLoader::GetResources()) + { + for (auto& resFile : resFiles) + { + Ref res = resFile.lock(); + if (!res) + { + continue; + } + + ImGui::PushID(i++); + + String path = res->getPath().generic_string(); + + auto& findIt = std::find(preloads.begin(), preloads.end(), Pair(resType, path)); + + bool enabled = findIt != preloads.end(); + if (ImGui::Checkbox(path.c_str(), &enabled)) + { + if (enabled) + { + preloads.push_back({ resType, path }); + } + else + { + preloads.erase(findIt); + } + } + ImGui::SameLine(); + ImGui::BulletText("%s", ResourceFile::s_TypeNames.at(resType).c_str()); + + ImGui::PopID(); + } + } + + ImGui::EndPopup(); + } + + Scene* cameraScene = SceneLoader::GetSingleton()->getRootScene()->findScene(camera); + if (!cameraScene) + { + cameraScene = SceneLoader::GetSingleton()->getRootScene(); + } + if (ImGui::BeginCombo("Camera", cameraScene->getFullName().c_str())) + { + drawCameraSceneSelectables(SceneLoader::GetSingleton()->getRootScene(), camera); + ImGui::EndCombo(); + } + + Scene* listenerScene = SceneLoader::GetSingleton()->getRootScene()->findScene(listener); + if (!listenerScene) + { + listenerScene = SceneLoader::GetSingleton()->getRootScene(); + } + if (ImGui::BeginCombo("Listener", listenerScene->getFullName().c_str())) + { + drawListenerSceneSelectables(SceneLoader::GetSingleton()->getRootScene(), listener); + ImGui::EndCombo(); + } + + if (ImGui::BeginCombo("Start Scheme", startScheme.c_str())) + { + for (auto& [name, inputScheme] : inputSchemes) + { + if (ImGui::MenuItem(name.c_str())) + { + startScheme = name; + } + } + + ImGui::EndCombo(); + } + + ImGui::Text("Input Schemes:"); + ImGui::Separator(); + int i = 0; + const String* inputSchemeToRemove = nullptr; + for (auto& [name, inputScheme] : inputSchemes) + { + ImGui::PushID(i); + ImGui::Text(name.c_str()); + ImGui::Checkbox("Active", &inputScheme.isActive); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 100); + if (ImGui::ListBoxHeader(name.c_str())) + { + int boolDeletion = -1; + for (int p = 0; p < inputScheme.bools.size(); p++) + { + InputDescription& boolInput = inputScheme.bools[p]; + ImGui::PushID(i); + + if (ImGui::SmallButton("x")) + { + boolDeletion = p; + } + ImGui::SameLine(); + + drawInputScheme(boolInput); + + ImGui::PopID(); + i++; + } + int floatDeletion = -1; + for (int p = 0; p < inputScheme.floats.size(); p++) + { + InputDescription& floatInput = inputScheme.floats[p]; + ImGui::PushID(i); + + if (ImGui::SmallButton("x")) + { + floatDeletion = p; + } + ImGui::SameLine(); + + drawInputScheme(floatInput); + + ImGui::PopID(); + i++; + } + + if (boolDeletion != -1) + { + inputScheme.bools.erase(inputScheme.bools.begin() + boolDeletion); + } + if (floatDeletion != -1) + { + inputScheme.floats.erase(inputScheme.floats.begin() + floatDeletion); + } + + ImGui::ListBoxFooter(); + } + + static int type = 0; + ImGui::Combo("Type", &type, "Bool\0Float\0"); + ImGui::SameLine(); + if (ImGui::Button("Add Input")) + { + InputDescription inputDesc; + inputDesc.device = Device::Mouse; + inputDesc.button = MouseButton::MouseButtonLeft; + inputDesc.inputEvent = name + "::GameBoolEvent"; + + if (type == 0) + { + inputScheme.bools.push_back(inputDesc); + } + else if (type == 1) + { + inputScheme.floats.push_back(inputDesc); + } + } + if (ImGui::Button("Remove Scheme")) + { + inputSchemeToRemove = &name; + } + ImGui::PopID(); + ImGui::Separator(); + i++; + } + + if (inputSchemeToRemove) + { + inputSchemes.erase(*inputSchemeToRemove); + startScheme = ""; + } + + static String newSchemeName = "New Scheme"; + ImGui::InputText("##New Scheme", &newSchemeName); + ImGui::SameLine(); + if (ImGui::Button("Add Scheme")) + { + inputSchemes.insert({ newSchemeName, InputScheme() }); + } +} + +void SceneSettings::drawInputScheme(InputDescription& inputDesc) +{ + Device originalDevice = inputDesc.device; + int device = (int)originalDevice; + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() / 3.0f); + if (ImGui::Combo("##device", &device, "Mouse\0Keyboard\0Pad1\0Pad2\0")) + { + inputDesc.device = (Device)device; + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() / 3.0f); + if (inputDesc.device == Device::Mouse) + { + inputDesc.button = originalDevice == inputDesc.device ? inputDesc.button : 0; + auto mouseKeys = InputManager::GetMouseButtonNames(); + char buffer[20] = {}; + InputManager::GetSingleton()->getMouse()->GetButtonName(inputDesc.button, buffer, 20); + String key = buffer; + Array mouseKeysBuffer; + int currentKey = 0; + for (int i = 0; i < mouseKeys.size(); i++) + { + mouseKeysBuffer[i] = mouseKeys[i].c_str(); + currentKey = (key == mouseKeys[i]) ? i : currentKey; + } + ImGui::Combo("##mouseInput", ¤tKey, mouseKeysBuffer.data(), mouseKeysBuffer.size()); + inputDesc.button = InputManager::GetSingleton()->getMouse()->GetButtonByName(mouseKeys[currentKey].c_str()); + } + else if (inputDesc.device == Device::Keyboard) + { + inputDesc.button = originalDevice == inputDesc.device ? inputDesc.button : 0; + auto keyboardKeys = InputManager::GetKeyboardButtonNames(); + char buffer[20] = {}; + InputManager::GetSingleton()->getKeyboard()->GetButtonName(inputDesc.button, buffer, 20); + String key = buffer; + Array keyboardKeysBuffer; + int currentKey = 0; + for (int i = 0; i < keyboardKeys.size(); i++) + { + keyboardKeysBuffer[i] = keyboardKeys[i].c_str(); + currentKey = (key == keyboardKeys[i]) ? i : currentKey; + } + ImGui::Combo("", ¤tKey, keyboardKeysBuffer.data(), keyboardKeysBuffer.size()); + inputDesc.button = InputManager::GetSingleton()->getKeyboard()->GetButtonByName(keyboardKeys[currentKey].c_str()); + } + else if (inputDesc.device == Device::Pad1 || inputDesc.device == Device::Pad2) + { + inputDesc.button = originalDevice == inputDesc.device ? inputDesc.button : 0; + auto padKeys = InputManager::GetPadButtonNames(); + char buffer[20] = {}; + InputManager::GetSingleton()->getPad1()->GetButtonName(inputDesc.button, buffer, 20); + String key = buffer; + Array padKeysBuffer; + int currentKey = 0; + for (int i = 0; i < padKeys.size(); i++) + { + padKeysBuffer[i] = padKeys[i].c_str(); + currentKey = (key == padKeys[i]) ? i : currentKey; + } + ImGui::Combo("##padInput", ¤tKey, padKeysBuffer.data(), padKeysBuffer.size()); + inputDesc.button = InputManager::GetSingleton()->getPad1()->GetButtonByName(padKeys[currentKey].c_str()); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() / 3.0f); + ImGui::InputTextWithHint("##event", "Event", &inputDesc.inputEvent); +} diff --git a/rootex/framework/scene.h b/rootex/framework/scene.h index 24a175ddd..01adccb96 100644 --- a/rootex/framework/scene.h +++ b/rootex/framework/scene.h @@ -51,7 +51,7 @@ class Scene Entity m_Entity; Scene* m_ParentScene = nullptr; - Vector> m_ChildrenScenes; + Unordered_set> m_ChildrenScenes; bool checkCycle(Scene* child); @@ -85,7 +85,7 @@ class Scene JSON::json getJSON() const; bool& getIsScenePaused() { return m_IsScenePaused; } void setIsScenePaused(bool pause) { m_IsScenePaused = pause; } - Vector>& getChildren() { return m_ChildrenScenes; } + Unordered_set>& getChildren() { return m_ChildrenScenes; } SceneID getID() const { return m_ID; } ImportStyle getImportStyle() const { return m_ImportStyle; } String getScenePath() const { return m_SceneFile; }