ArtifactEngine/Shared/Settings.h
2026-04-06 19:22:10 -04:00

85 lines
2 KiB
C++

#pragma once
#include <string>
#include <fstream>
#include <sstream>
#include <optional>
#include "Paths.h"
#include "Events.h"
namespace Artifact {
namespace Events {
struct SettingChanged {
std::string key;
std::optional<std::string> value;
};
}
class Settings: public EventTarget {
const Path path;
std::unordered_map<std::string, std::string> data;
public:
Settings();
Settings(Path path);
void reload();
void save();
template<typename T>
T get(std::string & key, const T & fallback = {}) {
auto it = data.find(key);
if (it == data.end()) {
return fallback;
}
const std::string & str = it->second;
if constexpr (std::is_same_v<T, std::string>) {
return str;
}
if constexpr (std::is_same_v<T, bool>) {
std::string lower = str;
std::transform(lower.begin(), lower.end(), lower.begin(),
[](unsigned char c){ return static_cast<char>(std::tolower(c)); });
if (lower == "true" || lower == "1" || lower == "yes" || lower == "on") {
return true;
}
if (lower == "false" || lower == "0" || lower == "no" || lower == "off") {
return false;
}
return fallback;
}
std::istringstream iss(str);
T value;
if (iss >> value) {
return value;
}
return fallback;
}
template<typename T>
void set(const std::string & key, const T & value) {
std::ostringstream oss;
oss << std::boolalpha << value;
data[key] = oss.str();
dispatch(Events::SettingChanged { .key = key, .value = value });
}
void reset(const std::string & key) {
data.erase(key);
dispatch(Events::SettingChanged { .key = key, .value = std::nullopt });
}
void clear() {
data.clear();
}
};
}