85 lines
2 KiB
C++
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();
|
|
}
|
|
};
|
|
|
|
}
|