1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#ifndef SETTINGS_H
#define SETTINGS_H
#include <map>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
class SettingValue {
public:
virtual ~SettingValue() {}
virtual std::string ValueToString() const = 0;
virtual void SetFromString(const std::string& valueStr) = 0;
virtual std::unique_ptr<SettingValue> Create() const = 0;
};
class StringSetting final : public SettingValue {
public:
StringSetting() {}
StringSetting(const std::string& value) { _value = value; }
std::string& Value() { return _value; }
const std::string& Value() const { return _value; }
std::string ValueToString() const override { return _value; }
void SetFromString(const std::string& valueStr) override {
_value = valueStr;
}
std::unique_ptr<SettingValue> Create() const override {
return std::unique_ptr<SettingValue>(new StringSetting(_value));
}
private:
std::string _value;
};
class SettingItem {
public:
explicit SettingItem(std::unique_ptr<SettingValue> defaultValue)
: _defaultValue(std::move(defaultValue)) {}
bool HasValue() const { return _value != nullptr; }
SettingValue& Value() { return *_value; }
void SetValue(std::unique_ptr<SettingValue> value) {
_value = std::move(value);
}
const SettingValue& DefaultValue() const { return *_defaultValue; }
const SettingValue& ValueOrDefault() const {
return _value == nullptr ? *_defaultValue : *_value;
}
void MakeDefault() { _value.reset(); }
private:
std::unique_ptr<SettingValue> _value, _defaultValue;
};
class Settings {
public:
Settings();
static std::string GetConfigDir();
std::string GetStrategyFilename() const;
void Load();
void Save() const;
void InitializeWorkStrategy();
std::vector<std::string> RecentFiles() const {
return getStrArr("recent-files", 10);
}
void SetRecentFiles(const std::vector<std::string>& recentFiles) {
return setStrArr("recent-files", recentFiles);
}
std::vector<std::string> RecentStrategies() const {
return getStrArr("recent-strategies", 10);
}
void SetRecentStrategies(const std::vector<std::string>& recentStrategies) {
return setStrArr("recent-strategies", recentStrategies);
}
private:
static std::string getConfigFilename();
void initStr(const std::string& key, const std::string& defaultStr) {
_settings.emplace(
key, std::unique_ptr<SettingValue>(new StringSetting(defaultStr)));
}
void initStrArray(const std::string& key,
const std::vector<std::string>& defaultVal) {
for (size_t i = 0; i != defaultVal.size(); ++i)
_settings.emplace(
key + '[' + std::to_string(i) + ']',
std::unique_ptr<SettingValue>(new StringSetting(defaultVal[i])));
}
void set(const std::string& key, const std::string& value) {
auto iter = _settings.find(key);
if (iter == _settings.end())
throw std::runtime_error("Unknown setting in settings file: " + key);
if (!iter->second.HasValue())
iter->second.SetValue(iter->second.DefaultValue().Create());
iter->second.Value().SetFromString(value);
}
std::string getStr(const std::string& key) const {
return static_cast<const StringSetting&>(
_settings.find(key)->second.ValueOrDefault())
.Value();
}
void setStr(const std::string& key, const std::string& value) {
SettingItem& item = _settings.find(key)->second;
if (static_cast<const StringSetting&>(item.DefaultValue()).Value() ==
value) {
item.MakeDefault();
} else {
if (!item.HasValue()) item.SetValue(item.DefaultValue().Create());
static_cast<StringSetting&>(item.Value()).Value() = value;
}
}
std::vector<std::string> getStrArr(const std::string& key, size_t n) const {
std::vector<std::string> arr(n);
for (size_t i = 0; i != n; ++i)
arr[i] = getStr(key + '[' + std::to_string(i) + ']');
return arr;
}
void setStrArr(const std::string& key,
const std::vector<std::string>& values) {
for (size_t i = 0; i != values.size(); ++i)
setStr(key + '[' + std::to_string(i) + ']', values[i]);
}
std::map<std::string, SettingItem> _settings;
};
#endif
|