From eaa61ee9817c9daf683c3f88d2a4dd0651b82236 Mon Sep 17 00:00:00 2001 From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com> Date: Sun, 11 May 2025 00:30:31 -0500 Subject: [PATCH] switch to useing CLion and started on Project Creator && Fixed Crash on Viewport movve --- .idea/.gitignore | 8 + .idea/.name | 1 + .idea/Create-Engine.iml | 2 + .idea/betterCommentsSettings.xml | 31 ++ .idea/editor.xml | 344 ++++++++++++++++++++ .idea/material_theme_project_new.xml | 10 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + .idea/vcs.xml | 7 + CMakeLists.txt | 63 ++++ imgui.ini | 14 +- src/build/imgui.ini | 67 ++++ src/src/Components/AudioPlayerComponent.cpp | 1 + src/src/Components/TilemapComponent.cpp | 1 + src/src/Engine.cpp | 89 ++--- src/src/Engine.h | 4 +- src/src/Renderer.cpp | 1 + src/src/core/functions/ProjectManager.cpp | 148 +++++++++ src/src/core/functions/ProjectManager.h | 8 + src/src/core/utils/ExceptionHandler.cpp | 7 +- src/src/core/utils/FileDialog.cpp | 1 + src/src/core/utils/FileDialog.h | 1 + 22 files changed, 772 insertions(+), 51 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/Create-Engine.iml create mode 100644 .idea/betterCommentsSettings.xml create mode 100644 .idea/editor.xml create mode 100644 .idea/material_theme_project_new.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 CMakeLists.txt create mode 100644 src/build/imgui.ini diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..8f78700 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +CreateEngine \ No newline at end of file diff --git a/.idea/Create-Engine.iml b/.idea/Create-Engine.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/Create-Engine.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/betterCommentsSettings.xml b/.idea/betterCommentsSettings.xml new file mode 100644 index 0000000..4f152ed --- /dev/null +++ b/.idea/betterCommentsSettings.xml @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..25c6c37 --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,344 @@ + + + + + \ No newline at end of file diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..79c85c6 --- /dev/null +++ b/.idea/material_theme_project_new.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..094c27b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..108b7f6 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ef77ca7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.15) +project(CreateEngine VERSION 1.0 LANGUAGES C CXX) + +# --- Standards --- +set(CMAKE_C_STANDARD 99) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# --- Compiler flags --- +if(MSVC) + add_compile_definitions(GLM_ENABLE_EXPERIMENTAL) + add_compile_options(/W4 /Zi) +else() + add_compile_definitions(GLM_ENABLE_EXPERIMENTAL) + add_compile_options(-Wall -g) + add_compile_options(-O2 -static -static-libstdc++ -static-libgcc) +endif() + +# --- Include directories --- +include_directories( + ${CMAKE_SOURCE_DIR}/src/include + ${CMAKE_SOURCE_DIR}/src/include/lua + ${CMAKE_SOURCE_DIR}/src/vendor + ${CMAKE_SOURCE_DIR}/src/vendor/imgui + ${CMAKE_SOURCE_DIR}/src/vendor/imguizmo + ${CMAKE_SOURCE_DIR}/src/vendor/box2d + ${CMAKE_SOURCE_DIR}/src/vendor/box2d/include + ${CMAKE_SOURCE_DIR}/src/vendor/xxhash + ${CMAKE_SOURCE_DIR}/src/vendor/miniaudio +) + +# --- Gather source files --- +file(GLOB_RECURSE SOURCE_FILES + ${CMAKE_SOURCE_DIR}/src/src/*.cpp + ${CMAKE_SOURCE_DIR}/src/src/*.c + ${CMAKE_SOURCE_DIR}/src/vendor/*.cpp + ${CMAKE_SOURCE_DIR}/src/vendor/*.c + ${CMAKE_SOURCE_DIR}/src/include/lua/*.c +) + + +# --- Define target --- +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) + +# --- Link libraries --- +target_link_libraries(${PROJECT_NAME} PRIVATE + glfw3 + glew32 + opengl32 + gdi32 + yaml-cpp + comdlg32 + ssl + crypto + dbghelp + z + freetype +) + +# --- Output dir --- +set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/src/build" +) diff --git a/imgui.ini b/imgui.ini index 94954b8..2e7c451 100644 --- a/imgui.ini +++ b/imgui.ini @@ -57,7 +57,7 @@ DockId=0x00000017,1 Pos=343,955 Size=1232,222 Collapsed=0 -DockId=0x00000014,0 +DockId=0x00000011,0 [Window][Profiler Timeline] Pos=265,69 @@ -116,7 +116,7 @@ DockId=0x0000000E,0 Pos=1061,223 Size=44,497 Collapsed=0 -DockId=0x00000012,0 +DockId=0x00000014,0 [Window][Master Bus] Pos=1003,570 @@ -190,16 +190,16 @@ DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Spl DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,519 HiddenTabBar=1 Selected=0x36AF052B DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1577,701 Split=Y Selected=0xC450F867 DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,659 Split=X Selected=0xC450F867 - DockNode ID=0x00000017 Parent=0x00000007 SizeRef=1208,860 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867 + DockNode ID=0x00000017 Parent=0x00000007 SizeRef=1208,860 CentralNode=1 Selected=0xC450F867 DockNode ID=0x00000018 Parent=0x00000007 SizeRef=367,860 Split=Y Selected=0x36DC96AB DockNode ID=0x0000001B Parent=0x00000018 SizeRef=367,537 HiddenTabBar=1 Selected=0x36DC96AB DockNode ID=0x0000001C Parent=0x00000018 SizeRef=367,120 HiddenTabBar=1 Selected=0x8CFF897F DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,497 Split=X Selected=0xEA83D666 DockNode ID=0x00000015 Parent=0x00000008 SizeRef=1283,172 Split=X Selected=0xEA83D666 - DockNode ID=0x00000011 Parent=0x00000015 SizeRef=1206,168 Split=Y Selected=0x9B5D3198 - DockNode ID=0x00000013 Parent=0x00000011 SizeRef=1449,273 HiddenTabBar=1 Selected=0xEA83D666 - DockNode ID=0x00000014 Parent=0x00000011 SizeRef=1449,222 HiddenTabBar=1 Selected=0x9B5D3198 - DockNode ID=0x00000012 Parent=0x00000015 SizeRef=75,168 HiddenTabBar=1 Selected=0x56009A08 + DockNode ID=0x00000011 Parent=0x00000015 SizeRef=1206,168 HiddenTabBar=1 Selected=0x9B5D3198 + DockNode ID=0x00000012 Parent=0x00000015 SizeRef=75,168 Split=X Selected=0x56009A08 + DockNode ID=0x00000013 Parent=0x00000012 SizeRef=1207,497 Selected=0xEA83D666 + DockNode ID=0x00000014 Parent=0x00000012 SizeRef=74,497 HiddenTabBar=1 Selected=0x56009A08 DockNode ID=0x00000016 Parent=0x00000008 SizeRef=292,172 Split=Y Selected=0x3FC1A724 DockNode ID=0x00000019 Parent=0x00000016 SizeRef=314,268 HiddenTabBar=1 Selected=0x3FC1A724 DockNode ID=0x0000001A Parent=0x00000016 SizeRef=314,227 HiddenTabBar=1 Selected=0xA873C17F diff --git a/src/build/imgui.ini b/src/build/imgui.ini new file mode 100644 index 0000000..f7a6e41 --- /dev/null +++ b/src/build/imgui.ini @@ -0,0 +1,67 @@ +[Window][WindowOverViewport_11111111] +Pos=0,19 +Size=1920,1158 +Collapsed=0 + +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Performance Info] +Pos=165,119 +Size=198,265 +Collapsed=0 + +[Window][Color Correction] +Pos=264,422 +Size=136,215 +Collapsed=0 + +[Window][Resources] +Pos=739,417 +Size=229,105 +Collapsed=0 + +[Window][Audio Output] +Pos=421,336 +Size=120,180 +Collapsed=0 + +[Window][Lua Globals] +Pos=957,363 +Size=184,48 +Collapsed=0 + +[Window][Scene Tree] +Pos=357,113 +Size=240,180 +Collapsed=0 + +[Window][Inspector] +Pos=967,84 +Size=276,245 +Collapsed=0 + +[Window][Viewport] +Pos=81,61 +Size=216,189 +Collapsed=0 + +[Window][Console] +Pos=0,600 +Size=1920,577 +Collapsed=0 +DockId=0x00000002,0 + +[Table][0x43152D8E,3] +RefScale=13 +Column 0 Width=120 +Column 1 Width=90 +Column 2 Weight=1.0000 + +[Docking][Data] +DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1920,1158 Split=Y + DockNode ID=0x00000001 Parent=0x11111111 SizeRef=1920,579 CentralNode=1 + DockNode ID=0x00000002 Parent=0x11111111 SizeRef=1920,577 Selected=0xEA83D666 + diff --git a/src/src/Components/AudioPlayerComponent.cpp b/src/src/Components/AudioPlayerComponent.cpp index 42233b7..6a9d5ce 100644 --- a/src/src/Components/AudioPlayerComponent.cpp +++ b/src/src/Components/AudioPlayerComponent.cpp @@ -14,6 +14,7 @@ void AudioPlayerComponent::SetAudio(uint64_t uaid) { m_UAID = uaid; } + void AudioPlayerComponent::Play() { if (m_UAID == 0) return; AudioEngine::Play(m_UAID, loop); diff --git a/src/src/Components/TilemapComponent.cpp b/src/src/Components/TilemapComponent.cpp index b994b79..bc37123 100644 --- a/src/src/Components/TilemapComponent.cpp +++ b/src/src/Components/TilemapComponent.cpp @@ -22,6 +22,7 @@ void TilemapComponent::UnpackCoord(uint64_t key, int& x, int& y) } + bool TilemapComponent::HasSelection() { return hasSelection; diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp index 5686022..c34346c 100644 --- a/src/src/Engine.cpp +++ b/src/src/Engine.cpp @@ -20,14 +20,12 @@ #include "core/utils/EngineConfig.h" -#include "core/functions/Prefab.h" #include "core/functions/ProjectManager.h" #include "core/functions/SceneSerializer.h" #include "utils/GameObjectsList.h" #include "core/utils/Profiler.h" #include "core/utils/utils.h" -#include "core/utils/LoadingWindow.h" #include "core/scripts/LuaGlobalBridge.h" #include "editor/windows/AssetBrowser.h" @@ -62,18 +60,16 @@ #include #define WIN32_LEAN_AND_MEAN #include -#include #include -#include #include using json = nlohmann::json; static bool playing = false; -static bool lastPlaying = false; +bool Engine::running = true; + static glm::vec2 cameraPos = {0, 0}; static float cameraZoom = 1.0f; -static ImVec2 lastMousePos = {}; static glm::vec2 editorCameraSavedPos = {0.0f, 0.0f}; static float editorCameraSavedZoom = 1.0f; @@ -85,7 +81,14 @@ float g_fps = 0.0f; static const std::string tempScenePath = "__tmp_scene.yaml"; -GLFWwindow *window = nullptr; + + +static std::shared_ptr previewObj = nullptr; +static std::shared_ptr previousSelection = nullptr; +static uint64_t previewUAID = 0; +static AssetType previewType = AssetType::Unknown; + +static GLFWwindow *window = nullptr; Engine::Engine() { @@ -146,7 +149,7 @@ void DrawProfilerTimelineBars(const ProfileNode &node, "%s (%.2f ms)", node.name.c_str(), node.visualDurationMs); - if (fn >= 0 && fn < (int)sizeof(fullBuf)) + if (fn >= 0 && fn < static_cast(sizeof(fullBuf))) { ImVec2 fullSz = ImGui::CalcTextSize(fullBuf); if (fullSz.x <= availW) @@ -357,7 +360,7 @@ void Engine::ShowDebugOverlay(float deltaTime) // === Performance Window === static std::vector fpsHistory; - static const int maxFpsHistory = 100; + static constexpr int maxFpsHistory = 100; static float fpsTimer = 0.0f; float fps = 1.0f / deltaTime; g_fps = fps; @@ -483,6 +486,18 @@ void DrawGizmoForObject(const std::shared_ptr &obj, } } +void Engine::OnWindowClose(GLFWwindow* window) +{ + Logger::LogInfo("Closing"); + glfwSetWindowShouldClose(window, GLFW_TRUE); + running = false; + +} + + + + + void Engine::Init() { @@ -508,6 +523,9 @@ void Engine::Init() glewInit(); glfwSetDropCallback(window, GLFWDropCallback); + glfwSetWindowCloseCallback(window, OnWindowClose); + + g_engineConfig.LoadFromFile(); Logger::LogOk("Config Core"); @@ -549,7 +567,10 @@ void Engine::Init() Logger::LogOk("Engine Core"); - ProjectManager::LoadProject("C:/Users/spenc/OneDrive/Desktop", "TestProject"); + + + + //ProjectManager::LoadProject("C:/Users/spenc/OneDrive/Desktop", "TestProject"); } core::types::Vec2 ScreenToWorld(const core::types::Vec2 &screenPos, const core::types::Vec2 &viewportSize, const core::types::Vec2 &cameraPos, float zoom) @@ -632,7 +653,7 @@ void Engine::collectObjects(bool playing, const glm::vec2 &camPos, float camZoom void Engine::Run() { - while (!glfwWindowShouldClose(window) && running) + while (running) { if (g_engineConfig.settings.profile_editor) { @@ -945,9 +966,10 @@ void Engine::Run() } DrawInspectorUI(selected); - ImGui::Begin("Viewport", nullptr, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); ImVec2 size = ImGui::GetContentRegionAvail(); + ImVec2 windowPos = ImGui::GetWindowPos(); + static bool lastPlaying = false; if (playing && !lastPlaying) @@ -988,7 +1010,6 @@ void Engine::Run() float zoomFactor = (wheel > 0) ? 1.1f : 1.0f / 1.1f; ImVec2 mousePos = ImGui::GetMousePos(); - ImVec2 windowPos = ImGui::GetWindowPos(); ImVec2 contentMin = ImGui::GetWindowContentRegionMin(); glm::vec2 relativeMouse = glm::vec2( @@ -1007,7 +1028,10 @@ void Engine::Run() } profiler.BeginEngineSection("Renderer::Resize"); - Renderer::Resize((int)size.x, (int)size.y); + if (size.x > 0 && size.y > 0) + { + Renderer::Resize((int) size.x, (int) size.y); + } profiler.EndEngineSection(); profiler.BeginEngineSection("Renderer::Begin"); @@ -1159,8 +1183,8 @@ void Engine::Run() core::types::Color color = core::types::Color::Lerp(settings.startColor, settings.endColor, t); core::types::Vec2 pWorld = p.position; - core::types::Vec2 size = core::types::Vec2(p.size, p.size); - Renderer::BatchQuad(pWorld, size, p.rotation, color, cameraPos, cameraZoom, settings.roundness); + core::types::Vec2 particleSize = core::types::Vec2(p.size, p.size); + Renderer::BatchQuad(pWorld, particleSize, p.rotation, color, cameraPos, cameraZoom, settings.roundness); } profiler.EndSection(); @@ -1180,11 +1204,11 @@ void Engine::Run() GLuint texID = Renderer::GetFinalTexture(); ImGui::Image((ImTextureID)(uintptr_t)texID, size, ImVec2(0, 1), ImVec2(1, 0)); - ImVec2 winPos = ImGui::GetWindowPos(); + ImVec2 winSize = ImGui::GetWindowSize(); ImVec2 mousePos = ImGui::GetMousePos(); core::types::Vec2 viewportSize(winSize.x, winSize.y); - core::types::Vec2 screenMousePos(mousePos.x - winPos.x, mousePos.y - winPos.y); + core::types::Vec2 screenMousePos(mousePos.x - windowPos.x, mousePos.y - windowPos.y); bool mouseInWindow = screenMousePos.x >= 0 && screenMousePos.y >= 0 && @@ -1199,14 +1223,12 @@ void Engine::Run() if (light) { auto *drawList = ImGui::GetWindowDrawList(); - ImVec2 winPos = ImGui::GetWindowPos(); - ImVec2 winSize = ImGui::GetWindowSize(); auto worldToScreen = [&](const core::types::Vec2 &w) { float x = (w.x - cameraPos.x) * cameraZoom + winSize.x * 0.5f; float y = (w.y - cameraPos.y) * cameraZoom + winSize.y * 0.5f; - return ImVec2(winPos.x + x, winPos.y + y); + return ImVec2(windowPos.x + x, windowPos.y + y); }; core::types::Vec2 lightPos = light->GetOwner()->GetWorldPosition(); @@ -1222,7 +1244,7 @@ void Engine::Run() int(color.b * 255), 100); - const float thickness = 2.0f; + constexpr float thickness = 2.0f; drawList->AddCircle(center, radiusPx, col, 0, thickness); @@ -1241,20 +1263,18 @@ void Engine::Run() static int dragIndex = -1; auto *drawList = ImGui::GetWindowDrawList(); - ImVec2 winPos = ImGui::GetWindowPos(); - ImVec2 winSize = ImGui::GetWindowSize(); ImVec2 mouse = ImGui::GetIO().MousePos; auto worldToScreen = [&](const core::types::Vec2 &w) { float x = (w.x - cameraPos.x) * cameraZoom + winSize.x * 0.5f; float y = (w.y - cameraPos.y) * cameraZoom + winSize.y * 0.5f; - return ImVec2(winPos.x + x, winPos.y + y); + return ImVec2(windowPos.x + x, windowPos.y + y); }; auto screenToWorld = [&](const ImVec2 &s) { - float localX = s.x - winPos.x - winSize.x * 0.5f; - float localY = s.y - winPos.y - winSize.y * 0.5f; + float localX = s.x - windowPos.x - winSize.x * 0.5f; + float localY = s.y - windowPos.y - winSize.y * 0.5f; return core::types::Vec2(localX / cameraZoom + cameraPos.x, localY / cameraZoom + cameraPos.y); }; @@ -1337,11 +1357,8 @@ void Engine::Run() if (const auto *imageAsset = dynamic_cast(asset)) { auto *drawList = ImGui::GetWindowDrawList(); - const auto texSize = imageAsset->size; - int maxCols = static_cast(texSize.x / tileSize.x); - int maxRows = static_cast(texSize.y / tileSize.y); - core::types::Vec2 screenMouse(mousePos.x - winPos.x, mousePos.y - winPos.y); + core::types::Vec2 screenMouse(mousePos.x - windowPos.x, mousePos.y - windowPos.y); core::types::Vec2 worldMouse = ScreenToWorld(screenMouse, {winSize.x, winSize.y}, cameraPos, cameraZoom); int centerCol = static_cast(worldMouse.x / tileSize.x); @@ -1353,7 +1370,7 @@ void Engine::Run() int minRow = centerRow - radius; int maxRow = centerRow + radius; - core::types::Vec2 screenCenter = {winPos.x + winSize.x * 0.5f, winPos.y + winSize.y * 0.5f}; + core::types::Vec2 screenCenter = {windowPos.x + winSize.x * 0.5f, windowPos.y + winSize.y * 0.5f}; float maxDist = static_cast(radius) * tileSize.x * cameraZoom; for (int y = minRow; y <= maxRow; ++y) @@ -1441,10 +1458,6 @@ void Engine::Run() } { - static std::shared_ptr previewObj = nullptr; - static std::shared_ptr previousSelection = nullptr; - static uint64_t previewUAID = 0; - static AssetType previewType = AssetType::Unknown; const ImGuiPayload *payload = ImGui::GetDragDropPayload(); bool dragging = payload && payload->DataSize == sizeof(uint64_t); @@ -1457,8 +1470,6 @@ void Engine::Run() uint64_t uaid = *(const uint64_t *)payload->Data; const auto *asset = AssetManager::GetAssetByID(uaid); - if (!asset) - return; // --- Create Preview --- if (!previewObj || previewUAID != uaid) @@ -1477,14 +1488,12 @@ void Engine::Run() if (!prefabInfo) { Logger::LogError("[AssetManager] Asset is not a PrefabAssetInfo"); - return; } previewObj = prefabInfo->Instantiate(); if (!previewObj) { Logger::LogError("[Engine] Failed to instantiate prefab."); - return; } previewObj->SetName(prefabInfo->prefabName); diff --git a/src/src/Engine.h b/src/src/Engine.h index b36485a..4efc063 100644 --- a/src/src/Engine.h +++ b/src/src/Engine.h @@ -13,6 +13,7 @@ class ParticleComponent; class AnimationComponent; class TilemapComponent; class PathFollowerComponent; +class GLFWwindow; class Engine { @@ -20,6 +21,7 @@ public: Engine(); ~Engine(); void Run(); + static void OnWindowClose(GLFWwindow* window); std::shared_ptr GetObjectByTag(const std::string &tag); void Shutdown(); @@ -50,7 +52,7 @@ private: std::vector m_particleUpdates; std::vector m_PathUpdates; - bool running = true; + static bool running; diff --git a/src/src/Renderer.cpp b/src/src/Renderer.cpp index f30a6d0..ca6de9d 100644 --- a/src/src/Renderer.cpp +++ b/src/src/Renderer.cpp @@ -417,6 +417,7 @@ void Renderer::Resize(int w, int h) width = w; height = h; + // Resize all textures glBindTexture(GL_TEXTURE_2D, textureColorBuffer); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); diff --git a/src/src/core/functions/ProjectManager.cpp b/src/src/core/functions/ProjectManager.cpp index a42d7dc..28a1cdb 100644 --- a/src/src/core/functions/ProjectManager.cpp +++ b/src/src/core/functions/ProjectManager.cpp @@ -4,12 +4,15 @@ #include "../../core/utils/EngineConfig.h" #include "../../core/utils/Logging.h" #include "../../Engine.h" +#include "../../core/utils/FileDialog.h" #include "SceneSerializer.h" #include #include #include #include +#include +#include namespace fs = std::filesystem; @@ -17,6 +20,81 @@ std::string ProjectManager::s_currentProjectPath; std::string ProjectManager::s_currentProjectName; std::string ProjectManager::s_defaultScene; + + + +// Call this to open the popup: +// ImGui::OpenPopup("Create New Project"); +// ShowCreateProjectPopup(&open); +void ProjectManager::ShowCreateProjectPopup(bool* pOpen) +{ + // Keep static buffers across frames + static char nameBuf[128] = ""; + static char pathBuf[512] = ""; + + // Center-popup and set a decent default size + ImGui::SetNextWindowSize({500, 0}, ImGuiCond_Appearing); + if (!ImGui::BeginPopupModal("Create New Project", pOpen, ImGuiWindowFlags_NoResize)) + return; + + // Title + ImGui::TextUnformatted("Enter details for your new project:"); + ImGui::Separator(); + ImGui::Spacing(); + + // Project Name field + ImGui::InputText("##proj_name", nameBuf, sizeof(nameBuf)); + ImGui::SameLine(); + ImGui::Text("Project Name"); + + // Project Path field with Browse button + ImGui::PushItemWidth(-100); // make path input use remaining width + ImGui::InputText("##proj_path", pathBuf, sizeof(pathBuf)); + ImGui::PopItemWidth(); + ImGui::SameLine(); + if (ImGui::Button("Browse...", {80, 0})) + { + std::string chosen = CreateFileDialog(FileDialogType::Project); + if (!chosen.empty()) + strncpy(pathBuf, chosen.c_str(), sizeof(pathBuf)); + } + ImGui::SameLine(); + ImGui::Text("Project Folder"); + + ImGui::Spacing(); + + // Compute and show the final .cproj path preview + std::filesystem::path preview = std::filesystem::path(pathBuf) / (std::string(nameBuf) + ".cproj"); + ImGui::Text("Project file will be created at:"); + ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "%s", preview.string().c_str()); + + ImGui::Spacing(); + ImGui::Separator(); + + // Buttons: Cancel and Create + float width = ImGui::GetContentRegionAvail().x; + ImGui::Dummy({0,0}); // for a little vertical padding + if (ImGui::Button("Cancel", {width * 0.45f, 0})) + { + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Create Project", {width * 0.45f, 0})) + { + CreateProject(nameBuf, pathBuf); + ImGui::CloseCurrentPopup(); + + // Clear buffers for next time + nameBuf[0] = '\0'; + pathBuf[0] = '\0'; + } + + ImGui::EndPopup(); +} + + + + bool CreateDirectories(const fs::path &baseDir) { static const std::vector subdirs = { @@ -136,6 +214,73 @@ bool ProjectManager::LoadProject(const std::string &projectPath, return true; } +bool ProjectManager::CreateProject(const std::string &projectPath, + const std::string &projectName) +{ + fs::path baseDir = fs::path(projectPath) / projectName; + fs::path projFile = baseDir / (projectName + ".cproj"); + + std::error_code ec; + if (!fs::create_directories(baseDir, ec) && ec) + { + Logger::LogError("Failed to create project directory '%s': %s", + projectPath.c_str(), ec.message().c_str()); + return false; + } + + // Set current project path before scene creation + s_currentProjectPath = baseDir.string(); + s_currentProjectName = projectName; + + // Create initial scene + fs::path scenePath = baseDir / "Assets" / "Scenes" / "main.cene"; + + SceneLoader::SaveScene(scenePath.string()); + + s_defaultScene = scenePath.string(); + + // Write .cproj YAML + YAML::Emitter out; + out << YAML::BeginMap; + out << YAML::Key << "Name" << YAML::Value << projectName; + out << YAML::Key << "EngineVersion" << YAML::Value << g_engineConfig.version; + fs::path relPath = fs::relative(scenePath, baseDir); + out << YAML::Key << "s_defaultScene" << YAML::Value << ("res://" + relPath.generic_string()); + + auto now = std::chrono::system_clock::now(); + auto t = std::chrono::system_clock::to_time_t(now); + std::tm tm{}; +#if defined(_WIN32) + gmtime_s(&tm, &t); +#else + gmtime_r(&t, &tm); +#endif + char buf[32]; + std::strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", &tm); + out << YAML::Key << "CreatedDate" << YAML::Value << buf; + out << YAML::EndMap; + + std::ofstream fout(projFile); + if (!fout.is_open()) + { + Logger::LogError("Could not open project file for writing: %s", + projFile.string().c_str()); + return false; + } + fout << out.c_str(); + fout.close(); + + Logger::LogOk("Created project '%s' at '%s'", + projectName.c_str(), projectPath.c_str()); + + CreateDirectories(baseDir); + + SceneLoader::LoadScene(scenePath.string()); + + return true; +} + + bool ProjectManager::SaveProject(const std::string &projectPath, const std::string &projectName) { @@ -150,6 +295,8 @@ bool ProjectManager::SaveProject(const std::string &projectPath, return false; } + + YAML::Emitter out; out << YAML::BeginMap; out << YAML::Key << "Name" << YAML::Value << projectName; @@ -207,4 +354,5 @@ const std::string &ProjectManager::GetCurrentAssetsPath() fs::path p = fs::path(s_currentProjectPath) / s_currentProjectName / "Assets"; assetsPath = p.string(); return assetsPath; + } diff --git a/src/src/core/functions/ProjectManager.h b/src/src/core/functions/ProjectManager.h index e975f64..6c21d7a 100644 --- a/src/src/core/functions/ProjectManager.h +++ b/src/src/core/functions/ProjectManager.h @@ -20,6 +20,14 @@ public: static bool SaveProject(const std::string& projectPath, const std::string& projectName); + // Creates a project at the path with the name + // makes a .cproj file at the path in the name folder + static bool CreateProject(const std::string& projectPath, + const std::string& projectName); + + void ShowCreateProjectPopup(bool* pOpen); + + static const std::string& GetCurrentProjectPath(); static const std::string& GetCurrentProjectName(); static const std::string& GetCurrentAssetsPath(); diff --git a/src/src/core/utils/ExceptionHandler.cpp b/src/src/core/utils/ExceptionHandler.cpp index 2a2ffdb..6e8df38 100644 --- a/src/src/core/utils/ExceptionHandler.cpp +++ b/src/src/core/utils/ExceptionHandler.cpp @@ -63,10 +63,11 @@ bool SignalHandler::IsInterrupted() { void SignalHandler::HandleSignal(int signal) { if (signal == SIGINT) { + std::cout << "\n[Engine] Shutting down." << std::endl; - if (engine) - engine->Stop(); - engine->Shutdown(); + //if (engine) + // engine->Stop(); + // engine->Shutdown(); interrupted = true; } diff --git a/src/src/core/utils/FileDialog.cpp b/src/src/core/utils/FileDialog.cpp index 00cd308..3d6192a 100644 --- a/src/src/core/utils/FileDialog.cpp +++ b/src/src/core/utils/FileDialog.cpp @@ -22,6 +22,7 @@ static std::unordered_map filters = { { FileDialogType::Shaders, "Shader Files\0*.glsl;*.vert;*.frag;*.hlsl\0All Files\0*.*\0" }, { FileDialogType::Fonts, "Font Files\0*.ttf;*.otf;*.fnt\0All Files\0*.*\0" }, { FileDialogType::Models, "3D Models\0*.obj;*.fbx;*.gltf;*.dae\0All Files\0*.*\0" }, + { FileDialogType::Project, "Project File\0*.cproj\0All Files\0*.*\0" }, { FileDialogType::All, "All Files\0*.*\0" } }; diff --git a/src/src/core/utils/FileDialog.h b/src/src/core/utils/FileDialog.h index 50c6722..eec7bf6 100644 --- a/src/src/core/utils/FileDialog.h +++ b/src/src/core/utils/FileDialog.h @@ -13,6 +13,7 @@ enum class FileDialogType { Shaders, // .vert, .frag, .glsl Fonts, // .ttf, .otf Models, // .obj, .fbx, .gltf, etc. + Project, All };