aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Core/Application.cpp11
-rw-r--r--src/Core/SettingsManager.cpp178
-rw-r--r--src/Core/SettingsManager.h70
-rw-r--r--src/States/ConfigState.cpp56
-rw-r--r--src/States/SimulationState.cpp56
5 files changed, 363 insertions, 8 deletions
diff --git a/src/Core/Application.cpp b/src/Core/Application.cpp
index 302132a..b879535 100644
--- a/src/Core/Application.cpp
+++ b/src/Core/Application.cpp
@@ -1,6 +1,7 @@
#include "Application.h"
#include "Rendering/Renderer.h"
+#include "SettingsManager.h"
#include "States/SimulationState.h"
#include "States/ConfigState.h"
@@ -98,7 +99,14 @@ namespace Donut
{
Logger::Init();
- RendererAPI::SetAPI(RendererAPI::API::OpenGL);
+ // Initialize settings manager first
+ SettingsManager::Initialize();
+
+ // Apply loaded settings
+ const auto& settings = SettingsManager::GetSettingsConst();
+ RendererAPI::API api = (settings.graphics.renderAPI == "Vulkan") ? RendererAPI::API::Vulkan : RendererAPI::API::OpenGL;
+ RendererAPI::SetAPI(api);
+
Renderer::Init();
m_Window->InitImGui();
@@ -117,6 +125,7 @@ namespace Donut
m_StateManager->Shutdown();
Renderer::Shutdown();
+ SettingsManager::Shutdown();
Logger::Shutdown();
}
diff --git a/src/Core/SettingsManager.cpp b/src/Core/SettingsManager.cpp
new file mode 100644
index 0000000..f35a016
--- /dev/null
+++ b/src/Core/SettingsManager.cpp
@@ -0,0 +1,178 @@
+#include "SettingsManager.h"
+#include "Log.h"
+#include "ThemeManager.h"
+#include "Rendering/Renderer.h"
+
+#include <fstream>
+#include <filesystem>
+#include <algorithm>
+
+namespace Donut
+{
+ Settings SettingsManager::s_Settings;
+ bool SettingsManager::s_Initialized = false;
+
+ void SettingsManager::Initialize()
+ {
+ if (s_Initialized)
+ return;
+
+ LoadSettings();
+ s_Initialized = true;
+ DONUT_INFO("Settings Manager initialized");
+ }
+
+ void SettingsManager::Shutdown()
+ {
+ if (!s_Initialized)
+ return;
+
+ SaveSettings();
+ s_Initialized = false;
+ DONUT_INFO("Settings Manager shutdown");
+ }
+
+ void SettingsManager::LoadSettings()
+ {
+ std::string filePath = GetSettingsFilePath();
+
+ try
+ {
+ if (std::filesystem::exists(filePath))
+ {
+ auto config = toml::parse(filePath);
+
+ if (config.contains("simulation"))
+ {
+ auto sim = config["simulation"];
+ s_Settings.simulation.targetFPS = toml::find_or(sim, "target_fps", 60);
+ s_Settings.simulation.computeHeight = toml::find_or(sim, "compute_height", 512);
+ s_Settings.simulation.maxStepsMoving = toml::find_or(sim, "max_steps_moving", 30000);
+ s_Settings.simulation.maxStepsStatic = toml::find_or(sim, "max_steps_static", 15000);
+ s_Settings.simulation.earlyExitDistance = toml::find_or(sim, "early_exit_distance", 5e12f);
+ s_Settings.simulation.gravityEnabled = toml::find_or(sim, "gravity_enabled", true);
+
+ s_Settings.simulation.targetFPS = std::max(30, std::min(120, s_Settings.simulation.targetFPS));
+ s_Settings.simulation.computeHeight = std::max(64, std::min(2048, s_Settings.simulation.computeHeight));
+ s_Settings.simulation.maxStepsMoving = std::max(1000, std::min(60000, s_Settings.simulation.maxStepsMoving));
+ s_Settings.simulation.maxStepsStatic = std::max(1000, std::min(30000, s_Settings.simulation.maxStepsStatic));
+ s_Settings.simulation.earlyExitDistance = std::max(1e11f, std::min(1e13f, s_Settings.simulation.earlyExitDistance));
+ }
+
+ if (config.contains("graphics"))
+ {
+ auto gfx = config["graphics"];
+ s_Settings.graphics.renderAPI = toml::find_or(gfx, "render_api", std::string("OpenGL"));
+ s_Settings.graphics.vSyncEnabled = toml::find_or(gfx, "vsync_enabled", true);
+ s_Settings.graphics.showFPS = toml::find_or(gfx, "show_fps", true);
+ s_Settings.graphics.showPerformanceMetrics = toml::find_or(gfx, "show_performance_metrics", true);
+ s_Settings.graphics.showDebugInfo = toml::find_or(gfx, "show_debug_info", false);
+ s_Settings.graphics.enableAntiAliasing = toml::find_or(gfx, "enable_anti_aliasing", true);
+ s_Settings.graphics.selectedTheme = toml::find_or(gfx, "selected_theme", std::string("Dark"));
+
+ if (s_Settings.graphics.renderAPI != "OpenGL" &&
+ s_Settings.graphics.renderAPI != "Vulkan")
+ s_Settings.graphics.renderAPI = "OpenGL";
+ if (s_Settings.graphics.selectedTheme != "Dark" &&
+ s_Settings.graphics.selectedTheme != "Light" &&
+ s_Settings.graphics.selectedTheme != "Blue")
+ s_Settings.graphics.selectedTheme = "Dark";
+ }
+
+ DONUT_INFO("Settings loaded from {}", filePath);
+ }
+ else
+ {
+ LoadDefaultSettings();
+ SaveSettings();
+ DONUT_INFO("No settings file found, created default settings");
+ }
+ }
+ catch (const std::exception& e)
+ {
+ DONUT_ERROR("Failed to load settings: {}", e.what());
+ LoadDefaultSettings();
+ }
+ }
+
+ void SettingsManager::SaveSettings()
+ {
+ std::string filePath = GetSettingsFilePath();
+
+ try
+ {
+ std::filesystem::path path(filePath);
+ std::filesystem::create_directories(path.parent_path());
+
+ toml::value simulation = toml::table
+ {
+ {"target_fps", s_Settings.simulation.targetFPS },
+ {"compute_height", s_Settings.simulation.computeHeight },
+ {"max_steps_moving", s_Settings.simulation.maxStepsMoving },
+ {"max_steps_static", s_Settings.simulation.maxStepsStatic },
+ {"early_exit_distance", s_Settings.simulation.earlyExitDistance},
+ {"gravity_enabled", s_Settings.simulation.gravityEnabled }
+ };
+
+ toml::value graphics = toml::table
+ {
+ {"render_api", s_Settings.graphics.renderAPI },
+ {"vsync_enabled", s_Settings.graphics.vSyncEnabled },
+ {"show_fps", s_Settings.graphics.showFPS },
+ {"show_performance_metrics", s_Settings.graphics.showPerformanceMetrics},
+ {"show_debug_info", s_Settings.graphics.showDebugInfo },
+ {"enable_anti_aliasing", s_Settings.graphics.enableAntiAliasing },
+ {"selected_theme", s_Settings.graphics.selectedTheme }
+ };
+
+ toml::value config = toml::table
+ {
+ {"simulation", simulation},
+ {"graphics", graphics}
+ };
+
+ std::ofstream file(filePath);
+ file << config;
+ file.close();
+
+ DONUT_INFO("Settings saved to {}", filePath);
+ }
+ catch (const std::exception& e)
+ DONUT_ERROR("Failed to save settings: {}", e.what());
+ }
+
+ void SettingsManager::SetSimulationSettings(const SimulationSettings& settings)
+ {
+ s_Settings.simulation = settings;
+ SaveSettings();
+ }
+
+ void SettingsManager::SetGraphicsSettings(const GraphicsSettings& settings)
+ {
+ s_Settings.graphics = settings;
+ SaveSettings();
+ }
+
+ std::string SettingsManager::GetSettingsFilePath()
+ {
+ return "Config/settings.toml";
+ }
+
+ void SettingsManager::LoadDefaultSettings()
+ {
+ s_Settings.simulation.targetFPS = 60;
+ s_Settings.simulation.computeHeight = 512;
+ s_Settings.simulation.maxStepsMoving = 30000;
+ s_Settings.simulation.maxStepsStatic = 15000;
+ s_Settings.simulation.earlyExitDistance = 5e12f;
+ s_Settings.simulation.gravityEnabled = true;
+
+ s_Settings.graphics.renderAPI = "OpenGL";
+ s_Settings.graphics.vSyncEnabled = true;
+ s_Settings.graphics.showFPS = true;
+ s_Settings.graphics.showPerformanceMetrics = true;
+ s_Settings.graphics.showDebugInfo = false;
+ s_Settings.graphics.enableAntiAliasing = true;
+ s_Settings.graphics.selectedTheme = "Dark";
+ }
+}
diff --git a/src/Core/SettingsManager.h b/src/Core/SettingsManager.h
new file mode 100644
index 0000000..bea1162
--- /dev/null
+++ b/src/Core/SettingsManager.h
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <string>
+#include <toml.hpp>
+
+namespace Donut
+{
+ struct SimulationSettings
+ {
+ int targetFPS = 60;
+ int computeHeight = 512;
+ int maxStepsMoving = 30000;
+ int maxStepsStatic = 15000;
+ float earlyExitDistance = 5e12f;
+ bool gravityEnabled = true;
+ };
+
+ struct GraphicsSettings
+ {
+ std::string renderAPI = "OpenGL";
+ bool vSyncEnabled = true;
+ bool showFPS = true;
+ bool showPerformanceMetrics = true;
+ bool showDebugInfo = false;
+ bool enableAntiAliasing = true;
+ std::string selectedTheme = "Dark";
+ };
+
+ struct Settings
+ {
+ SimulationSettings simulation;
+ GraphicsSettings graphics;
+ };
+
+ class SettingsManager
+ {
+ public:
+ static void Initialize();
+ static void Shutdown();
+
+ static void LoadSettings();
+ static void SaveSettings();
+
+ static Settings& GetSettings() { return s_Settings; }
+ static const Settings& GetSettingsConst() { return s_Settings; }
+
+ static void SetSimulationSettings(const SimulationSettings& settings);
+ static void SetGraphicsSettings(const GraphicsSettings& settings);
+
+ static int GetTargetFPS() { return s_Settings.simulation.targetFPS; }
+ static int GetComputeHeight() { return s_Settings.simulation.computeHeight; }
+ static int GetMaxStepsMoving() { return s_Settings.simulation.maxStepsMoving; }
+ static int GetMaxStepsStatic() { return s_Settings.simulation.maxStepsStatic; }
+ static float GetEarlyExitDistance() { return s_Settings.simulation.earlyExitDistance; }
+ static bool GetGravityEnabled() { return s_Settings.simulation.gravityEnabled; }
+ static std::string GetRenderAPI() { return s_Settings.graphics.renderAPI; }
+ static bool GetVSyncEnabled() { return s_Settings.graphics.vSyncEnabled; }
+ static bool GetShowFPS() { return s_Settings.graphics.showFPS; }
+ static bool GetShowPerformanceMetrics() { return s_Settings.graphics.showPerformanceMetrics; }
+ static bool GetShowDebugInfo() { return s_Settings.graphics.showDebugInfo; }
+ static bool GetEnableAntiAliasing() { return s_Settings.graphics.enableAntiAliasing; }
+ static std::string GetSelectedTheme() { return s_Settings.graphics.selectedTheme; }
+ private:
+ static std::string GetSettingsFilePath();
+ static void LoadDefaultSettings();
+ private:
+ static Settings s_Settings;
+ static bool s_Initialized;
+ };
+}
diff --git a/src/States/ConfigState.cpp b/src/States/ConfigState.cpp
index 688c48a..1470c6d 100644
--- a/src/States/ConfigState.cpp
+++ b/src/States/ConfigState.cpp
@@ -2,6 +2,7 @@
#include "Rendering/Renderer.h"
#include "Core/Application.h"
#include "Core/ThemeManager.h"
+#include "Core/SettingsManager.h"
#include <imgui.h>
#include <imgui_internal.h>
@@ -13,8 +14,22 @@ namespace Donut
{
DONUT_INFO("Entering Config State");
- m_SelectedAPI = Renderer::GetAPI();
- m_SelectedTheme = static_cast<int>(ThemeManager::GetCurrentTheme());
+ const auto& settings = SettingsManager::GetSettingsConst();
+
+ m_SelectedAPI = (settings.graphics.renderAPI == "Vulkan") ? RendererAPI::API::Vulkan : RendererAPI::API::OpenGL;
+ m_SelectedTheme = (settings.graphics.selectedTheme == "Light") ? 1 :
+ (settings.graphics.selectedTheme == "Blue") ? 2 : 0;
+ m_TargetFPS = settings.simulation.targetFPS;
+ m_ComputeHeight = settings.simulation.computeHeight;
+ m_MaxStepsMoving = settings.simulation.maxStepsMoving;
+ m_MaxStepsStatic = settings.simulation.maxStepsStatic;
+ m_EarlyExitDistance = settings.simulation.earlyExitDistance;
+ m_GravityEnabled = settings.simulation.gravityEnabled;
+ m_VSyncEnabled = settings.graphics.vSyncEnabled;
+ m_ShowFPS = settings.graphics.showFPS;
+ m_ShowPerformanceMetrics = settings.graphics.showPerformanceMetrics;
+ m_ShowDebugInfo = settings.graphics.showDebugInfo;
+ m_EnableAntiAliasing = settings.graphics.enableAntiAliasing;
}
void ConfigState::OnExit()
@@ -60,7 +75,7 @@ namespace Donut
ImGui::Columns(2, "ConfigColumns", true);
- float availableHeight = ImGui::GetWindowHeight() - 140; // Reserve space for header, separator, buttons, and footer
+ float availableHeight = ImGui::GetWindowHeight() - 140;
ImGui::BeginChild("GraphicsSettings", ImVec2(0, availableHeight), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
ImGui::TextColored(ImVec4(0.9f, 0.9f, 1.0f, 1.0f), "Graphics Settings");
@@ -200,7 +215,7 @@ namespace Donut
ImGui::Separator();
ImGui::Spacing();
- float buttonWidth = (ImGui::GetWindowWidth() - 80) / 4.0f;
+ float buttonWidth = (ImGui::GetWindowWidth() - 100) / 5.0f;
if (ImGui::Button("Start Simulation", ImVec2(buttonWidth, 35)))
{
@@ -217,6 +232,13 @@ namespace Donut
ApplySettings();
ImGui::SameLine();
+ if (ImGui::Button("Save Settings", ImVec2(buttonWidth, 35)))
+ {
+ ApplySettings();
+ DONUT_INFO("Settings saved manually");
+ }
+
+ ImGui::SameLine();
if (ImGui::Button("Exit", ImVec2(buttonWidth, 35)))
Application::Get().Close();
@@ -237,8 +259,29 @@ namespace Donut
void ConfigState::ApplySettings()
{
+ SimulationSettings simSettings;
+ simSettings.targetFPS = m_TargetFPS;
+ simSettings.computeHeight = m_ComputeHeight;
+ simSettings.maxStepsMoving = m_MaxStepsMoving;
+ simSettings.maxStepsStatic = m_MaxStepsStatic;
+ simSettings.earlyExitDistance = m_EarlyExitDistance;
+ simSettings.gravityEnabled = m_GravityEnabled;
+
+ GraphicsSettings gfxSettings;
+ gfxSettings.renderAPI = (m_SelectedAPI == RendererAPI::API::Vulkan) ? "Vulkan" : "OpenGL";
+ gfxSettings.vSyncEnabled = m_VSyncEnabled;
+ gfxSettings.showFPS = m_ShowFPS;
+ gfxSettings.showPerformanceMetrics = m_ShowPerformanceMetrics;
+ gfxSettings.showDebugInfo = m_ShowDebugInfo;
+ gfxSettings.enableAntiAliasing = m_EnableAntiAliasing;
+ gfxSettings.selectedTheme = (m_SelectedTheme == 1) ? "Light" :
+ (m_SelectedTheme == 2) ? "Blue" : "Dark";
+
+ SettingsManager::SetSimulationSettings(simSettings);
+ SettingsManager::SetGraphicsSettings(gfxSettings);
+
RendererAPI::SetAPI(m_SelectedAPI);
- DONUT_INFO("Settings applied");
+ DONUT_INFO("Settings applied and saved");
}
void ConfigState::ResetToDefaults()
@@ -257,6 +300,7 @@ namespace Donut
m_EnableAntiAliasing = true;
m_SelectedTheme = 0;
- DONUT_INFO("Settings reset to defaults");
+ ApplySettings();
+ DONUT_INFO("Settings reset to defaults and saved");
}
};
diff --git a/src/States/SimulationState.cpp b/src/States/SimulationState.cpp
index 87bf1ec..b4ed204 100644
--- a/src/States/SimulationState.cpp
+++ b/src/States/SimulationState.cpp
@@ -3,6 +3,7 @@
#include "Core/Application.h"
#include "Core/Window.h"
#include "Core/Event.h"
+#include "Core/SettingsManager.h"
#include <imgui.h>
#include <GLFW/glfw3.h>
@@ -12,6 +13,17 @@ namespace Donut
void SimulationState::OnEnter()
{
DONUT_INFO("Entering Simulation State");
+
+ const auto& settings = SettingsManager::GetSettingsConst();
+
+ m_Engine.SetTargetFPS(settings.simulation.targetFPS);
+ m_Engine.SetComputeHeight(settings.simulation.computeHeight);
+ m_Engine.SetMaxStepsMoving(settings.simulation.maxStepsMoving);
+ m_Engine.SetMaxStepsStatic(settings.simulation.maxStepsStatic);
+ m_Engine.SetEarlyExitDistance(settings.simulation.earlyExitDistance);
+ m_Engine.GetGravity() = settings.simulation.gravityEnabled;
+
+ m_Engine.UpdateComputeDimensions();
m_Initialized = true;
}
@@ -92,8 +104,22 @@ namespace Donut
ImGui::Begin("Simulation Controls", nullptr, ImGuiWindowFlags_NoCollapse);
ImGui::TextColored(ImVec4(0.8f, 0.8f, 1.0f, 1.0f), "Black Hole Simulation");
+ ImGui::SameLine();
if (ImGui::Button("Back to Config"))
Application::Get().GetStateManager().SwitchToState("Config");
+ ImGui::SameLine();
+ if (ImGui::Button("Save Settings"))
+ {
+ SimulationSettings settings = SettingsManager::GetSettingsConst().simulation;
+ settings.targetFPS = m_Engine.GetTargetFPS();
+ settings.computeHeight = m_Engine.GetComputeHeight();
+ settings.maxStepsMoving = m_Engine.GetMaxStepsMoving();
+ settings.maxStepsStatic = m_Engine.GetMaxStepsStatic();
+ settings.earlyExitDistance = m_Engine.GetEarlyExitDistance();
+ settings.gravityEnabled = m_Engine.GetGravity();
+ SettingsManager::SetSimulationSettings(settings);
+ DONUT_INFO("Simulation settings saved manually");
+ }
ImGui::Separator();
@@ -106,7 +132,12 @@ namespace Donut
int targetFPS = m_Engine.GetTargetFPS();
if (ImGui::SliderInt("Target FPS", &targetFPS, 30, 120))
+ {
m_Engine.SetTargetFPS(targetFPS);
+ SimulationSettings settings = SettingsManager::GetSettingsConst().simulation;
+ settings.targetFPS = targetFPS;
+ SettingsManager::SetSimulationSettings(settings);
+ }
ImGui::Spacing();
@@ -122,6 +153,9 @@ namespace Donut
{
m_Engine.SetComputeHeight(computeHeight);
m_Engine.UpdateComputeDimensions();
+ SimulationSettings settings = SettingsManager::GetSettingsConst().simulation;
+ settings.computeHeight = computeHeight;
+ SettingsManager::SetSimulationSettings(settings);
}
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Compute Width: %d (auto-calculated)", m_Engine.GetComputeWidth());
@@ -133,13 +167,28 @@ namespace Donut
int maxStepsMoving = m_Engine.GetMaxStepsMoving();
if (ImGui::SliderInt("Max Steps (Moving)", &maxStepsMoving, 1000, 60000))
+ {
m_Engine.SetMaxStepsMoving(maxStepsMoving);
+ SimulationSettings settings = SettingsManager::GetSettingsConst().simulation;
+ settings.maxStepsMoving = maxStepsMoving;
+ SettingsManager::SetSimulationSettings(settings);
+ }
int maxStepsStatic = m_Engine.GetMaxStepsStatic();
if (ImGui::SliderInt("Max Steps (Static)", &maxStepsStatic, 1000, 30000))
+ {
m_Engine.SetMaxStepsStatic(maxStepsStatic);
+ SimulationSettings settings = SettingsManager::GetSettingsConst().simulation;
+ settings.maxStepsStatic = maxStepsStatic;
+ SettingsManager::SetSimulationSettings(settings);
+ }
float earlyExitDistance = m_Engine.GetEarlyExitDistance();
if (ImGui::SliderFloat("Early Exit Distance", &earlyExitDistance, 1e11f, 1e13f, "%.2e"))
+ {
m_Engine.SetEarlyExitDistance(earlyExitDistance);
+ SimulationSettings settings = SettingsManager::GetSettingsConst().simulation;
+ settings.earlyExitDistance = earlyExitDistance;
+ SettingsManager::SetSimulationSettings(settings);
+ }
ImGui::Spacing();
@@ -147,7 +196,12 @@ namespace Donut
ImGui::Separator();
bool& gravity = m_Engine.GetGravity();
- ImGui::Checkbox("Gravity Enabled", &gravity);
+ if (ImGui::Checkbox("Gravity Enabled", &gravity))
+ {
+ SimulationSettings settings = SettingsManager::GetSettingsConst().simulation;
+ settings.gravityEnabled = gravity;
+ SettingsManager::SetSimulationSettings(settings);
+ }
ImGui::Spacing();