From bea9a563541896e089e0f02d1c42ec88e1b22e64 Mon Sep 17 00:00:00 2001 From: Chewico Date: Wed, 21 May 2025 19:29:16 +0200 Subject: [PATCH] Refactoring Application, removing singelton to make it namespace, cleaner and easier to access --- Deer/Include/Deer/Application.h | 21 ++++ Deer/src/Deer/Core/Application_tmp.cpp | 118 ++++++++++++++++++ Deer/src/Plattform/ImGUI/ImGuiLayer.cpp | 1 - DeerStudio/src/DeerStudio/DeerStudio.h | 45 +------ DeerStudio/src/DeerStudio/DeerStudioInit.cpp | 109 ++++++++++++++++ .../src/DeerStudio/EditorEngine/API/UI.h | 3 + .../EditorEngine/API_Implementation/UI.cpp | 10 ++ .../API_Registration/UI_Register.cpp | 2 + roe/Editor/Viewport.as | 10 +- roe/Editor/as.predefined | 5 +- 10 files changed, 282 insertions(+), 42 deletions(-) create mode 100644 Deer/src/Deer/Core/Application_tmp.cpp create mode 100644 DeerStudio/src/DeerStudio/DeerStudioInit.cpp diff --git a/Deer/Include/Deer/Application.h b/Deer/Include/Deer/Application.h index 6993382..d59d9ae 100755 --- a/Deer/Include/Deer/Application.h +++ b/Deer/Include/Deer/Application.h @@ -25,6 +25,27 @@ namespace Deer { float m_time; }; + namespace Application_tmp { + using Function = void(*)(); + using EventFunction = void(*)(Event&); + + extern bool running; + + void run(); + + void setTickCallback(Function); + +#ifdef DEER_RENDER + void initWindow(); + void shutdownWindow(); + + void setRenderCallback(Function); + void setEventCallback(EventFunction); + + Window& getWindow(); +#endif + } + class Application { public: Application(); diff --git a/Deer/src/Deer/Core/Application_tmp.cpp b/Deer/src/Deer/Core/Application_tmp.cpp new file mode 100644 index 0000000..48de355 --- /dev/null +++ b/Deer/src/Deer/Core/Application_tmp.cpp @@ -0,0 +1,118 @@ +#include "Deer/Application.h" +#include +#include + +#ifdef DEER_RENDER +#include "DeerRender/Render/RenderCommand.h" +#include "DeerRender/Render/RenderUtils.h" +#include "DeerRender/Render/Render.h" + +#include "DeerRender/ImGui/ImGuiLayer.h" +#include "imgui.h" +#endif + +namespace Deer { + namespace Application_tmp { + Function tickCallback; + bool running; + + const double targetUpdateTime = 1.0 / 60.0; // Fixed 60 FPS update + double targetRenderTime = 1.0 / 160.0; // User-defined render FPS + +#ifdef DEER_RENDER + Function renderCallback; + EventFunction eventCallback; + Scope window; + Scope imGuiLayer; +#endif + + void setTickCallback(Function _tick) { + tickCallback = _tick; + } + +#ifdef DEER_RENDER + void setRenderCallback(Function _render) { + renderCallback = _render; + } + + void setEventCallback(EventFunction _event) { + eventCallback = _event; + } + + Window& getWindow() { + return *window; + } + + void initWindow() { + window = Scope(Window::create()); + imGuiLayer = MakeScope(); + + window->initWindow(); + imGuiLayer->onAttach(); + + if (eventCallback) + window->setEventCallback(eventCallback); + + RenderUtils::initializeRenderUtils(); + RenderCommand::init(); + } + + void shutdownWindow() { + imGuiLayer->onDetach(); + + window.reset(); + imGuiLayer.reset(); + } +#endif + + void run() { + running = true; + + auto previousTime = std::chrono::high_resolution_clock::now(); + double accumulatedUpdateTime = 0.0; + double accumulatedRenderTime = 0.0; + + while (running) { + // Time handling + auto currentTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration deltaTime = currentTime - previousTime; + previousTime = currentTime; + + accumulatedUpdateTime += deltaTime.count(); + accumulatedRenderTime += deltaTime.count(); + + // Fixed Update loop (60 FPS) + while (accumulatedUpdateTime >= targetUpdateTime) { + Timestep timestep = (float)targetUpdateTime; + accumulatedUpdateTime -= targetUpdateTime; + + if (tickCallback) + tickCallback(); + + } + +#ifdef DEER_RENDER + // Render loop (User-defined FPS) + if (accumulatedRenderTime >= targetRenderTime && tickCallback) { + RenderCommand::setClearColor({ 0.2f, 0.2f, 0.3f, 1.0f }); + RenderCommand::clear(); + + ImGuiIO& io = ImGui::GetIO(); + io.DeltaTime = (float)targetRenderTime; + imGuiLayer->begin(); + + tickCallback(); + + imGuiLayer->end(); + accumulatedRenderTime -= targetRenderTime; + + } + + window->resolveEvents(); +#endif + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } + } +} \ No newline at end of file diff --git a/Deer/src/Plattform/ImGUI/ImGuiLayer.cpp b/Deer/src/Plattform/ImGUI/ImGuiLayer.cpp index 8233b0a..0d16a4b 100755 --- a/Deer/src/Plattform/ImGUI/ImGuiLayer.cpp +++ b/Deer/src/Plattform/ImGUI/ImGuiLayer.cpp @@ -45,7 +45,6 @@ namespace Deer { } void ImGuiLayer::end() { - RenderCommand::unbindFrameBuffer(); ImGui::EndFrame(); diff --git a/DeerStudio/src/DeerStudio/DeerStudio.h b/DeerStudio/src/DeerStudio/DeerStudio.h index ef34b09..2f08e49 100755 --- a/DeerStudio/src/DeerStudio/DeerStudio.h +++ b/DeerStudio/src/DeerStudio/DeerStudio.h @@ -1,46 +1,13 @@ #pragma once -#include "Deer/EntryPoint.h" -#include "Deer/Application.h" - #include "DeerRender/Events/Event.h" -#include "DeerStudio/Editor/ActiveEntity.h" -#include "DeerStudio/Editor/EditorPanel.h" - -#include - -class asIScriptEngine; -class asIScriptObject; -class asIScriptModule; -class asIScriptContext; - +int main(int, char**); namespace Deer { - class DeerStudioApplication : public Deer::Application { - public: - DeerStudioApplication() - : Application(Deer::WindowProps("Deer Studio")) { } - private: - int originEntity, dirEntity, hitEntity; - private: - int onPreInit() override; - int onInit() override; - void onShutdown() override; - - void onRender(Timestep delta) override; - void onUpdate(Timestep delta) override; - - void onEvent(Event& e) override; - void onImGUI() override; - void drawMenuBar(); - void onChangeScene(); + namespace DeerStudio { + void onRender(Timestep delta); + void onUpdate(Timestep delta); - std::vector> Panels; - }; - + void onEvent(Event& e); + } } - -Deer::Application* createApplication(int argc, char** argv) { - Deer::DeerStudioApplication* app = new Deer::DeerStudioApplication(); - return app; -} \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/DeerStudioInit.cpp b/DeerStudio/src/DeerStudio/DeerStudioInit.cpp new file mode 100644 index 0000000..63a34ce --- /dev/null +++ b/DeerStudio/src/DeerStudio/DeerStudioInit.cpp @@ -0,0 +1,109 @@ +#include "DeerStudio.h" + +#include "DeerStudio/EditorEngine.h" + +// TMP +#include "DeerStudio/Editor/Icons.h" +#include "DeerStudio/Fonts.h" +#include "DeerStudio/Style.h" +// TMP + +#include "Deer/Application.h" +#include "Deer/Path.h" + +#include "Deer/DataStore.h" +#include "Deer/Voxel.h" + +int main(int, char**) { + Deer::Path projectPath = Deer::Application_tmp::getWindow().folderDialog(nullptr); + if (projectPath.empty()) return 0; + + Deer::DataStore::rootPath = projectPath; + Deer::DataStore::loadVoxelsData(); + Deer::DataStore::loadVoxelsAspect(); + + Deer::Application_tmp::initWindow(); + + Deer::DataStore::generateTextureAtlas(); + Deer::DataStore::loadVoxelsShaders(); + + Deer::EditorEngine::initialize(); + + Deer::Icons::setupIcons(); + + Deer::initializeFonts(); + + SetupImGuiStyle(); + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20)); + + Deer::Application_tmp::run(); + + Deer::EditorEngine::deinitialize(); +} + +namespace Deer { + namespace DeerStudio { + void onUpdate() { + if (Scene::getExecutingState()) + Scene::tickExecution(); + + if (VoxelWorld::isInitialized()) + VoxelWorld::bakeNextChunk(); + } + + void onRender() { + static bool opt_fullscreen = true; + static bool opt_padding = false; + static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None; + + ImGuiWindowFlags window_flags = + ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; + + { + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(viewport->WorkPos); + ImGui::SetNextWindowSize(viewport->WorkSize); + ImGui::SetNextWindowViewport(viewport->ID); + window_flags |= ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; + window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | + ImGuiWindowFlags_NoNavFocus; + window_flags |= ImGuiWindowFlags_NoBackground; + } + + static bool p_open = true; + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + ImGui::Begin("DockSpace Demo", &p_open, window_flags); + ImGui::PopStyleVar(); + ImGui::PopStyleVar(2); + + ImGuiID dockspace_id = ImGui::GetID("DockSpace Demo"); + ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); + + if (ImGui::BeginMenuBar()) { + drawMenuBar(); + ImGui::EndMenuBar(); + } + + for (auto Panel : Panels) { + Panel->onImGui(); + } + + // ---- PanelS ----- + TerrainEditor::onImGui(); + viewport_onImGui(); + EditorEngine::render(); + // ---- PanelS ----- + Scene::gizmoRenderer.refresh(); + ImGui::End(); + } + + void onEvent(Event& e) { + viewport_onEvent(e); + } + } +} // namespace Deer \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h b/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h index a436b4e..77327d3 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h +++ b/DeerStudio/src/DeerStudio/EditorEngine/API/UI.h @@ -71,6 +71,9 @@ namespace Deer { int getAvailableSizeX(); int getAvailableSizeY(); + + float slider(std::string&, float, float, float); + int sliderInt(std::string&, int, int, int); // Draws a button for a popup menu bool menuItem(std::string&); diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp index bb74690..f78f333 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Implementation/UI.cpp @@ -449,6 +449,16 @@ namespace Deer { return false; } + float slider(std::string& label, float value, float min, float max) { + ImGui::SliderFloat(label.c_str(), &value, min, max); + return value; + } + + int sliderInt(std::string& label, int value, int min, int max) { + ImGui::SliderInt(label.c_str(), &value, min, max); + return value; + } + float getMouseDeltaX() { ImGuiIO& io = ImGui::GetIO(); return io.MouseDelta.x; diff --git a/DeerStudio/src/DeerStudio/EditorEngine/API_Registration/UI_Register.cpp b/DeerStudio/src/DeerStudio/EditorEngine/API_Registration/UI_Register.cpp index 85888ba..6acf3e8 100644 --- a/DeerStudio/src/DeerStudio/EditorEngine/API_Registration/UI_Register.cpp +++ b/DeerStudio/src/DeerStudio/EditorEngine/API_Registration/UI_Register.cpp @@ -52,6 +52,8 @@ namespace Deer { REGISTER_GLOBAL_FUNC("int getAvailableSizeX()", getAvailableSizeX); REGISTER_GLOBAL_FUNC("int getAvailableSizeY()", getAvailableSizeY); REGISTER_GLOBAL_FUNC("void disablePannelPadding(bool)", disablePannelPadding); + REGISTER_GLOBAL_FUNC("int sliderInt(string&in, int, int, int)", sliderInt); + REGISTER_GLOBAL_FUNC("float slider(string&in, float, float, float)", slider); scriptEngine->SetDefaultNamespace(""); } diff --git a/roe/Editor/Viewport.as b/roe/Editor/Viewport.as index b22ec6f..0e4bba6 100644 --- a/roe/Editor/Viewport.as +++ b/roe/Editor/Viewport.as @@ -41,7 +41,6 @@ class ViewportPannel : DockPanel { sceneCamera.transform.position = sceneCamera.transform.relative(panDir); } - vec3 relDir = vec3(); if (UI::isKeyDown(key::W)) @@ -78,7 +77,16 @@ class ViewportPannel : DockPanel { if (UI::menuItem("Start")) { } + + if (UI::menuItem("Camera Props")) { + UI::openPopup("ViewportCameraProps", any()); + } + + UI::simplePopup("ViewportCameraProps", ReciverFunc(this.viewportCameraProps)); } + void viewportCameraProps(any@ data) { + sceneCamera.camera.fov = UI::slider("Fov", sceneCamera.camera.fov / 3.14f * 180, 10, 160) / 180 * 3.14f; + } } \ No newline at end of file diff --git a/roe/Editor/as.predefined b/roe/Editor/as.predefined index 2eb8a1d..b234fbe 100644 --- a/roe/Editor/as.predefined +++ b/roe/Editor/as.predefined @@ -501,5 +501,8 @@ namespace UI { float getMouseDeltaY(); int getAvailableSizeX(); int getAvailableSizeY(); - void disablePannelPadding(bool) + void disablePannelPadding(bool); + + int sliderInt(string&in, int value, int min, int max); + float slider(string&in, float value, float min, float max); }