❇️ Added Settings classes to save and load local configurations

pull/32/head
kziolkowski 2 months ago
parent 2947011a1a
commit ce29711614

@ -34,6 +34,7 @@ Signal_Debugger="*res://addons/SignalVisualizer/Debugger/SignalDebugger.gd"
FightWorldAutoload="*res://prefabs/fight/fight_world_autoload.tscn" FightWorldAutoload="*res://prefabs/fight/fight_world_autoload.tscn"
FieldService="*res://scripts/CSharp/Common/Farming/FieldService.cs" FieldService="*res://scripts/CSharp/Common/Farming/FieldService.cs"
SaveGameManager="*res://scripts/CSharp/Common/Savegame/SaveGameManager.cs" SaveGameManager="*res://scripts/CSharp/Common/Savegame/SaveGameManager.cs"
SettingsSaveController="*res://scripts/CSharp/Common/Savegame/SettingsSaveController.cs"
[dialogic] [dialogic]

@ -1,10 +1,13 @@
[gd_scene load_steps=2 format=3 uid="uid://bopv10dqm1knc"] [gd_scene load_steps=3 format=3 uid="uid://bopv10dqm1knc"]
[ext_resource type="PackedScene" uid="uid://c6wnoif01ltld" path="res://scenes/Babushka_scene_startMenu.tscn" id="1_15ton"] [ext_resource type="PackedScene" uid="uid://c6wnoif01ltld" path="res://scenes/Babushka_scene_startMenu.tscn" id="1_15ton"]
[ext_resource type="Script" uid="uid://bbp0dyddwdbl8" path="res://scripts/CSharp/Common/Savegame/WindowSettingsSync.cs" id="2_d3jfo"]
[node name="BabushkaSceneBootstrap" type="Node2D"] [node name="BabushkaSceneBootstrap" type="Node2D"]
[node name="BabushkaSceneStartMenu" parent="." instance=ExtResource("1_15ton")] [node name="BabushkaSceneStartMenu" parent="." instance=ExtResource("1_15ton")]
_sceneNamesToLoad = PackedStringArray("res://scenes/Babushka_scene_farm_outside_2d.tscn")
[node name="SceneParent" type="Node" parent="."] [node name="SceneParent" type="Node" parent="."]
[node name="WindowSettings" type="Node" parent="."]
script = ExtResource("2_d3jfo")

@ -0,0 +1,31 @@
namespace Babushka.scripts.CSharp.Common.Savegame;
/// <summary>
/// Data structure for device-specific settings that should be saved / loaded to disk.
/// Will not be synced across devices.
/// </summary>
public class SettingsData
{
/// <summary>
/// To be incremented (and migrated) on modification.
/// </summary>
public const int VERSION = 1;
public int version { get; set; } = VERSION;
public bool IsVersionValid()
{
return VERSION == version;
}
public double runtimeSeconds { get; set; }
public int windowSizeX { get; set; } = 800;
public int windowSizeY { get; set; } = 600;
public int windowPositionX { get; set; } = 100;
public int windowPositionY { get; set; } = 100;
public bool windowBorderless { get; set; }
public float volumeMaster { get; set; } = 1.0f;
public float volumeFx { get; set; } = 1.0f;
public float volumeMusic { get; set; } = 1.0f;
}

@ -0,0 +1,108 @@
using System;
using System.Text.Json;
using Godot;
namespace Babushka.scripts.CSharp.Common.Savegame;
/// <summary>
/// Handles the saving and loading of local settings data.
/// </summary>
[GlobalClass]
public partial class SettingsSaveController : Node
{
public static string SETTINGS_FILE_PATH = "user://userSettings.json";
public static SettingsSaveController Instance;
public SettingsData? settings = new SettingsData();
public SettingsData settingsDefault = new SettingsData();
public event Action OnSettingsReloaded;
private bool _loadedData;
private DateTime _readyTime;
public bool LoadedData => _loadedData;
public override void _EnterTree()
{
SETTINGS_FILE_PATH = ProjectSettings.GlobalizePath(SETTINGS_FILE_PATH);
_readyTime = DateTime.Now;
Instance = this;
LoadSettings();
}
public override void _ExitTree()
{
if (settings != null)
settings.runtimeSeconds += (DateTime.Now - _readyTime).TotalSeconds;
SaveSettings();
Instance = null;
}
/// <summary>
/// Saves Settings Data onto disk.
/// </summary>
public void SaveSettings()
{
try
{
string jsonString = JsonSerializer.Serialize(
settings,
new JsonSerializerOptions() { WriteIndented = true}
);
System.IO.File.WriteAllText(SETTINGS_FILE_PATH, jsonString);
}
catch (Exception e)
{
GD.PrintErr("Error Saving Settings:", e);
Console.WriteLine(e);
}
}
/// <summary>
/// Loads Settings data from disk.
/// </summary>
public void LoadSettings()
{
_loadedData = false;
try
{
if (!System.IO.File.Exists(SETTINGS_FILE_PATH))
{
settings = new SettingsData();
}
else
{
string jsonString = System.IO.File.ReadAllText(SETTINGS_FILE_PATH);
SettingsData? loadedSettings = JsonSerializer.Deserialize<SettingsData>(jsonString);
if (loadedSettings != null && !loadedSettings.IsVersionValid())
{
_loadedData = false;
}
else
{
settings = loadedSettings;
_loadedData = true;
}
}
}
catch (Exception e)
{
GD.PrintErr("Loading Error:", e);
Console.WriteLine(e);
}
}
/// <summary>
/// Resets Settings to default.
/// </summary>
public void ResetSettings()
{
settings = JsonSerializer.Deserialize<SettingsData>(JsonSerializer.Serialize<SettingsData>(settingsDefault));
OnSettingsReloaded?.Invoke();
}
}

@ -0,0 +1,101 @@
using Godot;
namespace Babushka.scripts.CSharp.Common.Savegame;
/// <summary>
/// Tracks important window settings and communicates with the <see cref="SettingsSaveController"/> to save/load them.
/// </summary>
public partial class WindowSettingsSync : Node
{
private Window window;
public override void _Ready()
{
window = GetWindow();
window.SizeChanged += SaveWindowSize;
SyncSettings();
SettingsSaveController.Instance.OnSettingsReloaded += SyncSettings;
}
public override void _ExitTree()
{
SaveWindowPosition();
SaveWindowBorderless();
SaveWindowSize();
SettingsSaveController.Instance.SaveSettings();
}
/// <summary>
/// Tries to get previous settings from settings-savefile, if available.
/// </summary>
public void SyncSettings()
{
if (!SettingsSaveController.Instance.LoadedData)
{
SaveWindowPosition();
SaveWindowSize();
SaveWindowBorderless();
return;
}
SettingsData? settingsData = SettingsSaveController.Instance.settings;
if (settingsData != null)
{
window.Position = new Vector2I(settingsData.windowPositionX, settingsData.windowPositionY);
ValidateWindowPosition();
window.Size = new Vector2I(settingsData.windowSizeX, settingsData.windowSizeY);
window.Borderless = settingsData.windowBorderless;
}
}
private void ValidateWindowPosition()
{
bool validWindowPosition = false;
foreach (Rect2I displayRect in DisplayServer.GetDisplayCutouts())
{
if (displayRect.HasPoint(window.Position))
{
validWindowPosition = true;
break;
}
}
if (!validWindowPosition)
{
window.MoveToCenter();
SaveWindowPosition();
}
}
private void SaveWindowPosition()
{
SettingsData? settingsData = SettingsSaveController.Instance.settings;
if (settingsData != null)
{
settingsData.windowPositionX = window.Position.X;
settingsData.windowPositionY = window.Position.Y;
}
}
private void SaveWindowSize()
{
SettingsData? settingsData = SettingsSaveController.Instance.settings;
if (settingsData != null)
{
settingsData.windowSizeX = window.Size.X;
settingsData.windowSizeY = window.Size.Y;
}
}
private void SaveWindowBorderless()
{
SettingsData? settingsData = SettingsSaveController.Instance.settings;
if (settingsData != null)
settingsData.windowBorderless = window.Borderless;
}
}

@ -34,6 +34,7 @@ public partial class SceneTransition : Node
public void Quit() public void Quit()
{ {
SettingsSaveController.Instance.SaveSettings();
GetTree().Quit(); GetTree().Quit();
} }

Loading…
Cancel
Save